diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /gfx/2d/DrawEventRecorder.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/2d/DrawEventRecorder.cpp')
-rw-r--r-- | gfx/2d/DrawEventRecorder.cpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/gfx/2d/DrawEventRecorder.cpp b/gfx/2d/DrawEventRecorder.cpp new file mode 100644 index 0000000000..894eb1045c --- /dev/null +++ b/gfx/2d/DrawEventRecorder.cpp @@ -0,0 +1,159 @@ +/* -*- 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 "DrawEventRecorder.h" + +#include "mozilla/UniquePtrExtensions.h" +#include "PathRecording.h" +#include "RecordingTypes.h" +#include "RecordedEventImpl.h" + +namespace mozilla { +namespace gfx { + +DrawEventRecorderPrivate::DrawEventRecorderPrivate() : mExternalFonts(false) {} + +void DrawEventRecorderPrivate::StoreExternalSurfaceRecording( + SourceSurface* aSurface, uint64_t aKey) { + RecordEvent(RecordedExternalSurfaceCreation(aSurface, aKey)); + mExternalSurfaces.push_back(aSurface); +} + +void DrawEventRecorderPrivate::StoreSourceSurfaceRecording( + SourceSurface* aSurface, const char* aReason) { + RefPtr<DataSourceSurface> dataSurf = aSurface->GetDataSurface(); + IntSize surfaceSize = aSurface->GetSize(); + Maybe<DataSourceSurface::ScopedMap> map; + if (dataSurf) { + map.emplace(dataSurf, DataSourceSurface::READ); + } + if (!dataSurf || !map->IsMapped() || + !Factory::AllowedSurfaceSize(surfaceSize)) { + gfxWarning() << "Recording failed to record SourceSurface for " << aReason; + + // If surface size is not allowed, replace with reasonable size. + if (!Factory::AllowedSurfaceSize(surfaceSize)) { + surfaceSize.width = std::min(surfaceSize.width, kReasonableSurfaceSize); + surfaceSize.height = std::min(surfaceSize.height, kReasonableSurfaceSize); + } + + // Insert a dummy source surface. + int32_t stride = surfaceSize.width * BytesPerPixel(aSurface->GetFormat()); + UniquePtr<uint8_t[]> sourceData = + MakeUniqueFallible<uint8_t[]>(stride * surfaceSize.height); + if (!sourceData) { + // If the surface is too big just create a 1 x 1 dummy. + surfaceSize.width = 1; + surfaceSize.height = 1; + stride = surfaceSize.width * BytesPerPixel(aSurface->GetFormat()); + sourceData = MakeUnique<uint8_t[]>(stride * surfaceSize.height); + } + + RecordEvent(RecordedSourceSurfaceCreation(aSurface, sourceData.get(), + stride, surfaceSize, + aSurface->GetFormat())); + return; + } + + RecordEvent(RecordedSourceSurfaceCreation( + aSurface, map->GetData(), map->GetStride(), dataSurf->GetSize(), + dataSurf->GetFormat())); +} + +void DrawEventRecorderPrivate::RecordSourceSurfaceDestruction(void* aSurface) { + RemoveSourceSurface(static_cast<SourceSurface*>(aSurface)); + RemoveStoredObject(aSurface); + RecordEvent(RecordedSourceSurfaceDestruction(ReferencePtr(aSurface))); +} + +void DrawEventRecorderPrivate::DecrementUnscaledFontRefCount( + const ReferencePtr aUnscaledFont) { + auto element = mUnscaledFontRefs.find(aUnscaledFont); + MOZ_DIAGNOSTIC_ASSERT(element != mUnscaledFontRefs.end(), + "DecrementUnscaledFontRefCount calls should balance " + "with IncrementUnscaledFontRefCount calls"); + if (--(element->second) <= 0) { + RecordEvent(RecordedUnscaledFontDestruction(aUnscaledFont)); + mUnscaledFontRefs.erase(aUnscaledFont); + } +} + +void DrawEventRecorderMemory::RecordEvent(const RecordedEvent& aEvent) { + aEvent.RecordToStream(mOutputStream); +} + +void DrawEventRecorderMemory::AddDependentSurface(uint64_t aDependencyId) { + mDependentSurfaces.Insert(aDependencyId); +} + +nsTHashSet<uint64_t>&& DrawEventRecorderMemory::TakeDependentSurfaces() { + return std::move(mDependentSurfaces); +} + +DrawEventRecorderMemory::DrawEventRecorderMemory() { + WriteHeader(mOutputStream); +} + +DrawEventRecorderMemory::DrawEventRecorderMemory( + const SerializeResourcesFn& aFn) + : mSerializeCallback(aFn) { + mExternalFonts = !!mSerializeCallback; + WriteHeader(mOutputStream); +} + +void DrawEventRecorderMemory::Flush() {} + +void DrawEventRecorderMemory::FlushItem(IntRect aRect) { + MOZ_RELEASE_ASSERT(!aRect.IsEmpty()); + // Detaching our existing resources will add some + // destruction events to our stream so we need to do that + // first. + DetachResources(); + + // See moz2d_renderer.rs for a description of the stream format + WriteElement(mIndex, mOutputStream.mLength); + + // write out the fonts into the extra data section + mSerializeCallback(mOutputStream, mScaledFonts); + WriteElement(mIndex, mOutputStream.mLength); + + WriteElement(mIndex, aRect.x); + WriteElement(mIndex, aRect.y); + WriteElement(mIndex, aRect.XMost()); + WriteElement(mIndex, aRect.YMost()); + ClearResources(); + + // write out a new header for the next recording in the stream + WriteHeader(mOutputStream); +} + +bool DrawEventRecorderMemory::Finish() { + // this length might be 0, and things should still work. + // for example if there are no items in a particular area + size_t indexOffset = mOutputStream.mLength; + // write out the index + mOutputStream.write(mIndex.mData, mIndex.mLength); + bool hasItems = mIndex.mLength != 0; + mIndex.reset(); + // write out the offset of the Index to the end of the output stream + WriteElement(mOutputStream, indexOffset); + ClearResources(); + return hasItems; +} + +size_t DrawEventRecorderMemory::RecordingSize() { + return mOutputStream.mLength; +} + +void DrawEventRecorderMemory::WipeRecording() { + mOutputStream.reset(); + mIndex.reset(); + + WriteHeader(mOutputStream); +} + +} // namespace gfx +} // namespace mozilla |