From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- gfx/layers/CompositionRecorder.cpp | 114 +++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 gfx/layers/CompositionRecorder.cpp (limited to 'gfx/layers/CompositionRecorder.cpp') diff --git a/gfx/layers/CompositionRecorder.cpp b/gfx/layers/CompositionRecorder.cpp new file mode 100644 index 0000000000..61d43330e9 --- /dev/null +++ b/gfx/layers/CompositionRecorder.cpp @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CompositionRecorder.h" +#include "gfxUtils.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/gfx/gfxVars.h" +#include "nsIInputStream.h" +#include "nsIBinaryOutputStream.h" +#include "nsIObjectOutputStream.h" +#include "prtime.h" + +#include +#include +#include "stdio.h" +#ifdef XP_WIN +# include "direct.h" +#else +# include +# include "sys/stat.h" +#endif + +using namespace mozilla::gfx; + +namespace mozilla { +namespace layers { + +CompositionRecorder::CompositionRecorder(TimeStamp aRecordingStart) + : mRecordingStart(aRecordingStart) {} + +void CompositionRecorder::RecordFrame(RecordedFrame* aFrame) { + mRecordedFrames.AppendElement(aFrame); +} + +Maybe CompositionRecorder::GetRecording() { + FrameRecording recording; + + recording.startTime() = mRecordingStart; + + nsTArray bytes; + for (RefPtr& recordedFrame : mRecordedFrames) { + RefPtr surf = recordedFrame->GetSourceSurface(); + if (!surf) { + return Nothing(); + } + + nsCOMPtr imgStream; + nsresult rv = gfxUtils::EncodeSourceSurfaceAsStream( + surf, ImageType::PNG, u""_ns, getter_AddRefs(imgStream)); + if (NS_FAILED(rv)) { + return Nothing(); + } + + uint64_t bufSize64; + rv = imgStream->Available(&bufSize64); + if (NS_FAILED(rv) || bufSize64 > UINT32_MAX) { + return Nothing(); + } + + const uint32_t frameLength = static_cast(bufSize64); + size_t startIndex = bytes.Length(); + bytes.SetLength(startIndex + frameLength); + + uint8_t* bytePtr = &bytes[startIndex]; + uint32_t bytesLeft = frameLength; + + while (bytesLeft > 0) { + uint32_t bytesRead = 0; + rv = imgStream->Read(reinterpret_cast(bytePtr), bytesLeft, + &bytesRead); + if (NS_FAILED(rv) || bytesRead == 0) { + return Nothing(); + } + + bytePtr += bytesRead; + bytesLeft -= bytesRead; + } + +#ifdef DEBUG + + // Currently, all implementers of imgIEncoder report their exact size + // through nsIInputStream::Available(), but let's explicitly state that we + // rely on that behavior for the algorithm above. + + char dummy = 0; + uint32_t bytesRead = 0; + rv = imgStream->Read(&dummy, 1, &bytesRead); + MOZ_ASSERT(NS_SUCCEEDED(rv) && bytesRead == 0); + +#endif + + RecordedFrameData frameData; + + frameData.timeOffset() = recordedFrame->GetTimeStamp(); + frameData.length() = frameLength; + + recording.frames().AppendElement(std::move(frameData)); + + // Now that we're done, release the frame so we can free up its memory + recordedFrame = nullptr; + } + + mRecordedFrames.Clear(); + + recording.bytes() = ipc::BigBuffer(bytes); + + return Some(std::move(recording)); +} + +} // namespace layers +} // namespace mozilla -- cgit v1.2.3