From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- gfx/2d/2D.h | 13 ++- gfx/2d/DrawEventRecorder.cpp | 7 ++ gfx/2d/DrawEventRecorder.h | 23 ++++- gfx/2d/DrawTargetRecording.cpp | 202 ++++++++++++++++++++++------------------- gfx/2d/DrawTargetRecording.h | 46 +++++++++- gfx/2d/RecordedEvent.cpp | 2 + gfx/2d/RecordedEvent.h | 7 ++ gfx/2d/RecordedEventImpl.h | 84 +++++++++++++++++ gfx/2d/SkConvolver.cpp | 47 +++++++--- gfx/2d/SkConvolver.h | 16 ++-- 10 files changed, 327 insertions(+), 120 deletions(-) (limited to 'gfx/2d') diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index e6b94f86ea..f16a0ee0cc 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -85,7 +85,9 @@ namespace mozilla { class Mutex; namespace layers { +class Image; class MemoryOrShmem; +class SurfaceDescriptor; class SurfaceDescriptorBuffer; class TextureData; } // namespace layers @@ -1416,6 +1418,15 @@ class DrawTarget : public external::AtomicRefCounted { const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), const DrawOptions& aOptions = DrawOptions()) = 0; + virtual void DrawSurfaceDescriptor( + const layers::SurfaceDescriptor& aDesc, + const RefPtr& aImageOfSurfaceDescriptor, const Rect& aDest, + const Rect& aSource, + const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), + const DrawOptions& aOptions = DrawOptions()) { + MOZ_CRASH("GFX: DrawSurfaceDescriptor"); + } + /** * Draw a surface to the draw target, when the surface will be available * at a later time. This is only valid for recording DrawTargets. @@ -1981,7 +1992,7 @@ class DrawTarget : public external::AtomicRefCounted { UserData mUserData; Matrix mTransform; IntRect mOpaqueRect; - bool mTransformDirty : 1; + mutable bool mTransformDirty : 1; bool mPermitSubpixelAA : 1; SurfaceFormat mFormat; diff --git a/gfx/2d/DrawEventRecorder.cpp b/gfx/2d/DrawEventRecorder.cpp index 51f8b836ec..b24b158f56 100644 --- a/gfx/2d/DrawEventRecorder.cpp +++ b/gfx/2d/DrawEventRecorder.cpp @@ -33,6 +33,13 @@ void DrawEventRecorderPrivate::StoreExternalSurfaceRecording( mExternalSurfaces.push_back({aSurface}); } +void DrawEventRecorderPrivate::StoreExternalImageRecording( + const RefPtr& aImageOfSurfaceDescriptor) { + NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); + + mExternalImages.push_back({aImageOfSurfaceDescriptor}); +} + void DrawEventRecorderPrivate::StoreSourceSurfaceRecording( SourceSurface* aSurface, const char* aReason) { NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); diff --git a/gfx/2d/DrawEventRecorder.h b/gfx/2d/DrawEventRecorder.h index d62f098784..c099973fbd 100644 --- a/gfx/2d/DrawEventRecorder.h +++ b/gfx/2d/DrawEventRecorder.h @@ -15,6 +15,7 @@ #include #include +#include "ImageContainer.h" #include "mozilla/DataMutex.h" #include "mozilla/ThreadSafeWeakPtr.h" #include "nsTHashMap.h" @@ -83,7 +84,8 @@ class DrawEventRecorderPrivate : public DrawEventRecorder { virtual void RecordEvent(const RecordedEvent& aEvent) = 0; - void RecordEvent(DrawTargetRecording* aDT, const RecordedEvent& aEvent) { + void RecordEvent(const DrawTargetRecording* aDT, + const RecordedEvent& aEvent) { ReferencePtr dt = aDT; if (mCurrentDT != dt) { SetDrawTarget(dt); @@ -93,7 +95,7 @@ class DrawEventRecorderPrivate : public DrawEventRecorder { void SetDrawTarget(ReferencePtr aDT); - void ClearDrawTarget(DrawTargetRecording* aDT) { + void ClearDrawTarget(const DrawTargetRecording* aDT) { ReferencePtr dt = aDT; if (mCurrentDT == dt) { mCurrentDT = nullptr; @@ -185,6 +187,12 @@ class DrawEventRecorderPrivate : public DrawEventRecorder { virtual void StoreSourceSurfaceRecording(SourceSurface* aSurface, const char* aReason); + virtual void StoreImageRecording( + const RefPtr& aImageOfSurfaceDescriptor, + const char* aReasony) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + } + /** * Used when a source surface is destroyed, aSurface is a void* instead of a * SourceSurface* because this is called during the SourceSurface destructor, @@ -209,11 +217,21 @@ class DrawEventRecorderPrivate : public DrawEventRecorder { aSurfaces = std::move(mExternalSurfaces); } + struct ExternalImageEntry { + RefPtr mImage; + int64_t mEventCount = -1; + }; + + using ExternalImagesHolder = std::deque; + protected: NS_DECL_OWNINGTHREAD void StoreExternalSurfaceRecording(SourceSurface* aSurface, uint64_t aKey); + void StoreExternalImageRecording( + const RefPtr& aImageOfSurfaceDescriptor); + void ProcessPendingDeletions() { NS_ASSERT_OWNINGTHREAD(DrawEventRecorderPrivate); @@ -253,6 +271,7 @@ class DrawEventRecorderPrivate : public DrawEventRecorder { ReferencePtr mCurrentDT; ExternalSurfacesHolder mExternalSurfaces; + ExternalImagesHolder mExternalImages; bool mExternalFonts; }; diff --git a/gfx/2d/DrawTargetRecording.cpp b/gfx/2d/DrawTargetRecording.cpp index 6edc8cdf91..cdabb80ecd 100644 --- a/gfx/2d/DrawTargetRecording.cpp +++ b/gfx/2d/DrawTargetRecording.cpp @@ -9,6 +9,7 @@ #include "PathRecording.h" #include +#include "ImageContainer.h" #include "Logging.h" #include "Tools.h" #include "Filters.h" @@ -199,7 +200,7 @@ DrawTargetRecording::DrawTargetRecording( : mRecorder(static_cast(aRecorder)), mFinalDT(aDT), mRect(IntPoint(0, 0), aSize) { - mRecorder->RecordEvent(layers::RecordedCanvasDrawTargetCreation( + RecordEventSkipFlushTransform(layers::RecordedCanvasDrawTargetCreation( this, aTextureId, aTextureOwnerId, mFinalDT->GetBackendType(), aSize, mFinalDT->GetFormat())); mFormat = mFinalDT->GetFormat(); @@ -214,7 +215,7 @@ DrawTargetRecording::DrawTargetRecording(DrawEventRecorder* aRecorder, mRect(aRect) { MOZ_DIAGNOSTIC_ASSERT(aRecorder->GetRecorderType() != RecorderType::CANVAS); RefPtr snapshot = aHasData ? mFinalDT->Snapshot() : nullptr; - mRecorder->RecordEvent( + RecordEventSkipFlushTransform( RecordedDrawTargetCreation(this, mFinalDT->GetBackendType(), mRect, mFinalDT->GetFormat(), aHasData, snapshot)); mFormat = mFinalDT->GetFormat(); @@ -229,21 +230,22 @@ DrawTargetRecording::DrawTargetRecording(const DrawTargetRecording* aDT, } DrawTargetRecording::~DrawTargetRecording() { - mRecorder->RecordEvent(RecordedDrawTargetDestruction(ReferencePtr(this))); + RecordEventSkipFlushTransform( + RecordedDrawTargetDestruction(ReferencePtr(this))); mRecorder->ClearDrawTarget(this); } void DrawTargetRecording::Link(const char* aDestination, const Rect& aRect) { MarkChanged(); - mRecorder->RecordEvent(this, RecordedLink(aDestination, aRect)); + RecordEventSelf(RecordedLink(aDestination, aRect)); } void DrawTargetRecording::Destination(const char* aDestination, const Point& aPoint) { MarkChanged(); - mRecorder->RecordEvent(this, RecordedDestination(aDestination, aPoint)); + RecordEventSelf(RecordedDestination(aDestination, aPoint)); } void DrawTargetRecording::FillRect(const Rect& aRect, const Pattern& aPattern, @@ -252,7 +254,7 @@ void DrawTargetRecording::FillRect(const Rect& aRect, const Pattern& aPattern, EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent(this, RecordedFillRect(aRect, aPattern, aOptions)); + RecordEventSelf(RecordedFillRect(aRect, aPattern, aOptions)); } void DrawTargetRecording::StrokeRect(const Rect& aRect, const Pattern& aPattern, @@ -262,8 +264,8 @@ void DrawTargetRecording::StrokeRect(const Rect& aRect, const Pattern& aPattern, EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent( - this, RecordedStrokeRect(aRect, aPattern, aStrokeOptions, aOptions)); + RecordEventSelf( + RecordedStrokeRect(aRect, aPattern, aStrokeOptions, aOptions)); } void DrawTargetRecording::StrokeLine(const Point& aBegin, const Point& aEnd, @@ -274,8 +276,8 @@ void DrawTargetRecording::StrokeLine(const Point& aBegin, const Point& aEnd, EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent(this, RecordedStrokeLine(aBegin, aEnd, aPattern, - aStrokeOptions, aOptions)); + RecordEventSelf( + RecordedStrokeLine(aBegin, aEnd, aPattern, aStrokeOptions, aOptions)); } void DrawTargetRecording::Fill(const Path* aPath, const Pattern& aPattern, @@ -291,16 +293,14 @@ void DrawTargetRecording::Fill(const Path* aPath, const Pattern& aPattern, auto circle = path->AsCircle(); if (circle) { EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent( - this, RecordedFillCircle(circle.value(), aPattern, aOptions)); + RecordEventSelf(RecordedFillCircle(circle.value(), aPattern, aOptions)); return; } } RefPtr pathRecording = EnsurePathStored(aPath); EnsurePatternDependenciesStored(aPattern); - - mRecorder->RecordEvent(this, RecordedFill(pathRecording, aPattern, aOptions)); + RecordEventSelf(RecordedFill(pathRecording, aPattern, aOptions)); } struct RecordingFontUserData { @@ -345,7 +345,7 @@ void DrawTargetRecording::DrawGlyphs(ScaledFont* aFont, // playback. RecordedFontDescriptor fontDesc(unscaledFont); if (fontDesc.IsValid()) { - mRecorder->RecordEvent(fontDesc); + RecordEventSkipFlushTransform(fontDesc); } else { RecordedFontData fontData(unscaledFont); RecordedFontDetails fontDetails; @@ -353,10 +353,10 @@ void DrawTargetRecording::DrawGlyphs(ScaledFont* aFont, // Try to serialise the whole font, just in case this is a web font // that is not present on the system. if (!mRecorder->HasStoredFontData(fontDetails.fontDataKey)) { - mRecorder->RecordEvent(fontData); + RecordEventSkipFlushTransform(fontData); mRecorder->AddStoredFontData(fontDetails.fontDataKey); } - mRecorder->RecordEvent( + RecordEventSkipFlushTransform( RecordedUnscaledFontCreation(unscaledFont, fontDetails)); } else { gfxWarning() << "DrawTargetRecording::FillGlyphs failed to serialise " @@ -364,7 +364,8 @@ void DrawTargetRecording::DrawGlyphs(ScaledFont* aFont, } } } - mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, unscaledFont)); + RecordEventSkipFlushTransform( + RecordedScaledFontCreation(aFont, unscaledFont)); RecordingFontUserData* userData = new RecordingFontUserData; userData->refPtr = aFont; userData->unscaledFont = unscaledFont; @@ -375,13 +376,12 @@ void DrawTargetRecording::DrawGlyphs(ScaledFont* aFont, } if (aStrokeOptions) { - mRecorder->RecordEvent( - this, RecordedStrokeGlyphs(aFont, aPattern, *aStrokeOptions, aOptions, - aBuffer.mGlyphs, aBuffer.mNumGlyphs)); + RecordEventSelf(RecordedStrokeGlyphs(aFont, aPattern, *aStrokeOptions, + aOptions, aBuffer.mGlyphs, + aBuffer.mNumGlyphs)); } else { - mRecorder->RecordEvent( - this, RecordedFillGlyphs(aFont, aPattern, aOptions, aBuffer.mGlyphs, - aBuffer.mNumGlyphs)); + RecordEventSelf(RecordedFillGlyphs(aFont, aPattern, aOptions, + aBuffer.mGlyphs, aBuffer.mNumGlyphs)); } } @@ -407,7 +407,7 @@ void DrawTargetRecording::Mask(const Pattern& aSource, const Pattern& aMask, EnsurePatternDependenciesStored(aSource); EnsurePatternDependenciesStored(aMask); - mRecorder->RecordEvent(this, RecordedMask(aSource, aMask, aOptions)); + RecordEventSelf(RecordedMask(aSource, aMask, aOptions)); } void DrawTargetRecording::MaskSurface(const Pattern& aSource, @@ -422,8 +422,7 @@ void DrawTargetRecording::MaskSurface(const Pattern& aSource, EnsurePatternDependenciesStored(aSource); EnsureSurfaceStoredRecording(mRecorder, aMask, "MaskSurface"); - mRecorder->RecordEvent( - this, RecordedMaskSurface(aSource, aMask, aOffset, aOptions)); + RecordEventSelf(RecordedMaskSurface(aSource, aMask, aOffset, aOptions)); } void DrawTargetRecording::Stroke(const Path* aPath, const Pattern& aPattern, @@ -436,18 +435,16 @@ void DrawTargetRecording::Stroke(const Path* aPath, const Pattern& aPattern, auto circle = path->AsCircle(); if (circle && circle->closed) { EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent( - this, RecordedStrokeCircle(circle.value(), aPattern, aStrokeOptions, - aOptions)); + RecordEventSelf(RecordedStrokeCircle(circle.value(), aPattern, + aStrokeOptions, aOptions)); return; } auto line = path->AsLine(); if (line) { EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent( - this, RecordedStrokeLine(line->origin, line->destination, aPattern, - aStrokeOptions, aOptions)); + RecordEventSelf(RecordedStrokeLine(line->origin, line->destination, + aPattern, aStrokeOptions, aOptions)); return; } } @@ -455,8 +452,8 @@ void DrawTargetRecording::Stroke(const Path* aPath, const Pattern& aPattern, RefPtr pathRecording = EnsurePathStored(aPath); EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent( - this, RecordedStroke(pathRecording, aPattern, aStrokeOptions, aOptions)); + RecordEventSelf( + RecordedStroke(pathRecording, aPattern, aStrokeOptions, aOptions)); } void DrawTargetRecording::DrawShadow(const Path* aPath, const Pattern& aPattern, @@ -468,9 +465,8 @@ void DrawTargetRecording::DrawShadow(const Path* aPath, const Pattern& aPattern, RefPtr pathRecording = EnsurePathStored(aPath); EnsurePatternDependenciesStored(aPattern); - mRecorder->RecordEvent( - this, RecordedDrawShadow(pathRecording, aPattern, aShadow, aOptions, - aStrokeOptions)); + RecordEventSelf(RecordedDrawShadow(pathRecording, aPattern, aShadow, aOptions, + aStrokeOptions)); } void DrawTargetRecording::MarkChanged() { mIsDirty = true; } @@ -479,7 +475,7 @@ already_AddRefed DrawTargetRecording::Snapshot() { RefPtr retSurf = new SourceSurfaceRecording(mRect.Size(), mFormat, mRecorder); - mRecorder->RecordEvent(this, RecordedSnapshot(ReferencePtr(retSurf))); + RecordEventSelfSkipFlushTransform(RecordedSnapshot(ReferencePtr(retSurf))); return retSurf.forget(); } @@ -489,8 +485,8 @@ already_AddRefed DrawTargetRecording::IntoLuminanceSource( RefPtr retSurf = new SourceSurfaceRecording(mRect.Size(), SurfaceFormat::A8, mRecorder); - mRecorder->RecordEvent( - this, RecordedIntoLuminanceSource(retSurf, aLuminanceType, aOpacity)); + RecordEventSelfSkipFlushTransform( + RecordedIntoLuminanceSource(retSurf, aLuminanceType, aOpacity)); return retSurf.forget(); } @@ -508,11 +504,11 @@ already_AddRefed SourceSurfaceRecording::ExtractSubrect( } void DrawTargetRecording::Flush() { - mRecorder->RecordEvent(this, RecordedFlush()); + RecordEventSelfSkipFlushTransform(RecordedFlush()); } void DrawTargetRecording::DetachAllSnapshots() { - mRecorder->RecordEvent(this, RecordedDetachAllSnapshots()); + RecordEventSelfSkipFlushTransform(RecordedDetachAllSnapshots()); } void DrawTargetRecording::DrawSurface(SourceSurface* aSurface, @@ -527,8 +523,22 @@ void DrawTargetRecording::DrawSurface(SourceSurface* aSurface, EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurface"); - mRecorder->RecordEvent(this, RecordedDrawSurface(aSurface, aDest, aSource, - aSurfOptions, aOptions)); + RecordEventSelf( + RecordedDrawSurface(aSurface, aDest, aSource, aSurfOptions, aOptions)); +} + +void DrawTargetRecording::DrawSurfaceDescriptor( + const layers::SurfaceDescriptor& aDesc, + const RefPtr& aImageOfSurfaceDescriptor, const Rect& aDest, + const Rect& aSource, const DrawSurfaceOptions& aSurfOptions, + const DrawOptions& aOptions) { + MarkChanged(); + + mRecorder->StoreImageRecording(aImageOfSurfaceDescriptor, + "DrawSurfaceDescriptor"); + + RecordEventSelf(RecordedDrawSurfaceDescriptor(aDesc, aDest, aSource, + aSurfOptions, aOptions)); } void DrawTargetRecording::DrawDependentSurface(uint64_t aId, @@ -536,7 +546,7 @@ void DrawTargetRecording::DrawDependentSurface(uint64_t aId, MarkChanged(); mRecorder->AddDependentSurface(aId); - mRecorder->RecordEvent(this, RecordedDrawDependentSurface(aId, aDest)); + RecordEventSelf(RecordedDrawDependentSurface(aId, aDest)); } void DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface* aSurface, @@ -551,8 +561,7 @@ void DrawTargetRecording::DrawSurfaceWithShadow(SourceSurface* aSurface, EnsureSurfaceStoredRecording(mRecorder, aSurface, "DrawSurfaceWithShadow"); - mRecorder->RecordEvent( - this, RecordedDrawSurfaceWithShadow(aSurface, aDest, aShadow, aOp)); + RecordEventSelf(RecordedDrawSurfaceWithShadow(aSurface, aDest, aShadow, aOp)); } void DrawTargetRecording::DrawFilter(FilterNode* aNode, const Rect& aSourceRect, @@ -566,15 +575,14 @@ void DrawTargetRecording::DrawFilter(FilterNode* aNode, const Rect& aSourceRect, MOZ_ASSERT(mRecorder->HasStoredObject(aNode)); - mRecorder->RecordEvent( - this, RecordedDrawFilter(aNode, aSourceRect, aDestPoint, aOptions)); + RecordEventSelf(RecordedDrawFilter(aNode, aSourceRect, aDestPoint, aOptions)); } already_AddRefed DrawTargetRecording::CreateFilter( FilterType aType) { RefPtr retNode = new FilterNodeRecording(mRecorder); - mRecorder->RecordEvent(this, RecordedFilterNodeCreation(retNode, aType)); + RecordEventSelfSkipFlushTransform(RecordedFilterNodeCreation(retNode, aType)); return retNode.forget(); } @@ -582,7 +590,7 @@ already_AddRefed DrawTargetRecording::CreateFilter( void DrawTargetRecording::ClearRect(const Rect& aRect) { MarkChanged(); - mRecorder->RecordEvent(this, RecordedClearRect(aRect)); + RecordEventSelf(RecordedClearRect(aRect)); } void DrawTargetRecording::CopySurface(SourceSurface* aSurface, @@ -596,8 +604,7 @@ void DrawTargetRecording::CopySurface(SourceSurface* aSurface, EnsureSurfaceStoredRecording(mRecorder, aSurface, "CopySurface"); - mRecorder->RecordEvent( - this, RecordedCopySurface(aSurface, aSourceRect, aDestination)); + RecordEventSelf(RecordedCopySurface(aSurface, aSourceRect, aDestination)); } void DrawTargetRecording::PushClip(const Path* aPath) { @@ -616,16 +623,15 @@ void DrawTargetRecording::PushClip(const Path* aPath) { } RefPtr pathRecording = EnsurePathStored(aPath); - - mRecorder->RecordEvent(this, RecordedPushClip(ReferencePtr(pathRecording))); + RecordEventSelf(RecordedPushClip(ReferencePtr(pathRecording))); } void DrawTargetRecording::PushClipRect(const Rect& aRect) { - mRecorder->RecordEvent(this, RecordedPushClipRect(aRect)); + RecordEventSelf(RecordedPushClipRect(aRect)); } void DrawTargetRecording::PopClip() { - mRecorder->RecordEvent(this, RecordedPopClip()); + RecordEventSelfSkipFlushTransform(RecordedPopClip()); } void DrawTargetRecording::PushLayer(bool aOpaque, Float aOpacity, @@ -637,9 +643,8 @@ void DrawTargetRecording::PushLayer(bool aOpaque, Float aOpacity, EnsureSurfaceStoredRecording(mRecorder, aMask, "PushLayer"); } - mRecorder->RecordEvent( - this, RecordedPushLayer(aOpaque, aOpacity, aMask, aMaskTransform, aBounds, - aCopyBackground)); + RecordEventSelf(RecordedPushLayer(aOpaque, aOpacity, aMask, aMaskTransform, + aBounds, aCopyBackground)); PushedLayer layer(GetPermitSubpixelAA()); mPushedLayers.push_back(layer); @@ -656,9 +661,9 @@ void DrawTargetRecording::PushLayerWithBlend(bool aOpaque, Float aOpacity, EnsureSurfaceStoredRecording(mRecorder, aMask, "PushLayer"); } - mRecorder->RecordEvent(this, RecordedPushLayerWithBlend( - aOpaque, aOpacity, aMask, aMaskTransform, - aBounds, aCopyBackground, aCompositionOp)); + RecordEventSelf(RecordedPushLayerWithBlend(aOpaque, aOpacity, aMask, + aMaskTransform, aBounds, + aCopyBackground, aCompositionOp)); PushedLayer layer(GetPermitSubpixelAA()); mPushedLayers.push_back(layer); @@ -668,7 +673,7 @@ void DrawTargetRecording::PushLayerWithBlend(bool aOpaque, Float aOpacity, void DrawTargetRecording::PopLayer() { MarkChanged(); - mRecorder->RecordEvent(this, RecordedPopLayer()); + RecordEventSelfSkipFlushTransform(RecordedPopLayer()); const PushedLayer& layer = mPushedLayers.back(); DrawTarget::SetPermitSubpixelAA(layer.mOldPermitSubpixelAA); @@ -719,8 +724,8 @@ already_AddRefed DrawTargetRecording::OptimizeSourceSurface( RefPtr retSurf = new SourceSurfaceRecording( aSurface->GetSize(), aSurface->GetFormat(), mRecorder, aSurface); - mRecorder->RecordEvent(const_cast(this), - RecordedOptimizeSourceSurface(aSurface, retSurf)); + RecordEventSelfSkipFlushTransform( + RecordedOptimizeSourceSurface(aSurface, retSurf)); userData->optimizedSurface = retSurf; return retSurf.forget(); @@ -736,7 +741,6 @@ DrawTargetRecording::CreateSourceSurfaceFromNativeSurface( already_AddRefed DrawTargetRecording::CreateSimilarDrawTargetWithBacking( const IntSize& aSize, SurfaceFormat aFormat) const { - RefPtr similarDT; if (mFinalDT->CanCreateSimilarDrawTarget(aSize, aFormat)) { // If the requested similar draw target is too big, then we should try to // rasterize on the content side to avoid duplicating the effort when a @@ -763,12 +767,12 @@ DrawTargetRecording::CreateSimilarDrawTargetWithBacking( already_AddRefed DrawTargetRecording::CreateSimilarDrawTarget( const IntSize& aSize, SurfaceFormat aFormat) const { - RefPtr similarDT; + RefPtr similarDT; if (mFinalDT->CanCreateSimilarDrawTarget(aSize, aFormat)) { similarDT = new DrawTargetRecording(this, IntRect(IntPoint(0, 0), aSize), aFormat); - mRecorder->RecordEvent( - const_cast(this), + similarDT->SetOptimizeTransform(mOptimizeTransform); + RecordEventSelfSkipFlushTransform( RecordedCreateSimilarDrawTarget(similarDT.get(), aSize, aFormat)); } else if (XRE_IsContentProcess()) { // Crash any content process that calls this function with arguments that @@ -789,11 +793,12 @@ bool DrawTargetRecording::CanCreateSimilarDrawTarget( RefPtr DrawTargetRecording::CreateClippedDrawTarget( const Rect& aBounds, SurfaceFormat aFormat) { - RefPtr similarDT; - similarDT = new DrawTargetRecording(this, mRect, aFormat); - mRecorder->RecordEvent( - this, RecordedCreateClippedDrawTarget(similarDT.get(), aBounds, aFormat)); - similarDT->SetTransform(mTransform); + RefPtr similarDT = + new DrawTargetRecording(this, mRect, aFormat); + similarDT->SetOptimizeTransform(mOptimizeTransform); + RecordEventSelf( + RecordedCreateClippedDrawTarget(similarDT.get(), aBounds, aFormat)); + similarDT->mTransform = similarDT->mRecordedTransform = mTransform; return similarDT; } @@ -801,14 +806,16 @@ already_AddRefed DrawTargetRecording::CreateSimilarDrawTargetForFilter( const IntSize& aMaxSize, SurfaceFormat aFormat, FilterNode* aFilter, FilterNode* aSource, const Rect& aSourceRect, const Point& aDestPoint) { - RefPtr similarDT; + RefPtr similarDT; if (mFinalDT->CanCreateSimilarDrawTarget(aMaxSize, aFormat)) { similarDT = new DrawTargetRecording(this, IntRect(IntPoint(0, 0), aMaxSize), aFormat); - mRecorder->RecordEvent( - this, RecordedCreateDrawTargetForFilter(similarDT.get(), aMaxSize, - aFormat, aFilter, aSource, - aSourceRect, aDestPoint)); + similarDT->SetOptimizeTransform(mOptimizeTransform); + // RecordedCreateDrawTargetForFilter::PlayEvent uses the transform, despite + // the fact that the underlying DrawTarget does not. + RecordEventSelf(RecordedCreateDrawTargetForFilter(similarDT.get(), aMaxSize, + aFormat, aFilter, aSource, + aSourceRect, aDestPoint)); } else if (XRE_IsContentProcess()) { // See CreateSimilarDrawTarget MOZ_CRASH( @@ -828,19 +835,22 @@ already_AddRefed DrawTargetRecording::CreateGradientStops( GradientStop* aStops, uint32_t aNumStops, ExtendMode aExtendMode) const { RefPtr retStops = new GradientStopsRecording(mRecorder); - mRecorder->RecordEvent( - const_cast(this), + RecordEventSelfSkipFlushTransform( RecordedGradientStopsCreation(retStops, aStops, aNumStops, aExtendMode)); return retStops.forget(); } void DrawTargetRecording::SetTransform(const Matrix& aTransform) { - if (mTransform.ExactlyEquals(aTransform)) { - return; - } DrawTarget::SetTransform(aTransform); - mRecorder->RecordEvent(this, RecordedSetTransform(aTransform)); + if (!mOptimizeTransform) { + FlushTransform(); + } +} + +void DrawTargetRecording::RecordTransform(const Matrix& aTransform) const { + RecordEventSelfSkipFlushTransform(RecordedSetTransform(aTransform)); + mRecordedTransform = aTransform; } void DrawTargetRecording::SetPermitSubpixelAA(bool aPermitSubpixelAA) { @@ -848,7 +858,8 @@ void DrawTargetRecording::SetPermitSubpixelAA(bool aPermitSubpixelAA) { return; } DrawTarget::SetPermitSubpixelAA(aPermitSubpixelAA); - mRecorder->RecordEvent(this, RecordedSetPermitSubpixelAA(aPermitSubpixelAA)); + RecordEventSelfSkipFlushTransform( + RecordedSetPermitSubpixelAA(aPermitSubpixelAA)); } already_AddRefed DrawTargetRecording::EnsurePathStored( @@ -874,7 +885,7 @@ already_AddRefed DrawTargetRecording::EnsurePathStored( // It's important that AddStoredObject or TryAddStoredObject is called before // this because that will run any pending processing required by recorded // objects that have been deleted off the main thread. - mRecorder->RecordEvent(this, RecordedPathCreation(pathRecording.get())); + RecordEventSelfSkipFlushTransform(RecordedPathCreation(pathRecording.get())); pathRecording->mStoredRecorders.push_back(mRecorder); return pathRecording.forget(); @@ -887,13 +898,16 @@ void DrawTargetRecording::FlushItem(const IntRect& aBounds) { // Reinitialize the recorder (FlushItem will write a new recording header) // Tell the new recording about our draw target // This code should match what happens in the DrawTargetRecording constructor. - MOZ_DIAGNOSTIC_ASSERT(mRecorder->GetRecorderType() != RecorderType::CANVAS); - mRecorder->RecordEvent( + MOZ_DIAGNOSTIC_ASSERT(mRecorder->GetRecorderType() == + RecorderType::WEBRENDER); + RecordEventSkipFlushTransform( RecordedDrawTargetCreation(this, mFinalDT->GetBackendType(), mRect, mFinalDT->GetFormat(), false, nullptr)); - // Add the current transform to the new recording - mRecorder->RecordEvent(this, - RecordedSetTransform(DrawTarget::GetTransform())); + // RecordedDrawTargetCreation can actually reuse the base DrawTarget for the + // recording, but we cannot conclude that from here, so force the transform + // to be recorded. + RecordTransform(mTransform); + mTransformDirty = false; } void DrawTargetRecording::EnsurePatternDependenciesStored( diff --git a/gfx/2d/DrawTargetRecording.h b/gfx/2d/DrawTargetRecording.h index 239d7ccfd4..5b24bd2987 100644 --- a/gfx/2d/DrawTargetRecording.h +++ b/gfx/2d/DrawTargetRecording.h @@ -18,7 +18,7 @@ struct RemoteTextureOwnerId; namespace gfx { -class DrawTargetRecording : public DrawTarget { +class DrawTargetRecording final : public DrawTarget { public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetRecording, override) DrawTargetRecording(DrawEventRecorder* aRecorder, DrawTarget* aDT, @@ -71,6 +71,13 @@ class DrawTargetRecording : public DrawTarget { const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), const DrawOptions& aOptions = DrawOptions()) override; + virtual void DrawSurfaceDescriptor( + const layers::SurfaceDescriptor& aDesc, + const RefPtr& aImageOfSurfaceDescriptor, const Rect& aDest, + const Rect& aSource, + const DrawSurfaceOptions& aSurfOptions = DrawSurfaceOptions(), + const DrawOptions& aOptions = DrawOptions()) override; + virtual void DrawDependentSurface(uint64_t aId, const Rect& aDest) override; virtual void DrawFilter(FilterNode* aNode, const Rect& aSourceRect, @@ -369,6 +376,10 @@ class DrawTargetRecording : public DrawTarget { void MarkClean() { mIsDirty = false; } + void SetOptimizeTransform(bool aOptimizeTransform) { + mOptimizeTransform = aOptimizeTransform; + } + private: /** * Used for creating a DrawTargetRecording for a CreateSimilarDrawTarget call. @@ -380,6 +391,35 @@ class DrawTargetRecording : public DrawTarget { DrawTargetRecording(const DrawTargetRecording* aDT, IntRect aRect, SurfaceFormat aFormat); + void RecordTransform(const Matrix& aTransform) const; + + void FlushTransform() const { + if (mTransformDirty) { + if (!mRecordedTransform.ExactlyEquals(mTransform)) { + RecordTransform(mTransform); + } + mTransformDirty = false; + } + } + + void RecordEvent(const RecordedEvent& aEvent) const { + FlushTransform(); + mRecorder->RecordEvent(aEvent); + } + + void RecordEventSelf(const RecordedEvent& aEvent) const { + FlushTransform(); + mRecorder->RecordEvent(this, aEvent); + } + + void RecordEventSkipFlushTransform(const RecordedEvent& aEvent) const { + mRecorder->RecordEvent(aEvent); + } + + void RecordEventSelfSkipFlushTransform(const RecordedEvent& aEvent) const { + mRecorder->RecordEvent(this, aEvent); + } + Path* GetPathForPathRecording(const Path* aPath) const; already_AddRefed EnsurePathStored(const Path* aPath); void EnsurePatternDependenciesStored(const Pattern& aPattern); @@ -403,6 +443,10 @@ class DrawTargetRecording : public DrawTarget { std::vector mPushedLayers; bool mIsDirty = false; + bool mOptimizeTransform = false; + + // Last transform that was used in the recording. + mutable Matrix mRecordedTransform; }; } // namespace gfx diff --git a/gfx/2d/RecordedEvent.cpp b/gfx/2d/RecordedEvent.cpp index 265ee1904b..c89bd99d4c 100644 --- a/gfx/2d/RecordedEvent.cpp +++ b/gfx/2d/RecordedEvent.cpp @@ -70,6 +70,8 @@ std::string RecordedEvent::GetEventName(EventType aType) { return "Stroke"; case DRAWSURFACE: return "DrawSurface"; + case DRAWSURFACEDESCRIPTOR: + return "DrawSurfaceDescriptor"; case DRAWDEPENDENTSURFACE: return "DrawDependentSurface"; case DRAWSURFACEWITHSHADOW: diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h index a8801ddd1f..835460ff25 100644 --- a/gfx/2d/RecordedEvent.h +++ b/gfx/2d/RecordedEvent.h @@ -102,6 +102,12 @@ class Translator { virtual already_AddRefed LookupExternalSurface(uint64_t aKey) { return nullptr; } + virtual already_AddRefed + LookupSourceSurfaceFromSurfaceDescriptor( + const layers::SurfaceDescriptor& aDesc) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + return nullptr; + } void DrawDependentSurface(uint64_t aKey, const Rect& aRect); virtual void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget* aDT) = 0; virtual void RemoveDrawTarget(ReferencePtr aRefPtr) = 0; @@ -389,6 +395,7 @@ class RecordedEvent { MASK, STROKE, DRAWSURFACE, + DRAWSURFACEDESCRIPTOR, DRAWDEPENDENTSURFACE, DRAWSURFACEWITHSHADOW, DRAWSHADOW, diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h index a880536bf8..1d8a275c63 100644 --- a/gfx/2d/RecordedEventImpl.h +++ b/gfx/2d/RecordedEventImpl.h @@ -17,6 +17,8 @@ #include "ScaledFontBase.h" #include "SFNTData.h" +#include "mozilla/layers/LayersSurfaces.h" + namespace mozilla { namespace gfx { @@ -852,6 +854,41 @@ class RecordedDrawSurface : public RecordedEventDerived { DrawOptions mOptions; }; +class RecordedDrawSurfaceDescriptor + : public RecordedEventDerived { + public: + RecordedDrawSurfaceDescriptor(const layers::SurfaceDescriptor& aDesc, + const Rect& aDest, const Rect& aSource, + const DrawSurfaceOptions& aDSOptions, + const DrawOptions& aOptions) + : RecordedEventDerived(DRAWSURFACEDESCRIPTOR), + mDesc(aDesc), + mDest(aDest), + mSource(aSource), + mDSOptions(aDSOptions), + mOptions(aOptions) {} + + bool PlayEvent(Translator* aTranslator) const override; + + template + void Record(S& aStream) const; + void OutputSimpleEventInfo(std::stringstream& aStringStream) const override; + + std::string GetName() const override { return "DrawSurfaceDescriptor"; } + + private: + friend class RecordedEvent; + + template + MOZ_IMPLICIT RecordedDrawSurfaceDescriptor(S& aStream); + + layers::SurfaceDescriptor mDesc; + Rect mDest; + Rect mSource; + DrawSurfaceOptions mDSOptions; + DrawOptions mOptions; +}; + class RecordedDrawDependentSurface : public RecordedEventDerived { public: @@ -3141,6 +3178,52 @@ inline void RecordedDrawSurface::OutputSimpleEventInfo( aStringStream << "DrawSurface (" << mRefSource << ")"; } +inline bool RecordedDrawSurfaceDescriptor::PlayEvent( + Translator* aTranslator) const { + DrawTarget* dt = aTranslator->GetCurrentDrawTarget(); + if (!dt) { + return false; + } + + RefPtr surface = + aTranslator->LookupSourceSurfaceFromSurfaceDescriptor(mDesc); + if (!surface) { + return false; + } + + RefPtr opt = dt->OptimizeSourceSurface(surface); + if (opt) { + surface = opt; + } + + dt->DrawSurface(surface, mDest, mSource, mDSOptions, mOptions); + return true; +} + +template +void RecordedDrawSurfaceDescriptor::Record(S& aStream) const { + WriteElement(aStream, mDesc); + WriteElement(aStream, mDest); + WriteElement(aStream, mSource); + WriteElement(aStream, mDSOptions); + WriteElement(aStream, mOptions); +} + +template +RecordedDrawSurfaceDescriptor::RecordedDrawSurfaceDescriptor(S& aStream) + : RecordedEventDerived(DRAWSURFACEDESCRIPTOR) { + ReadElement(aStream, mDesc); + ReadElement(aStream, mDest); + ReadElement(aStream, mSource); + ReadDrawSurfaceOptions(aStream, mDSOptions); + ReadDrawOptions(aStream, mOptions); +} + +inline void RecordedDrawSurfaceDescriptor::OutputSimpleEventInfo( + std::stringstream& aStringStream) const { + aStringStream << "DrawSurfaceDescriptor (" << mDesc.type() << ")"; +} + inline bool RecordedDrawDependentSurface::PlayEvent( Translator* aTranslator) const { aTranslator->DrawDependentSurface(mId, mDest); @@ -4379,6 +4462,7 @@ inline void RecordedDestination::OutputSimpleEventInfo( f(MASK, RecordedMask); \ f(STROKE, RecordedStroke); \ f(DRAWSURFACE, RecordedDrawSurface); \ + f(DRAWSURFACEDESCRIPTOR, RecordedDrawSurfaceDescriptor); \ f(DRAWDEPENDENTSURFACE, RecordedDrawDependentSurface); \ f(DRAWSURFACEWITHSHADOW, RecordedDrawSurfaceWithShadow); \ f(DRAWSHADOW, RecordedDrawShadow); \ diff --git a/gfx/2d/SkConvolver.cpp b/gfx/2d/SkConvolver.cpp index befe8da30b..b89a486d48 100644 --- a/gfx/2d/SkConvolver.cpp +++ b/gfx/2d/SkConvolver.cpp @@ -5,7 +5,6 @@ // found in the gfx/skia/LICENSE file. #include "SkConvolver.h" -#include "mozilla/Vector.h" #ifdef USE_SSE2 # include "mozilla/SSE.h" @@ -235,9 +234,11 @@ class CircularRowBuffer { : fRowByteWidth(destRowPixelWidth * 4), fNumRows(maxYFilterSize), fNextRow(0), - fNextRowCoordinate(firstInputRow) { - fBuffer.resize(fRowByteWidth * maxYFilterSize); - fRowAddresses.resize(fNumRows); + fNextRowCoordinate(firstInputRow) {} + + bool AllocBuffer() { + return fBuffer.resize(fRowByteWidth * fNumRows) && + fRowAddresses.resize(fNumRows); } // Moves to the next row in the buffer, returning a pointer to the beginning @@ -288,7 +289,7 @@ class CircularRowBuffer { private: // The buffer storing the rows. They are packed, each one fRowByteWidth. - std::vector fBuffer; + mozilla::Vector fBuffer; // Number of bytes per row in the |buffer|. int fRowByteWidth; @@ -305,14 +306,14 @@ class CircularRowBuffer { int fNextRowCoordinate; // Buffer used by GetRowAddresses(). - std::vector fRowAddresses; + mozilla::Vector fRowAddresses; }; SkConvolutionFilter1D::SkConvolutionFilter1D() : fMaxFilter(0) {} SkConvolutionFilter1D::~SkConvolutionFilter1D() = default; -void SkConvolutionFilter1D::AddFilter(int filterOffset, +bool SkConvolutionFilter1D::AddFilter(int filterOffset, const ConvolutionFixed* filterValues, int filterLength) { // It is common for leading/trailing filter values to be zeros. In such @@ -336,8 +337,9 @@ void SkConvolutionFilter1D::AddFilter(int filterOffset, filterLength = lastNonZero + 1 - firstNonZero; MOZ_ASSERT(filterLength > 0); - fFilterValues.insert(fFilterValues.end(), &filterValues[firstNonZero], - &filterValues[lastNonZero + 1]); + if (!fFilterValues.append(&filterValues[firstNonZero], filterLength)) { + return false; + } } else { // Here all the factors were zeroes. filterLength = 0; @@ -345,11 +347,17 @@ void SkConvolutionFilter1D::AddFilter(int filterOffset, FilterInstance instance = { // We pushed filterLength elements onto fFilterValues - int(fFilterValues.size()) - filterLength, filterOffset, filterLength, + int(fFilterValues.length()) - filterLength, filterOffset, filterLength, filterSize}; - fFilters.push_back(instance); + if (!fFilters.append(instance)) { + if (filterLength > 0) { + fFilterValues.shrinkBy(filterLength); + } + return false; + } fMaxFilter = std::max(fMaxFilter, filterLength); + return true; } bool SkConvolutionFilter1D::ComputeFilterValues( @@ -383,10 +391,13 @@ bool SkConvolutionFilter1D::ComputeFilterValues( int32_t filterValueCount = int32_t(ceilf(aDstSize * srcSupport * 2)); if (aDstSize > maxToPassToReserveAdditional || filterValueCount < 0 || - filterValueCount > maxToPassToReserveAdditional) { + filterValueCount > maxToPassToReserveAdditional || + !reserveAdditional(aDstSize, filterValueCount)) { return false; } - reserveAdditional(aDstSize, filterValueCount); + size_t oldFiltersLength = fFilters.length(); + size_t oldFilterValuesLength = fFilterValues.length(); + int oldMaxFilter = fMaxFilter; for (int32_t destI = 0; destI < aDstSize; destI++) { // This is the pixel in the source directly under the pixel in the dest. // Note that we base computations on the "center" of the pixels. To see @@ -443,7 +454,12 @@ bool SkConvolutionFilter1D::ComputeFilterValues( ConvolutionFixed leftovers = ToFixed(1) - fixedSum; fixedFilterValues[filterCount / 2] += leftovers; - AddFilter(int32_t(srcBegin), fixedFilterValues.begin(), filterCount); + if (!AddFilter(int32_t(srcBegin), fixedFilterValues.begin(), filterCount)) { + fFilters.shrinkTo(oldFiltersLength); + fFilterValues.shrinkTo(oldFilterValuesLength); + fMaxFilter = oldMaxFilter; + return false; + } } return maxFilter() > 0 && numValues() == aDstSize; @@ -515,6 +531,9 @@ bool BGRAConvolve2D(const unsigned char* sourceData, int sourceByteRowStride, } CircularRowBuffer rowBuffer(rowBufferWidth, rowBufferHeight, filterOffset); + if (!rowBuffer.AllocBuffer()) { + return false; + } // Loop over every possible output row, processing just enough horizontal // convolutions to run each subsequent vertical convolution. diff --git a/gfx/2d/SkConvolver.h b/gfx/2d/SkConvolver.h index 5ea8ab9b5d..e21b2be024 100644 --- a/gfx/2d/SkConvolver.h +++ b/gfx/2d/SkConvolver.h @@ -10,7 +10,7 @@ #include "mozilla/Assertions.h" #include #include -#include +#include "mozilla/Vector.h" namespace skia { @@ -81,11 +81,11 @@ class SkConvolutionFilter1D { // Returns the number of filters in this filter. This is the dimension of the // output image. - int numValues() const { return static_cast(fFilters.size()); } + int numValues() const { return static_cast(fFilters.length()); } - void reserveAdditional(int filterCount, int filterValueCount) { - fFilters.reserve(fFilters.size() + filterCount); - fFilterValues.reserve(fFilterValues.size() + filterValueCount); + bool reserveAdditional(int filterCount, int filterValueCount) { + return fFilters.reserve(fFilters.length() + filterCount) && + fFilterValues.reserve(fFilterValues.length() + filterValueCount); } // Appends the given list of scaling values for generating a given output @@ -98,7 +98,7 @@ class SkConvolutionFilter1D { // brighness of the image. // // The filterLength must be > 0. - void AddFilter(int filterOffset, const ConvolutionFixed* filterValues, + bool AddFilter(int filterOffset, const ConvolutionFixed* filterValues, int filterLength); // Retrieves a filter for the given |valueOffset|, a position in the output @@ -139,12 +139,12 @@ class SkConvolutionFilter1D { }; // Stores the information for each filter added to this class. - std::vector fFilters; + mozilla::Vector fFilters; // We store all the filter values in this flat list, indexed by // |FilterInstance.data_location| to avoid the mallocs required for storing // each one separately. - std::vector fFilterValues; + mozilla::Vector fFilterValues; // The maximum size of any filter we've added. int fMaxFilter; -- cgit v1.2.3