Bug 1364241. Handle empty transactions by keeping around the blob data. r=mchang
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Thu, 11 May 2017 18:32:36 -0400
changeset 359320 d4ffcd51dcf4d5518814d6718890a9b8122b644f
parent 359319 ebe76ed8ce973c01595f8893d4a04cfb42275748
child 359321 2cc47f8ec512cde03858259c0479d6cf70a7134d
push id31852
push userkwierso@gmail.com
push dateFri, 19 May 2017 21:47:27 +0000
treeherdermozilla-central@979f11deabd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1364241
milestone55.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 1364241. Handle empty transactions by keeping around the blob data. r=mchang This just wasn't implemented before.
gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
gfx/layers/wr/WebRenderPaintedLayerBlob.h
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
@@ -42,60 +42,60 @@ WebRenderPaintedLayerBlob::RenderLayer(w
   // We have something to paint but can't. This usually happens only in
   // empty transactions
   if (!regionToPaint.IsEmpty() && !WrManager()->GetPaintedLayerCallback()) {
     WrManager()->SetTransactionIncomplete();
     return;
   }
 
   IntSize imageSize(size.ToUnknownSize());
-  RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
-  RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, imageSize, gfx::SurfaceFormat::B8G8R8X8);
-  RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt);
+  if (!regionToPaint.IsEmpty() && WrManager()->GetPaintedLayerCallback()) {
+    RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
+    RefPtr<gfx::DrawTarget> dummyDt = gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, imageSize, gfx::SurfaceFormat::B8G8R8X8);
+    RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt);
 
-  if (!regionToPaint.IsEmpty() && WrManager()->GetPaintedLayerCallback()) {
     dt->ClearRect(Rect(0, 0, imageSize.width, imageSize.height));
     dt->SetTransform(Matrix().PreTranslate(-bounds.x, -bounds.y));
     RefPtr<gfxContext> ctx = gfxContext::CreatePreservingTransformOrNull(dt);
     MOZ_ASSERT(ctx); // already checked the target above
 
     WrManager()->GetPaintedLayerCallback()(this,
                                            ctx,
                                            visibleRegion.ToUnknownRegion(), visibleRegion.ToUnknownRegion(),
                                            DrawRegionClip::DRAW, nsIntRegion(), WrManager()->GetPaintedLayerCallbackData());
 
     if (gfxPrefs::WebRenderHighlightPaintedLayers()) {
       dt->SetTransform(Matrix());
       dt->FillRect(Rect(0, 0, imageSize.width, imageSize.height), ColorPattern(Color(1.0, 0.0, 0.0, 0.5)));
     }
 
+    wr::ByteBuffer bytes;
+    bytes.Allocate(recorder->RecordingSize());
+    DebugOnly<bool> ok = recorder->CopyRecording((char*)bytes.AsSlice().begin().get(), bytes.AsSlice().length());
+    MOZ_ASSERT(ok);
+
+    //XXX: We should switch to updating the blob image instead of adding a new one
+    //     That will get rid of this discard bit
+    if (mImageKey.isSome()) {
+      WrManager()->AddImageKeyForDiscard(mImageKey.value());
+    }
+    mImageKey = Some(GetImageKey());
+    WrBridge()->SendAddBlobImage(mImageKey.value(), imageSize, size.width * 4, dt->GetFormat(), bytes);
   } else {
-    // we need to reuse the blob image
-    MOZ_ASSERT(mExternalImageId);
-    MOZ_ASSERT(mImageContainer->HasCurrentImage());
     MOZ_ASSERT(GetInvalidRegion().IsEmpty());
   }
 
-  wr::ByteBuffer bytes;
-  bytes.Allocate(recorder->RecordingSize());
-  DebugOnly<bool> ok = recorder->CopyRecording((char*)bytes.AsSlice().begin().get(), bytes.AsSlice().length());
-  MOZ_ASSERT(ok);
-
   ScrollingLayersHelper scroller(this, aBuilder, aSc);
   StackingContextHelper sc(aSc, aBuilder, this);
   LayerRect rect = Bounds();
   DumpLayerInfo("PaintedLayer", rect);
 
   LayerRect clipRect = ClipRect().valueOr(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(&sc);
   WrClipRegionToken clip = aBuilder.PushClipRegion(
       sc.ToRelativeWrRect(clipRect),
       mask.ptrOr(nullptr));
 
-  WrImageKey key = GetImageKey();
-  WrBridge()->SendAddBlobImage(key, imageSize, size.width * 4, dt->GetFormat(), bytes);
-  WrManager()->AddImageKeyForDiscard(key);
-
-  aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, wr::ImageRendering::Auto, key);
+  aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, wr::ImageRendering::Auto, mImageKey.value());
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.h
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.h
@@ -30,16 +30,19 @@ public:
 
 protected:
   virtual ~WebRenderPaintedLayerBlob()
   {
     MOZ_COUNT_DTOR(WebRenderPaintedLayerBlob);
     if (mExternalImageId.isSome()) {
       WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
     }
+    if (mImageKey.isSome()) {
+      WrManager()->AddImageKeyForDiscard(mImageKey.value());
+    }
   }
 
   wr::MaybeExternalImageId mExternalImageId;
 
 public:
   virtual void InvalidateRegion(const nsIntRegion& aRegion) override
   {
     mInvalidRegion.Add(aRegion);
@@ -47,15 +50,15 @@ public:
   }
 
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder,
                    const StackingContextHelper& aSc) override;
 private:
   RefPtr<ImageContainer> mImageContainer;
   RefPtr<ImageClient> mImageClient;
-
+  Maybe<WrImageKey> mImageKey;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERPAINTEDLAYERBLOB_H