Bug 881634 - Only use a single snapshot with DrawTargetSkia. r=Bas
☠☠ backed out by 5695cebb5c12 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 01 Aug 2013 21:12:16 -0400
changeset 141286 e0e2e27af6c130aa0dbbcef50b20787c11519507
parent 141285 25f9ed87069cc89143cf053b31c4bc17ae0cb7ee
child 141287 a857a4246dd988ee8273e1f99a0c0d6d50cb6c59
push id25054
push usercbook@mozilla.com
push dateMon, 05 Aug 2013 09:19:53 +0000
treeherdermozilla-central@54434a926c5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs881634
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 881634 - Only use a single snapshot with DrawTargetSkia. r=Bas
gfx/2d/DrawTargetSkia.cpp
gfx/2d/DrawTargetSkia.h
gfx/2d/SourceSurfaceSkia.cpp
gfx/2d/SourceSurfaceSkia.h
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -71,39 +71,41 @@ public:
 
   std::vector<SkColor> mColors;
   std::vector<SkScalar> mPositions;
   int mCount;
   ExtendMode mExtendMode;
 };
 
 DrawTargetSkia::DrawTargetSkia()
+  : mSnapshot(nullptr)
 {
 #ifdef ANDROID
   mSoftClipping = false;
 #else
   mSoftClipping = true;
 #endif
 }
 
 DrawTargetSkia::~DrawTargetSkia()
 {
-  MOZ_ASSERT(mSnapshots.size() == 0);
 }
 
 TemporaryRef<SourceSurface>
 DrawTargetSkia::Snapshot()
 {
-  RefPtr<SourceSurfaceSkia> source = new SourceSurfaceSkia();
+  RefPtr<SourceSurfaceSkia> snapshot = mSnapshot;
+  if (!snapshot) {
+    snapshot = new SourceSurfaceSkia();
+    mSnapshot = snapshot;
+    if (!snapshot->InitFromCanvas(mCanvas.get(), mFormat, this))
+      return nullptr;
+  }
 
-  if (!source->InitFromCanvas(mCanvas.get(), mFormat, this))
-    return nullptr;
-
-  AppendSnapshot(source);
-  return source;
+  return snapshot;
 }
 
 void SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, Float aAlpha = 1.0)
 {
   switch (aPattern.GetType()) {
     case PATTERN_COLOR: {
       Color color = static_cast<const ColorPattern&>(aPattern).mColor;
       aPaint.setColor(ColorToSkColor(color, aAlpha));
@@ -768,37 +770,24 @@ DrawTargetSkia::CreateGradientStops(Grad
     stops[i] = aStops[i];
   }
   std::stable_sort(stops.begin(), stops.end());
   
   return new GradientStopsSkia(stops, aNumStops, aExtendMode);
 }
 
 void
-DrawTargetSkia::AppendSnapshot(SourceSurfaceSkia* aSnapshot)
+DrawTargetSkia::MarkChanged()
 {
-  mSnapshots.push_back(aSnapshot);
-}
-
-void
-DrawTargetSkia::RemoveSnapshot(SourceSurfaceSkia* aSnapshot)
-{
-  std::vector<SourceSurfaceSkia*>::iterator iter = std::find(mSnapshots.begin(), mSnapshots.end(), aSnapshot);
-  if (iter != mSnapshots.end()) {
-    mSnapshots.erase(iter);
+  if (mSnapshot) {
+    mSnapshot->DrawTargetWillChange();
+    mSnapshot = nullptr;
   }
 }
 
 void
-DrawTargetSkia::MarkChanged()
+DrawTargetSkia::SnapshotDestroyed()
 {
-  if (mSnapshots.size()) {
-    for (std::vector<SourceSurfaceSkia*>::iterator iter = mSnapshots.begin();
-         iter != mSnapshots.end(); iter++) {
-      (*iter)->DrawTargetWillChange();
-    }
-    // All snapshots will now have copied data.
-    mSnapshots.clear();
-  }
+  mSnapshot = nullptr;
 }
 
 }
 }
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -109,18 +109,17 @@ public:
   operator std::string() const {
     std::stringstream stream;
     stream << "DrawTargetSkia(" << this << ")";
     return stream.str();
   }
 
 private:
   friend class SourceSurfaceSkia;
-  void AppendSnapshot(SourceSurfaceSkia* aSnapshot);
-  void RemoveSnapshot(SourceSurfaceSkia* aSnapshot);
+  void SnapshotDestroyed();
 
   void MarkChanged();
 
 #ifdef USE_SKIA_GPU
   /*
    * These members have inter-dependencies, but do not keep each other alive, so
    * destruction order is very important here: mGrContext uses mGrGLInterface, and
    * through it, uses mGLContext, so it is important that they be declared in the
@@ -128,14 +127,14 @@ private:
    */
   RefPtr<GenericRefCountedBase> mGLContext;
   SkRefPtr<GrGLInterface> mGrGLInterface;
   SkRefPtr<GrContext> mGrContext;
 #endif
 
   IntSize mSize;
   SkRefPtr<SkCanvas> mCanvas;
-  std::vector<SourceSurfaceSkia*> mSnapshots;
+  SourceSurfaceSkia* mSnapshot;
   bool mSoftClipping;
 };
 
 }
 }
--- a/gfx/2d/SourceSurfaceSkia.cpp
+++ b/gfx/2d/SourceSurfaceSkia.cpp
@@ -17,17 +17,20 @@ namespace gfx {
 SourceSurfaceSkia::SourceSurfaceSkia()
   : mDrawTarget(nullptr), mLocked(false)
 {
 }
 
 SourceSurfaceSkia::~SourceSurfaceSkia()
 {
   MaybeUnlock();
-  MarkIndependent();
+  if (mDrawTarget) {
+    mDrawTarget->SnapshotDestroyed();
+    mDrawTarget = nullptr;
+  }
 }
 
 IntSize
 SourceSurfaceSkia::GetSize() const
 {
   return mSize;
 }
 
@@ -104,25 +107,16 @@ SourceSurfaceSkia::DrawTargetWillChange(
     mDrawTarget = nullptr;
     SkBitmap temp = mBitmap;
     mBitmap.reset();
     temp.copyTo(&mBitmap, temp.getConfig());
   }
 }
 
 void
-SourceSurfaceSkia::MarkIndependent()
-{
-  if (mDrawTarget) {
-    mDrawTarget->RemoveSnapshot(this);
-    mDrawTarget = nullptr;
-  }
-}
-
-void
 SourceSurfaceSkia::MaybeUnlock()
 {
   if (mLocked) {
     mBitmap.unlockPixels();
     mLocked = false;
   }
 }
 
--- a/gfx/2d/SourceSurfaceSkia.h
+++ b/gfx/2d/SourceSurfaceSkia.h
@@ -40,18 +40,16 @@ public:
   virtual unsigned char *GetData();
 
   virtual int32_t Stride() { return mStride; }
 
 private:
   friend class DrawTargetSkia;
 
   void DrawTargetWillChange();
-  void DrawTargetDestroyed();
-  void MarkIndependent();
   void MaybeUnlock();
 
   SkBitmap mBitmap;
   SurfaceFormat mFormat;
   IntSize mSize;
   int32_t mStride;
   RefPtr<DrawTargetSkia> mDrawTarget;
   bool mLocked;