Bug 1366915 part 2 - Make CompositorBridgeChild allocate pipeline id for async image pipeline r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Tue, 30 May 2017 09:59:44 +0900
changeset 586532 392436e4adff730e3d8da332bcde199bd1151a7b
parent 586531 9fb4a2607ce1199d49f06ed6843b81138a60eb28
child 586533 5235f24cdc6bb4add5bfeeb8f7551aa355f3f9fb
push id61447
push userbmo:agaynor@mozilla.com
push dateTue, 30 May 2017 17:35:49 +0000
reviewersnical
bugs1366915
milestone55.0a1
Bug 1366915 part 2 - Make CompositorBridgeChild allocate pipeline id for async image pipeline r=nical
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/wr/WebRenderImageLayer.cpp
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -76,25 +76,27 @@ GPUProcessManager::Initialize()
 void
 GPUProcessManager::Shutdown()
 {
   sSingleton = nullptr;
 }
 
 GPUProcessManager::GPUProcessManager()
  : mTaskFactory(this),
-   mNextLayerTreeId(0),
    mNextNamespace(0),
+   mIdNamespace(0),
+   mResourceId(0),
    mNumProcessAttempts(0),
    mDeviceResetCount(0),
    mProcess(nullptr),
    mGPUChild(nullptr)
 {
   MOZ_COUNT_CTOR(GPUProcessManager);
 
+  mIdNamespace = AllocateNamespace();
   mObserver = new Observer(this);
   nsContentUtils::RegisterShutdownObserver(mObserver);
 
   mDeviceResetLastTime = TimeStamp::Now();
 
   LayerTreeOwnerTracker::Initialize();
 }
 
@@ -883,18 +885,30 @@ bool
 GPUProcessManager::IsLayerTreeIdMapped(uint64_t aLayersId, base::ProcessId aRequestingId)
 {
   return LayerTreeOwnerTracker::Get()->IsMapped(aLayersId, aRequestingId);
 }
 
 uint64_t
 GPUProcessManager::AllocateLayerTreeId()
 {
+  // Allocate tree id by using id namespace.
+  // By it, tree id does not conflict with external image id and
+  // async image pipeline id.
   MOZ_ASSERT(NS_IsMainThread());
-  return ++mNextLayerTreeId;
+  ++mResourceId;
+  if (mResourceId == UINT32_MAX) {
+    // Move to next id namespace.
+    mIdNamespace = AllocateNamespace();
+    mResourceId = 1;
+  }
+
+  uint64_t layerTreeId = mIdNamespace;
+  layerTreeId = (layerTreeId << 32) | mResourceId;
+  return layerTreeId;
 }
 
 uint32_t
 GPUProcessManager::AllocateNamespace()
 {
   MOZ_ASSERT(NS_IsMainThread());
   return ++mNextNamespace;
 }
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -239,18 +239,19 @@ private:
   friend class Observer;
 
 private:
   bool mDecodeVideoOnGpuProcess = true;
 
   RefPtr<Observer> mObserver;
   ipc::TaskFactory<GPUProcessManager> mTaskFactory;
   RefPtr<VsyncIOThreadHolder> mVsyncIOThread;
-  uint64_t mNextLayerTreeId;
   uint32_t mNextNamespace;
+  uint32_t mIdNamespace;
+  uint32_t mResourceId;
   uint32_t mNumProcessAttempts;
 
   nsTArray<RefPtr<RemoteCompositorSession>> mRemoteSessions;
   nsTArray<GPUProcessListener*> mListeners;
 
   uint32_t mDeviceResetCount;
   TimeStamp mDeviceResetLastTime;
 
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -74,24 +74,25 @@ static void ShmemAllocated(CompositorBri
 }
 
 static StaticRefPtr<CompositorBridgeChild> sCompositorBridge;
 
 Atomic<int32_t> KnowsCompositor::sSerialCounter(0);
 
 CompositorBridgeChild::CompositorBridgeChild(LayerManager *aLayerManager, uint32_t aNamespace)
   : mLayerManager(aLayerManager)
