Bug 1363347 - Allow multiple external image IDs to be bound to the same image host if owned by the same WRBridge. r=sotaro
authorAndrew Osmond <aosmond@mozilla.com>
Thu, 18 May 2017 06:50:03 -0400
changeset 359333 954c86fc79b03c874f8478fa1ec0245d5ee5f485
parent 359332 b821901e8fad581f5714362c7a480b96c5384381
child 359334 26b53523d9c22e6c4a6a16bdf964080641c0eb45
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)
reviewerssotaro
bugs1363347
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 1363347 - Allow multiple external image IDs to be bound to the same image host if owned by the same WRBridge. r=sotaro
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderImageHost.cpp
gfx/layers/wr/WebRenderImageHost.h
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -656,17 +656,17 @@ mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvRemoveExternalImageId(const ExternalImageId& aImageId)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
   MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
   WebRenderImageHost* wrHost = mExternalImageIds.Get(wr::AsUint64(aImageId)).get();
   if (wrHost) {
-    wrHost->SetWrBridge(nullptr);
+    wrHost->ClearWrBridge();
   }
   mExternalImageIds.Remove(wr::AsUint64(aImageId));
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch)
@@ -870,17 +870,17 @@ WebRenderBridgeParent::ClearResources()
   // Schedule composition to clean up Pipeline
   mCompositorScheduler->ScheduleComposition();
   for (auto iter = mActiveKeys.Iter(); !iter.Done(); iter.Next()) {
     mKeysToDelete.push_back(iter.Data());
     iter.Remove();
   }
   DeleteOldImages();
   for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) {
-    iter.Data()->SetWrBridge(nullptr);
+    iter.Data()->ClearWrBridge();
   }
   mExternalImageIds.Clear();
   mCompositableHolder->RemovePipeline(mPipelineId, wr::NewEpoch(mWrEpoch));
 
   if (mWidget) {
     mCompositorScheduler->Destroy();
   }
   mCompositorScheduler = nullptr;
--- a/gfx/layers/wr/WebRenderImageHost.cpp
+++ b/gfx/layers/wr/WebRenderImageHost.cpp
@@ -23,16 +23,17 @@ using namespace gfx;
 namespace layers {
 
 class ISurfaceAllocator;
 
 WebRenderImageHost::WebRenderImageHost(const TextureInfo& aTextureInfo)
   : CompositableHost(aTextureInfo)
   , ImageComposite()
   , mWrBridge(nullptr)
+  , mWrBridgeBindings(0)
 {}
 
 WebRenderImageHost::~WebRenderImageHost()
 {
   MOZ_ASSERT(!mWrBridge);
 }
 
 void
@@ -274,14 +275,31 @@ WebRenderImageHost::GetImageSize() const
     return IntSize(img->mPictureRect.width, img->mPictureRect.height);
   }
   return IntSize();
 }
 
 void
 WebRenderImageHost::SetWrBridge(WebRenderBridgeParent* aWrBridge)
 {
-  SetCurrentTextureHost(nullptr);
+  // For image hosts created through ImageBridgeParent, there may be multiple
+  // references to it due to the order of creation and freeing of layers by
+  // the layer tree. However this should be limited to things such as video
+  // which will not be reused across different WebRenderBridgeParent objects.
+  MOZ_ASSERT(aWrBridge);
+  MOZ_ASSERT(!mWrBridge || mWrBridge == aWrBridge);
   mWrBridge = aWrBridge;
+  ++mWrBridgeBindings;
+}
+
+void
+WebRenderImageHost::ClearWrBridge()
+{
+  MOZ_ASSERT(mWrBridgeBindings > 0);
+  --mWrBridgeBindings;
+  if (mWrBridgeBindings == 0) {
+    SetCurrentTextureHost(nullptr);
+    mWrBridge = nullptr;
+  }
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderImageHost.h
+++ b/gfx/layers/wr/WebRenderImageHost.h
@@ -66,23 +66,27 @@ public:
   virtual void CleanupResources() override;
 
   virtual WebRenderImageHost* AsWebRenderImageHost() override { return this; }
 
   TextureHost* GetAsTextureHostForComposite();
 
   void SetWrBridge(WebRenderBridgeParent* aWrBridge);
 
+  void ClearWrBridge();
+
 protected:
   // ImageComposite
   virtual TimeStamp GetCompositionTime() const override;
 
   void SetCurrentTextureHost(TextureHost* aTexture);
 
   WebRenderBridgeParent* MOZ_NON_OWNING_REF mWrBridge;
 
+  uint32_t mWrBridgeBindings;
+
   CompositableTextureHostRef mCurrentTextureHost;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // MOZILLA_GFX_WEBRENDERIMAGEHOST_H