From 9d0fbfa02c72538f3d6f4e99e5f9d3d74fc22006 Mon Sep 17 00:00:00 2001 From: Markus Stange Date: Fri, 24 Oct 2014 18:32:22 +0200 Subject: [PATCH] Bug 1074842 - Let SourceSurfaceCGBitmapContext take ownership of the data when DrawTargetCG is destroyed. r=jrmuizel --- gfx/2d/DrawTargetCG.cpp | 8 +++++++- gfx/2d/DrawTargetCG.h | 1 + gfx/2d/SourceSurfaceCG.cpp | 18 ++++++++++++++++++ gfx/2d/SourceSurfaceCG.h | 3 +++ gfx/2d/Tools.h | 8 ++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/gfx/2d/DrawTargetCG.cpp b/gfx/2d/DrawTargetCG.cpp index bea930b2126c..d42920c4cc4e 100644 --- a/gfx/2d/DrawTargetCG.cpp +++ b/gfx/2d/DrawTargetCG.cpp @@ -149,7 +149,13 @@ DrawTargetCG::DrawTargetCG() DrawTargetCG::~DrawTargetCG() { - MarkChanged(); + if (mSnapshot) { + if (mSnapshot->refCount() > 1) { + // We only need to worry about snapshots that someone else knows about + mSnapshot->DrawTargetWillGoAway(); + } + mSnapshot = nullptr; + } // Both of these are OK with nullptr arguments, so we do not // need to check (these could be nullptr if Init fails) diff --git a/gfx/2d/DrawTargetCG.h b/gfx/2d/DrawTargetCG.h index 4284c495d2dc..382d9f77f2ca 100644 --- a/gfx/2d/DrawTargetCG.h +++ b/gfx/2d/DrawTargetCG.h @@ -97,6 +97,7 @@ class DrawTargetCG : public DrawTarget public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetCG) friend class BorrowedCGContext; + friend class SourceSurfaceCGBitmapContext; DrawTargetCG(); virtual ~DrawTargetCG(); diff --git a/gfx/2d/SourceSurfaceCG.cpp b/gfx/2d/SourceSurfaceCG.cpp index 49def436c064..12b038c20d9e 100644 --- a/gfx/2d/SourceSurfaceCG.cpp +++ b/gfx/2d/SourceSurfaceCG.cpp @@ -360,6 +360,24 @@ SourceSurfaceCGBitmapContext::DrawTargetWillChange() } } +void +SourceSurfaceCGBitmapContext::DrawTargetWillGoAway() +{ + if (mDrawTarget) { + if (mDrawTarget->mData != CGBitmapContextGetData(mCg)) { + DrawTargetWillChange(); + return; + } + + // Instead of copying the data over, we can just swap it. + mDataHolder.Swap(mDrawTarget->mData); + mData = mDataHolder; + mCg = nullptr; + mDrawTarget = nullptr; + // mImage is still valid because it still points to the same data. + } +} + SourceSurfaceCGBitmapContext::~SourceSurfaceCGBitmapContext() { if (mImage) diff --git a/gfx/2d/SourceSurfaceCG.h b/gfx/2d/SourceSurfaceCG.h index 24529e399a87..9e1798490e71 100644 --- a/gfx/2d/SourceSurfaceCG.h +++ b/gfx/2d/SourceSurfaceCG.h @@ -101,6 +101,7 @@ class SourceSurfaceCGContext : public DataSourceSurface public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceCGContext) virtual void DrawTargetWillChange() = 0; + virtual void DrawTargetWillGoAway() = 0; virtual CGImageRef GetImage() = 0; }; @@ -139,6 +140,7 @@ private: //XXX: do the other backends friend their DrawTarget? friend class DrawTargetCG; virtual void DrawTargetWillChange(); + virtual void DrawTargetWillGoAway(); void EnsureImage() const; // We hold a weak reference to these two objects. @@ -181,6 +183,7 @@ private: //XXX: do the other backends friend their DrawTarget? friend class DrawTargetCG; virtual void DrawTargetWillChange(); + virtual void DrawTargetWillGoAway() { DrawTargetWillChange(); } void EnsureImage() const; SurfaceFormat mFormat; diff --git a/gfx/2d/Tools.h b/gfx/2d/Tools.h index 0cde7d6d4d40..d7405c75bce6 100644 --- a/gfx/2d/Tools.h +++ b/gfx/2d/Tools.h @@ -7,6 +7,7 @@ #define MOZILLA_GFX_TOOLS_H_ #include "mozilla/CheckedInt.h" +#include "mozilla/Move.h" #include "mozilla/TypeTraits.h" #include "Types.h" #include "Point.h" @@ -178,6 +179,13 @@ struct AlignedArray mCount = aCount; } + void Swap(AlignedArray& aOther) + { + mozilla::Swap(mPtr, aOther.mPtr); + mozilla::Swap(mStorage, aOther.mStorage); + mozilla::Swap(mCount, aOther.mCount); + } + MOZ_ALWAYS_INLINE operator T*() { return mPtr;