-  , mNamespace(aNamespace)
+  , mIdNamespace(aNamespace)
+  , mResourceId(0)
   , mCanSend(false)
   , mFwdTransactionId(0)
   , mDeviceResetSequenceNumber(0)
   , mMessageLoop(MessageLoop::current())
   , mSectionAllocator(nullptr)
 {
-  MOZ_ASSERT(mNamespace);
+  MOZ_ASSERT(mIdNamespace);
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 CompositorBridgeChild::~CompositorBridgeChild()
 {
   if (mCanSend) {
     gfxCriticalError() << "CompositorBridgeChild was not deinitialized";
   }
@@ -1164,23 +1165,35 @@ CompositorBridgeChild::AllocPWebRenderBr
 bool
 CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor)
 {
   WebRenderBridgeChild* child = static_cast<WebRenderBridgeChild*>(aActor);
   child->ReleaseIPDLReference();
   return true;
 }
 
+uint64_t
+CompositorBridgeChild::GetNextResourceId()
+{
+  ++mResourceId;
+  MOZ_RELEASE_ASSERT(mResourceId != UINT32_MAX);
+
+  uint64_t id = mIdNamespace;
+  id = (id << 32) | mResourceId;
+
+  return id;
+}
+
 wr::MaybeExternalImageId
 CompositorBridgeChild::GetNextExternalImageId()
 {
-  static uint32_t sNextID = 1;
-  ++sNextID;
-  MOZ_RELEASE_ASSERT(sNextID != UINT32_MAX);
+  return Some(wr::ToExternalImageId(GetNextResourceId()));
+}
 
-  uint64_t imageId = mNamespace;
-  imageId = (imageId << 32) | sNextID;
-  return Some(wr::ToExternalImageId(imageId));
+wr::PipelineId
+CompositorBridgeChild::GetNextPipelineId()
+{
+  return wr::AsPipelineId(GetNextResourceId());
 }
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -230,16 +230,18 @@ public:
   bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override;
 
   uint64_t DeviceResetSequenceNumber() const {
     return mDeviceResetSequenceNumber;
   }
 
   wr::MaybeExternalImageId GetNextExternalImageId() override;
 
+  wr::PipelineId GetNextPipelineId();
+
 private:
   // Private destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeChild();
 
   void InitIPDL();
   void DeallocPCompositorBridgeChild() override;
 
   virtual PLayerTransactionChild*
@@ -263,16 +265,18 @@ private:
 
   mozilla::ipc::IPCResult RecvObserveLayerUpdate(const uint64_t& aLayersId,
                                                  const uint64_t& aEpoch,
                                                  const bool& aActive) override;
 
   already_AddRefed<nsIEventTarget>
   GetSpecificMessageEventTarget(const Message& aMsg) override;
 
+  uint64_t GetNextResourceId();
+
   // Class used to store the shared FrameMetrics, mutex, and APZCId  in a hash table
   class SharedFrameMetricsData {
   public:
     SharedFrameMetricsData(
         const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
         const CrossProcessMutexHandle& handle,
         const uint64_t& aLayersId,
         const uint32_t& aAPZCId);
@@ -291,17 +295,18 @@ private:
     CrossProcessMutex* mMutex;
     uint64_t mLayersId;
     // Unique ID of the APZC that is sharing the FrameMetrics
     uint32_t mAPZCId;
   };
 
   RefPtr<LayerManager> mLayerManager;
 
-  uint32_t mNamespace;
+  uint32_t mIdNamespace;
+  uint32_t mResourceId;
 
   // When not multi-process, hold a reference to the CompositorBridgeParent to keep it
   // alive. This reference should be null in multi-process.
   RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
 
   // The ViewID of the FrameMetrics is used as the key for this hash table.
   // While this should be safe to use since the ViewID is unique
   nsClassHashtable<nsUint64HashKey, SharedFrameMetricsData> mFrameMetricsTable;
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebRenderImageLayer.h"
 
 #include "gfxPrefs.h"
 #include "LayersLogging.h"
 #include "mozilla/gfx/gfxVars.h"
+#include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/ImageClient.h"
 #include "mozilla/layers/ScrollingLayersHelper.h"
 #include "mozilla/layers/StackingContextHelper.h"
 #include "mozilla/layers/TextureClientRecycleAllocator.h"
 #include "mozilla/layers/TextureWrapperImage.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 
@@ -124,16 +125,18 @@ WebRenderImageLayer::RenderLayer(wr::Dis
     }
     mImageClient->Connect();
   }
 
   if (mExternalImageId.isNothing()) {
     if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
       MOZ_ASSERT(!mImageClient);
       mExternalImageId = Some(WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle()));
+      // Alloc async image pipeline id.
+      mPipelineId = Some(WrBridge()->GetCompositorBridgeChild()->GetNextPipelineId());
     } else {
       // Handle CompositableType::IMAGE case
       MOZ_ASSERT(mImageClient);
       mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
     }
   }
   MOZ_ASSERT(mExternalImageId.isSome());