Bug 1423281: Store the userdata for freeing our memory on the longer living snapshot. r=dvander draft
authorBas Schouten <bschouten@mozilla.com>
Tue, 05 Dec 2017 19:15:02 +0100
changeset 707730 4633f0654445421932aba87a7b70971bd094ce4f
parent 707618 3942ce38b1f62fbc3154e42281d31cbed1e81ce0
child 743016 e6b03fc730e3b0ff57f4ee1e199df0d94aa9066f
push id92197
push userbschouten@mozilla.com
push dateTue, 05 Dec 2017 18:15:26 +0000
reviewersdvander
bugs1423281
milestone59.0a1
Bug 1423281: Store the userdata for freeing our memory on the longer living snapshot. r=dvander MozReview-Commit-ID: 91tVpJC7gAe
gfx/2d/SourceSurfaceCapture.cpp
--- a/gfx/2d/SourceSurfaceCapture.cpp
+++ b/gfx/2d/SourceSurfaceCapture.cpp
@@ -89,55 +89,67 @@ SourceSurfaceCapture::Resolve(BackendTyp
   }
   return mResolved;
 }
 
 RefPtr<SourceSurface>
 SourceSurfaceCapture::ResolveImpl(BackendType aBackendType)
 {
   RefPtr<DrawTarget> dt;
+  uint8_t* data = nullptr;
   if (!mSurfaceAllocationSize) {
     if (aBackendType == mRefDT->GetBackendType()) {
       dt = mRefDT->CreateSimilarDrawTarget(mSize, mFormat);
     } else {
       dt = Factory::CreateDrawTarget(aBackendType, mSize, mFormat);
     }
   } else {
-    uint8_t* data = static_cast<uint8_t*>(calloc(1, mSurfaceAllocationSize));
+    data = static_cast<uint8_t*>(calloc(1, mSurfaceAllocationSize));
     if (!data) {
       return nullptr;
     }
     BackendType type = Factory::DoesBackendSupportDataDrawtarget(aBackendType)
                        ? aBackendType
                        : BackendType::SKIA;
     dt = Factory::CreateDrawTargetForData(type, data, mSize, mStride, mFormat);
     if (!dt) {
       free(data);
       return nullptr;
     }
-    dt->AddUserData(reinterpret_cast<UserDataKey*>(dt.get()), data, free);
   }
+
   if (!dt) {
+    // Make sure we haven't allocated and aren't leaking something, the code right
+    // anove here should have guaranteed that.
+    MOZ_ASSERT(!data);
     return nullptr;
   }
 
   // If we're still attached to a DrawTarget, use its command list rather than
   // our own (which will be empty).
   CaptureCommandList& commands = mHasCommandList
                                  ? mCommands
                                  : mOwner->mCommands;
   for (CaptureCommandList::iterator iter(commands); !iter.Done(); iter.Next()) {
     DrawingCommand* cmd = iter.Get();
     cmd->ExecuteOnDT(dt, nullptr);
   }
+
+  RefPtr<SourceSurface> surf;
   if (!mShouldResolveToLuminance) {
-    return dt->Snapshot();
+    surf = dt->Snapshot();
   } else {
-    return dt->IntoLuminanceSource(mLuminanceType, mOpacity);
+    surf = dt->IntoLuminanceSource(mLuminanceType, mOpacity);
   }
+
+  if (data) {
+    surf->AddUserData(reinterpret_cast<UserDataKey*>(dt.get()), data, free);
+  }
+
+  return surf.forget();
 }
 
 already_AddRefed<DataSourceSurface>
 SourceSurfaceCapture::GetDataSurface()
 {
   RefPtr<SourceSurface> surface = Resolve();
   if (!surface) {
     return nullptr;