Bug 1347811 - Share WebRenderCompositableHolder between WebRenderBridgeParent r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Wed, 22 Mar 2017 10:27:38 +0900
changeset 399655 858c37bb49f5ee2a195fbd911f8a9323b3e365e2
parent 399654 441ae3d3a5e8e5bbb05f9ca1e1fd7859e5e8b569
child 399656 303e3c18824a61fbefe21803470cf26e7199ba49
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1347811
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 1347811 - Share WebRenderCompositableHolder between WebRenderBridgeParent r=nical
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderCompositableHolder.cpp
gfx/layers/wr/WebRenderCompositableHolder.h
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1834,16 +1834,18 @@ CompositorBridgeParent::DidComposite(Tim
 void
 CompositorBridgeParent::NotifyDidCompositeToPipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd)
 {
   if (mPaused) {
     return;
   }
   MOZ_ASSERT(mWrBridge);
 
+  mWrBridge->CompositableHolder()->Update(aPipelineId, aEpoch);
+
   if (mWrBridge->PipelineId() == aPipelineId) {
     uint64_t transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch);
     Unused << SendDidComposite(0, transactionId, aCompositeStart, aCompositeEnd);
 
     nsTArray<ImageCompositeNotificationInfo> notifications;
     mWrBridge->ExtractImageCompositeNotifications(&notifications);
     if (!notifications.IsEmpty()) {
       Unused << ImageBridgeParent::NotifyImageComposites(notifications);
--- a/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CrossProcessCompositorBridgeParent.cpp
@@ -218,17 +218,17 @@ CrossProcessCompositorBridgeParent::Allo
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
   MOZ_ASSERT(sIndirectLayerTrees.find(pipelineHandle) != sIndirectLayerTrees.end());
   MOZ_ASSERT(sIndirectLayerTrees[pipelineHandle].mWrBridge == nullptr);
   CompositorBridgeParent* cbp = sIndirectLayerTrees[pipelineHandle].mParent;
   WebRenderBridgeParent* root = sIndirectLayerTrees[cbp->RootLayerTreeId()].mWrBridge.get();
 
   WebRenderBridgeParent* parent = nullptr;
   RefPtr<wr::WebRenderAPI> api = root->GetWebRenderAPI();
-  RefPtr<WebRenderCompositableHolder> holder = new WebRenderCompositableHolder();
+  RefPtr<WebRenderCompositableHolder> holder = root->CompositableHolder();
   parent = new WebRenderBridgeParent(this, aPipelineId, nullptr, root->CompositorScheduler(), Move(api), Move(holder));
 
   parent->AddRef(); // IPDL reference
   sIndirectLayerTrees[pipelineHandle].mCrossProcessParent = this;
   sIndirectLayerTrees[pipelineHandle].mWrBridge = parent;
   *aTextureFactoryIdentifier = parent->GetTextureFactoryIdentifier();
   *aIdNamespace = parent->GetIdNameSpace();
 
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -108,16 +108,17 @@ WebRenderBridgeParent::WebRenderBridgePa
   , mCompositorScheduler(aScheduler)
   , mChildLayerObserverEpoch(0)
   , mParentLayerObserverEpoch(0)
   , mWrEpoch(0)
   , mIdNameSpace(++sIdNameSpace)
   , mDestroyed(false)
 {
   MOZ_ASSERT(mCompositableHolder);
+  mCompositableHolder->AddPipeline(mPipelineId);
   if (mWidget) {
     MOZ_ASSERT(!mCompositorScheduler);
     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
   }
 }
 
 
 mozilla::ipc::IPCResult
@@ -322,17 +323,17 @@ WebRenderBridgeParent::ProcessWebRenderC
         if (wrTexture) {
           // XXX handling YUV
           gfx::SurfaceFormat format =
             wrTexture->GetFormat() == SurfaceFormat::YUV ? SurfaceFormat::B8G8R8A8 : wrTexture->GetFormat();
           wr::ImageDescriptor descriptor(wrTexture->GetSize(), wrTexture->GetRGBStride(), format);
           mApi->AddExternalImageBuffer(key,
                                        descriptor,
                                        wrTexture->GetExternalImageKey());
-          mCompositableHolder->HoldExternalImage(aEpoch, texture->AsWebRenderTextureHost());
+          mCompositableHolder->HoldExternalImage(mPipelineId, aEpoch, texture->AsWebRenderTextureHost());
           keysToDelete.push_back(key);
           break;
         }
         RefPtr<DataSourceSurface> dSurf = host->GetAsSurface();
         if (!dSurf) {
           break;
         }
 
@@ -565,19 +566,16 @@ WebRenderBridgeParent::FlushTransactionI
   while (!mPendingTransactionIds.empty()) {
     id = mPendingTransactionIds.front().mId;
     if (mPendingTransactionIds.front().mEpoch == aEpoch) {
       mPendingTransactionIds.pop();
       break;
     }
     mPendingTransactionIds.pop();
   }
-
-  mCompositableHolder->Update(aEpoch);
-
   return id;
 }
 
 WebRenderBridgeParent::~WebRenderBridgeParent()
 {
 }
 
 void
@@ -604,19 +602,17 @@ WebRenderBridgeParent::ClearResources()
     ++mWrEpoch; // Update webrender epoch
     mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId);
     if (!mKeysToDelete.empty()) {
       // XXX Sync wait.
       mApi->WaitFlushed();
       DeleteOldImages();
     }
   }
