Bug 1506762 - Store wr::WebRenderPipelineInfo directly in AsyncImagePipelineManager::PipelineUpdates r=mattwoodrow
authorsotaro <sotaro.ikeda.g@gmail.com>
Fri, 16 Nov 2018 22:01:01 +0900
changeset 503204 ae143b5f65fb4a80538e765541de7f999c909233
parent 503203 98b78581ff763823e5eb20b0b559181e12bea5ea
child 503205 a43822d30dcf77d0734df7da40b39f882ab852a8
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1506762
milestone65.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 1506762 - Store wr::WebRenderPipelineInfo directly in AsyncImagePipelineManager::PipelineUpdates r=mattwoodrow
gfx/layers/wr/AsyncImagePipelineManager.cpp
gfx/layers/wr/AsyncImagePipelineManager.h
gfx/webrender_bindings/RenderThread.cpp
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -30,16 +30,24 @@ AsyncImagePipelineManager::ForwardingExt
 AsyncImagePipelineManager::AsyncImagePipeline::AsyncImagePipeline()
  : mInitialised(false)
  , mIsChanged(false)
  , mUseExternalImage(false)
  , mFilter(wr::ImageRendering::Auto)
  , mMixBlendMode(wr::MixBlendMode::Normal)
 {}
 
+AsyncImagePipelineManager::PipelineUpdates::PipelineUpdates(RefPtr<wr::WebRenderPipelineInfo> aPipelineInfo,
+                                                            const uint64_t aUpdatesCount,
+                                                            const bool aRendered)
+  : mPipelineInfo(aPipelineInfo)
+  , mUpdatesCount(aUpdatesCount)
+  , mRendered(aRendered)
+{}
+
 AsyncImagePipelineManager::AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi)
  : mApi(aApi)
  , mIdNamespace(mApi->GetNamespace())
  , mUseTripleBuffering(mApi->GetUseTripleBuffering())
  , mResourceId(0)
  , mAsyncImageEpoch{0}
  , mWillGenerateFrame(false)
  , mDestroyed(false)
@@ -548,36 +556,25 @@ AsyncImagePipelineManager::HoldExternalI
     return;
   }
 
   auto image = MakeUnique<ForwardingExternalImage>(aEpoch, aImageId);
   holder->mExternalImages.push(std::move(image));
 }
 
 void
