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 #include "CompositionRecorder.h"
9 #include "mozilla/gfx/2D.h"
10 #include "mozilla/gfx/gfxVars.h"
11 #include "nsIInputStream.h"
12 #include "nsIBinaryOutputStream.h"
13 #include "nsIObjectOutputStream.h"
22 # include <sys/types.h>
23 # include "sys/stat.h"
26 using namespace mozilla::gfx
;
31 CompositionRecorder::CompositionRecorder(TimeStamp aRecordingStart
)
32 : mRecordingStart(aRecordingStart
) {}
34 void CompositionRecorder::RecordFrame(RecordedFrame
* aFrame
) {
35 mRecordedFrames
.AppendElement(aFrame
);
38 Maybe
<FrameRecording
> CompositionRecorder::GetRecording() {
39 FrameRecording recording
;
41 recording
.startTime() = mRecordingStart
;
43 nsTArray
<uint8_t> bytes
;
44 for (RefPtr
<RecordedFrame
>& recordedFrame
: mRecordedFrames
) {
45 RefPtr
<DataSourceSurface
> surf
= recordedFrame
->GetSourceSurface();
50 nsCOMPtr
<nsIInputStream
> imgStream
;
51 nsresult rv
= gfxUtils::EncodeSourceSurfaceAsStream(
52 surf
, ImageType::PNG
, u
""_ns
, getter_AddRefs(imgStream
));
58 rv
= imgStream
->Available(&bufSize64
);
59 if (NS_FAILED(rv
) || bufSize64
> UINT32_MAX
) {
63 const uint32_t frameLength
= static_cast<uint32_t>(bufSize64
);
64 size_t startIndex
= bytes
.Length();
65 bytes
.SetLength(startIndex
+ frameLength
);
67 uint8_t* bytePtr
= &bytes
[startIndex
];
68 uint32_t bytesLeft
= frameLength
;
70 while (bytesLeft
> 0) {
71 uint32_t bytesRead
= 0;
72 rv
= imgStream
->Read(reinterpret_cast<char*>(bytePtr
), bytesLeft
,
74 if (NS_FAILED(rv
) || bytesRead
== 0) {
79 bytesLeft
-= bytesRead
;
84 // Currently, all implementers of imgIEncoder report their exact size
85 // through nsIInputStream::Available(), but let's explicitly state that we
86 // rely on that behavior for the algorithm above.
89 uint32_t bytesRead
= 0;
90 rv
= imgStream
->Read(&dummy
, 1, &bytesRead
);
91 MOZ_ASSERT(NS_SUCCEEDED(rv
) && bytesRead
== 0);
95 RecordedFrameData frameData
;
97 frameData
.timeOffset() = recordedFrame
->GetTimeStamp();
98 frameData
.length() = frameLength
;
100 recording
.frames().AppendElement(std::move(frameData
));
102 // Now that we're done, release the frame so we can free up its memory
103 recordedFrame
= nullptr;
106 mRecordedFrames
.Clear();
108 recording
.bytes() = ipc::BigBuffer(bytes
);
110 return Some(std::move(recording
));
113 } // namespace layers
114 } // namespace mozilla