-  if (mCompositableHolder) {
-    mCompositableHolder->Destroy();
-  }
+  mCompositableHolder->RemovePipeline(mPipelineId);
   mExternalImageIds.Clear();
 
   if (mWidget && mCompositorScheduler) {
     mCompositorScheduler->Destroy();
   }
   mCompositorScheduler = nullptr;
   mApi = nullptr;
   mCompositorBridge = nullptr;
--- a/gfx/layers/wr/WebRenderCompositableHolder.cpp
+++ b/gfx/layers/wr/WebRenderCompositableHolder.cpp
@@ -18,43 +18,61 @@ namespace layers {
 WebRenderCompositableHolder::WebRenderCompositableHolder()
 {
   MOZ_COUNT_CTOR(WebRenderCompositableHolder);
 }
 
 WebRenderCompositableHolder::~WebRenderCompositableHolder()
 {
   MOZ_COUNT_DTOR(WebRenderCompositableHolder);
-  MOZ_ASSERT(mWebRenderTextureHosts.empty());
+  MOZ_ASSERT(mPipelineTexturesHolders.IsEmpty());
 }
 
 void
-WebRenderCompositableHolder::Destroy()
+WebRenderCompositableHolder::AddPipeline(const wr::PipelineId& aPipelineId)
 {
-  while (!mWebRenderTextureHosts.empty()) {
-    mWebRenderTextureHosts.pop();
+  uint64_t id = wr::AsUint64(aPipelineId);
+
+  MOZ_ASSERT(!mPipelineTexturesHolders.Get(id));
+  PipelineTexturesHolder* holder = new PipelineTexturesHolder();
+  mPipelineTexturesHolders.Put(id, holder);
+}
+
+void
+WebRenderCompositableHolder::RemovePipeline(const wr::PipelineId& aPipelineId)
+{
+  uint64_t id = wr::AsUint64(aPipelineId);
+  if (mPipelineTexturesHolders.Get(id)) {
+    mPipelineTexturesHolders.Remove(id);
   }
 }
 
 void
-WebRenderCompositableHolder::HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
+WebRenderCompositableHolder::HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture)
 {
   MOZ_ASSERT(aTexture);
+  PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId));
+  MOZ_ASSERT(holder);
+  if (!holder) {
+    return;
+  }
   // Hold WebRenderTextureHost until end of its usage on RenderThread
-  mWebRenderTextureHosts.push(ForwardingTextureHosts(aEpoch, aTexture));
+  holder->mTextureHosts.push(ForwardingTextureHost(aEpoch, aTexture));
 }
 
 void
-WebRenderCompositableHolder::Update(const wr::Epoch& aEpoch)
+WebRenderCompositableHolder::Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch)
 {
-  if (mWebRenderTextureHosts.empty()) {
+  PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId));
+  if (!holder || holder->mTextureHosts.empty()) {
     return;
   }
-  while (!mWebRenderTextureHosts.empty()) {
-    if (aEpoch <= mWebRenderTextureHosts.front().mEpoch) {
+
+  while (!holder->mTextureHosts.empty()) {
+    if (aEpoch <= holder->mTextureHosts.front().mEpoch) {
       break;
     }
-    mWebRenderTextureHosts.pop();
+    holder->mTextureHosts.pop();
   }
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderCompositableHolder.h
+++ b/gfx/layers/wr/WebRenderCompositableHolder.h
@@ -28,31 +28,36 @@ public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderCompositableHolder)
 
   explicit WebRenderCompositableHolder();
 
 protected:
   ~WebRenderCompositableHolder();
 
 public:
-  void Destroy();
-  void HoldExternalImage(const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
-  void Update(const wr::Epoch& aEpoch);
+  void AddPipeline(const wr::PipelineId& aPipelineId);
+  void RemovePipeline(const wr::PipelineId& aPipelineId);
+  void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
+  void Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch);
 
 private:
 
-  struct ForwardingTextureHosts {
-    ForwardingTextureHosts(const wr::Epoch& aEpoch, TextureHost* aTexture)
+  struct ForwardingTextureHost {
+    ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
       : mEpoch(aEpoch)
       , mTexture(aTexture)
     {}
     wr::Epoch mEpoch;
     CompositableTextureHostRef mTexture;
   };
 
-  // Holds forwarding WebRenderTextureHosts.
-  std::queue<ForwardingTextureHosts> mWebRenderTextureHosts;
+  struct PipelineTexturesHolder {
+    // Holds forwarding WebRenderTextureHosts.
+    std::queue<ForwardingTextureHost> mTextureHosts;
+  };
+
+  nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */