1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_layout_printing_DrawEventRecorder_h
8 #define mozilla_layout_printing_DrawEventRecorder_h
12 #include "mozilla/gfx/DrawEventRecorder.h"
13 #include "mozilla/gfx/RecordingTypes.h"
20 class PRFileDescStream final
: public mozilla::gfx::EventStream
{
21 // Most writes, as seen in the print IPC use case, are very small (<32 bytes),
22 // with a small number of very large (>40KB) writes. Writes larger than this
23 // value are not buffered.
24 static const size_t kBufferSize
= 1024;
28 : mFd(nullptr), mBuffer(nullptr), mBufferPos(0), mGood(true) {}
29 PRFileDescStream(const PRFileDescStream
& other
) = delete;
30 ~PRFileDescStream() { Close(); }
32 void OpenFD(PRFileDesc
* aFd
) {
33 MOZ_DIAGNOSTIC_ASSERT(!IsOpen());
36 mBuffer
.reset(new uint8_t[kBufferSize
]);
41 // We need to be API compatible with std::ostream, and so we silently handle
42 // closes on a closed FD.
52 bool IsOpen() { return mFd
!= nullptr; }
55 // See comment in Close().
56 if (IsOpen() && mBufferPos
> 0) {
58 PR_Write(mFd
, static_cast<const void*>(mBuffer
.get()), mBufferPos
);
59 mGood
= length
>= 0 && static_cast<size_t>(length
) == mBufferPos
;
64 void Seek(PRInt64 aOffset
, PRSeekWhence aWhence
) {
66 PRInt64 pos
= PR_Seek64(mFd
, aOffset
, aWhence
);
70 void write(const char* aData
, size_t aSize
) override
{
75 // See comment in Close().
77 // If we're writing more data than could ever fit in our buffer, flush the
78 // buffer and write directly.
79 if (aSize
> kBufferSize
) {
81 PRInt32 length
= PR_Write(mFd
, static_cast<const void*>(aData
), aSize
);
82 mGood
= length
>= 0 && static_cast<size_t>(length
) == aSize
;
83 // If our write could fit in our buffer, but doesn't because the buffer
84 // is partially full, write to the buffer, flush the buffer, and then
85 // write the rest of the data to the buffer.
86 } else if (aSize
> AvailableBufferSpace()) {
87 size_t length
= AvailableBufferSpace();
88 WriteToBuffer(aData
, length
);
91 WriteToBuffer(aData
+ length
, aSize
- length
);
92 // Write fits in the buffer.
94 WriteToBuffer(aData
, aSize
);
99 void read(char* aOut
, size_t aSize
) override
{
105 PRInt32 res
= PR_Read(mFd
, static_cast<void*>(aOut
), aSize
);
106 mGood
= res
>= 0 && (static_cast<size_t>(res
) == aSize
);
109 bool good() final
{ return mGood
; }
111 void SetIsBad() final
{ mGood
= false; }
114 size_t AvailableBufferSpace() { return kBufferSize
- mBufferPos
; }
116 void WriteToBuffer(const char* aData
, size_t aSize
) {
117 MOZ_ASSERT(aSize
<= AvailableBufferSpace());
118 memcpy(mBuffer
.get() + mBufferPos
, aData
, aSize
);
123 std::unique_ptr
<uint8_t[]> mBuffer
;
128 class DrawEventRecorderPRFileDesc final
: public gfx::DrawEventRecorderPrivate
{
130 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawEventRecorderPRFileDesc
, override
)
131 explicit DrawEventRecorderPRFileDesc() = default;
132 ~DrawEventRecorderPRFileDesc();
134 gfx::RecorderType
GetRecorderType() const final
{
135 return gfx::RecorderType::PRFILEDESC
;
138 void RecordEvent(const gfx::RecordedEvent
& aEvent
) override
;
141 * Returns whether a recording file is currently open.
146 * Opens the recorder with the provided PRFileDesc *.
148 void OpenFD(PRFileDesc
* aFd
);
151 * Closes the file so that it can be processed. The recorder does NOT forget
152 * which objects it has recorded. This can be used with OpenNew, so that a
153 * recording can be processed in chunks. The file must be open.
157 void AddDependentSurface(uint64_t aDependencyId
) override
;
158 nsTArray
<uint64_t>&& TakeDependentSurfaces();
161 void Flush() override
;
163 PRFileDescStream mOutputStream
;
164 nsTArray
<uint64_t> mDependentSurfaces
;
167 } // namespace layout
169 } // namespace mozilla
171 #endif /* mozilla_layout_printing_DrawEventRecorder_h */