-AsyncImagePipelineManager::NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInfo, bool aRender)
+AsyncImagePipelineManager::NotifyPipelinesUpdated(RefPtr<wr::WebRenderPipelineInfo> aInfo, bool aRender)
 {
   // This is called on the render thread, so we just stash the data into
   // UpdatesQueue and process it later on the compositor thread.
   MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
 
   // Increment the count when render happens.
   uint64_t currCount = aRender ? ++mUpdatesCount : mUpdatesCount;
-  auto updates = MakeUnique<PipelineUpdates>(currCount, aRender);
-
-  for (uintptr_t i = 0; i < aInfo.epochs.length; i++) {
-    updates->mQueue.emplace(std::make_pair(
-        aInfo.epochs.data[i].pipeline_id,
-        Some(aInfo.epochs.data[i].epoch)));
-  }
-  for (uintptr_t i = 0; i < aInfo.removed_pipelines.length; i++) {
-    updates->mQueue.emplace(std::make_pair(
-        aInfo.removed_pipelines.data[i],
-        Nothing()));
-  }
+  auto updates = MakeUnique<PipelineUpdates>(aInfo, currCount, aRender);
 
   {
     // Scope lock to push UpdatesQueue to mUpdatesQueues.
     MutexAutoLock lock(mUpdatesLock);
     mUpdatesQueues.push(std::move(updates));
   }
 
   if (!aRender) {
@@ -599,23 +596,17 @@ AsyncImagePipelineManager::ProcessPipeli
 
   if (mDestroyed) {
     return;
   }
 
   UniquePtr<PipelineUpdates> updates;
 
   while (true) {
-    // Clear updates if it is empty. It is a preparation for next PipelineUpdates handling.
-    if (updates && updates->mQueue.empty()) {
-      updates = nullptr;
-    }
-
-    // Get new PipelineUpdates if necessary.
-    if (!updates) {
+    {
       // Scope lock to extract UpdatesQueue from mUpdatesQueues.
       MutexAutoLock lock(mUpdatesLock);
       if (mUpdatesQueues.empty()) {
         // No more PipelineUpdates to process for now.
         break;
       }
       // Check if PipelineUpdates is ready to process.
       uint64_t currCount = mUpdatesCount;
@@ -623,29 +614,26 @@ AsyncImagePipelineManager::ProcessPipeli
         // PipelineUpdates is not ready for processing for now.
         break;
       }
       updates = std::move(mUpdatesQueues.front());
       mUpdatesQueues.pop();
     }
     MOZ_ASSERT(updates);
 
-    if (updates->mQueue.empty()) {
-      // Try next PipelineUpdates.
-      continue;
-    }
+    auto& info = updates->mPipelineInfo->Raw();
 
-    wr::PipelineId pipelineId = updates->mQueue.front().first;
-    Maybe<wr::Epoch> epoch = updates->mQueue.front().second;
-    updates->mQueue.pop();
-
-    if (epoch.isSome()) {
-      ProcessPipelineRendered(pipelineId, *epoch, updates->mUpdatesCount);
-    } else {
-      ProcessPipelineRemoved(pipelineId, updates->mUpdatesCount);
+    for (uintptr_t i = 0; i < info.epochs.length; i++) {
+      ProcessPipelineRendered(info.epochs.data[i].pipeline_id,
+                              info.epochs.data[i].epoch,
+                              updates->mUpdatesCount);
+    }
+    for (uintptr_t i = 0; i < info.removed_pipelines.length; i++) {
+      ProcessPipelineRemoved(info.removed_pipelines.data[i],
+                             updates->mUpdatesCount);
     }
   }
   CheckForTextureHostsNotUsedByGPU();
 }
 
 void
 AsyncImagePipelineManager::ProcessPipelineRendered(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, const uint64_t aUpdatesCount)
 {
--- a/gfx/layers/wr/AsyncImagePipelineManager.h
+++ b/gfx/layers/wr/AsyncImagePipelineManager.h
@@ -18,16 +18,17 @@
 #include "mozilla/webrender/WebRenderTypes.h"
 #include "nsClassHashtable.h"
 
 namespace mozilla {
 
 namespace wr {
 class DisplayListBuilder;
 class WebRenderAPI;
+class WebRenderPipelineInfo;
 }
 
 namespace layers {
 
 class CompositableHost;
 class CompositorVsyncScheduler;
 class WebRenderImageHost;
 class WebRenderTextureHost;
@@ -51,17 +52,17 @@ public:
 
   void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture);
   void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHostWrapper* aWrTextureWrapper);
   void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, const wr::ExternalImageId& aImageId);
 
   // This is called from the Renderer thread to notify this class about the
   // pipelines in the most recently completed render. A copy of the update
   // information is put into mUpdatesQueue.
-  void NotifyPipelinesUpdated(const wr::WrPipelineInfo& aInfo, bool aRender);
+  void NotifyPipelinesUpdated(RefPtr<wr::WebRenderPipelineInfo> aInfo, bool aRender);
 
   // This is run on the compositor thread to process mUpdatesQueue. We make
   // this a public entry point because we need to invoke it from other places.
   void ProcessPipelineUpdates();
 
   TimeStamp GetCompositionTime() const {
     return mCompositionTime;
   }
@@ -242,36 +243,30 @@ private:
 
   nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications;
 
   // The lock that protects mUpdatesQueue
   Mutex mUpdatesLock;
   // Used for checking if PipelineUpdates could be processed.
   Atomic<uint64_t> mUpdatesCount;
   struct PipelineUpdates {
-    PipelineUpdates(const uint64_t aUpdatesCount, const bool aRendered)
-      : mUpdatesCount(aUpdatesCount)
-      , mRendered(aRendered)
-    {}
+    PipelineUpdates(RefPtr<wr::WebRenderPipelineInfo> aPipelineInfo,
+                    const uint64_t aUpdatesCount,
+                    const bool aRendered);
     bool NeedsToWait(const uint64_t aUpdatesCount) {
       MOZ_ASSERT(mUpdatesCount <= aUpdatesCount);
       if (mUpdatesCount == aUpdatesCount && !mRendered) {
         // RenderTextureHosts related to this might be still used by GPU.
         return true;
       }
       return false;
     }
+    RefPtr<wr::WebRenderPipelineInfo> mPipelineInfo;
     const uint64_t mUpdatesCount;
     const bool mRendered;
-    // Queue to store rendered pipeline epoch information. This is populated from
-    // the Renderer thread after a render, and is read from the compositor thread
-    // to free resources (e.g. textures) that are no longer needed. Each entry
-    // in the queue is a pair that holds the pipeline id and Some(x) for
-    // a render of epoch x, or Nothing() for a removed pipeline.
-    std::queue<std::pair<wr::PipelineId, Maybe<wr::Epoch>>> mQueue;
   };
   std::queue<UniquePtr<PipelineUpdates>> mUpdatesQueues;
 
   // Queue to store TextureHosts that might still be used by GPU.
   std::queue<std::pair<uint64_t, CompositableTextureHostRef>> mTexturesInUseByGPU;
 };
 
 } // namespace layers
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -420,17 +420,17 @@ RenderThread::UpdateAndRender(wr::Window
   RefPtr<layers::AsyncImagePipelineManager> pipelineMgr =
       renderer->GetCompositorBridge()->GetAsyncImagePipelineManager();
   // pipelineMgr should always be non-null here because it is only nulled out
   // after the WebRenderAPI instance for the CompositorBridgeParent is
   // destroyed, and that destruction blocks until the renderer thread has
   // removed the relevant renderer. And after that happens we should never reach
   // this code at all; it would bail out at the mRenderers.find check above.
   MOZ_ASSERT(pipelineMgr);
-  pipelineMgr->NotifyPipelinesUpdated(info->Raw(), aRender);
+  pipelineMgr->NotifyPipelinesUpdated(info, aRender);
 }
 
 void
 RenderThread::Pause(wr::WindowId aWindowId)
 {
   MOZ_ASSERT(IsInRenderThread());
 
   auto it = mRenderers.find(aWindowId);