Replace async image container IDs with a typed struct. (bug 1323957 part 1, r=mattwoodrow)
authorDavid Anderson <dvander@alliedmods.net>
Tue, 17 Jan 2017 18:47:05 -0800
changeset 374769 8205e8a9e7a33ed521fa5e0b2e947ca89448ff52
parent 374768 b54f9eb0ba7d7dba88b061ba063b5914633a2434
child 374770 b930d01d6aee9f296e875f024c56ba09579f738d
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1323957
milestone53.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
Replace async image container IDs with a typed struct. (bug 1323957 part 1, r=mattwoodrow)
dom/plugins/ipc/PluginInstanceParent.cpp
gfx/layers/AsyncCanvasRenderer.cpp
gfx/layers/AsyncCanvasRenderer.h
gfx/layers/ImageContainer.cpp
gfx/layers/ImageContainer.h
gfx/layers/LayersTypes.h
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/client/CompositableClient.cpp
gfx/layers/client/CompositableClient.h
gfx/layers/client/ImageClient.cpp
gfx/layers/client/ImageClient.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
gfx/layers/ipc/SharedRGBImage.cpp
widget/nsBaseWidget.cpp
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1201,17 +1201,17 @@ PluginInstanceParent::EndUpdateBackgroun
 #if defined(XP_WIN)
 nsresult
 PluginInstanceParent::SetScrollCaptureId(uint64_t aScrollCaptureId)
 {
   if (aScrollCaptureId == ImageContainer::sInvalidAsyncContainerId) {
     return NS_ERROR_FAILURE;
   }
 
-  mImageContainer = new ImageContainer(aScrollCaptureId);
+  mImageContainer = new ImageContainer(CompositableHandle(aScrollCaptureId));
   return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::GetScrollCaptureContainer(ImageContainer** aContainer)
 {
   if (!aContainer || !mImageContainer) {
     return NS_ERROR_FAILURE;
--- a/gfx/layers/AsyncCanvasRenderer.cpp
+++ b/gfx/layers/AsyncCanvasRenderer.cpp
@@ -24,17 +24,16 @@ namespace layers {
 
 AsyncCanvasRenderer::AsyncCanvasRenderer()
   : mHTMLCanvasElement(nullptr)
   , mContext(nullptr)
   , mGLContext(nullptr)
   , mIsAlphaPremultiplied(true)
   , mWidth(0)
   , mHeight(0)
-  , mCanvasClientAsyncID(0)
   , mCanvasClient(nullptr)
   , mMutex("AsyncCanvasRenderer::mMutex")
 {
   MOZ_COUNT_CTOR(AsyncCanvasRenderer);
 }
 
 AsyncCanvasRenderer::~AsyncCanvasRenderer()
 {
@@ -111,19 +110,19 @@ AsyncCanvasRenderer::NotifyElementAboutI
   }
 }
 
 void
 AsyncCanvasRenderer::SetCanvasClient(CanvasClient* aClient)
 {
   mCanvasClient = aClient;
   if (aClient) {
-    mCanvasClientAsyncID = aClient->GetAsyncID();
+    mCanvasClientAsyncHandle = aClient->GetAsyncHandle();
   } else {
-    mCanvasClientAsyncID = 0;
+    mCanvasClientAsyncHandle = CompositableHandle();
   }
 }
 
 void
 AsyncCanvasRenderer::SetActiveThread()
 {
   MutexAutoLock lock(mMutex);
   mActiveThread = NS_GetCurrentThread();
--- a/gfx/layers/AsyncCanvasRenderer.h
+++ b/gfx/layers/AsyncCanvasRenderer.h
@@ -101,19 +101,19 @@ public:
                  const char16_t *aEncoderOptions,
                  nsIInputStream **aStream);
 
   gfx::IntSize GetSize() const
   {
     return gfx::IntSize(mWidth, mHeight);
   }
 
-  uint64_t GetCanvasClientAsyncID() const
+  CompositableHandle GetCanvasClientAsyncHandle() const
   {
-    return mCanvasClientAsyncID;
+    return mCanvasClientAsyncHandle;
   }
 
   CanvasClient* GetCanvasClient() const
   {
     return mCanvasClient;
   }
 
   already_AddRefed<nsIThread> GetActiveThread();
@@ -135,17 +135,17 @@ private:
 
   // Readback current WebGL's content and return it as DataSourceSurface.
   already_AddRefed<gfx::DataSourceSurface> UpdateTarget();
 
   bool mIsAlphaPremultiplied;
 
   uint32_t mWidth;
   uint32_t mHeight;
-  uint64_t mCanvasClientAsyncID;
+  CompositableHandle mCanvasClientAsyncHandle;
 
   // The lifetime of this pointer is controlled by OffscreenCanvas
   // Can be accessed in active thread and ImageBridge thread.
   // But we never accessed it at the same time on both thread. So no
   // need to protect this member.
   CanvasClient* mCanvasClient;
 
   // When backend is LAYER_BASIC and SharedSurface type is Basic.
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -131,59 +131,57 @@ ImageContainer::EnsureImageClient(bool a
   if (!aCreate && (!mImageClient || mImageClient->GetForwarder()->GetLayersIPCActor()->IPCOpen())) {
     return;
   }
 
   RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton();
   if (imageBridge) {
     mImageClient = imageBridge->CreateImageClient(CompositableType::IMAGE, this);
     if (mImageClient) {
-      mAsyncContainerID = mImageClient->GetAsyncID();
+      mAsyncContainerHandle = mImageClient->GetAsyncHandle();
       mNotifyCompositeListener = new ImageContainerListener(this);
     }
   }
 }
 
 ImageContainer::ImageContainer(Mode flag)
 : mReentrantMonitor("ImageContainer.mReentrantMonitor"),
   mGenerationCounter(++sGenerationCounter),
   mPaintCount(0),
   mDroppedImageCount(0),
   mImageFactory(new ImageFactory()),
   mRecycleBin(new BufferRecycleBin()),
   mCurrentProducerID(-1)
 {
   if (flag == ASYNCHRONOUS) {
     EnsureImageClient(true);
-  } else {
-    mAsyncContainerID = sInvalidAsyncContainerId;
   }
 }
 
-ImageContainer::ImageContainer(uint64_t aAsyncContainerID)
+ImageContainer::ImageContainer(const CompositableHandle& aHandle)
   : mReentrantMonitor("ImageContainer.mReentrantMonitor"),
   mGenerationCounter(++sGenerationCounter),
   mPaintCount(0),
   mDroppedImageCount(0),
   mImageFactory(nullptr),
   mRecycleBin(nullptr),
-  mAsyncContainerID(aAsyncContainerID),
+  mAsyncContainerHandle(aHandle),
   mCurrentProducerID(-1)
 {
-  MOZ_ASSERT(mAsyncContainerID != sInvalidAsyncContainerId);
+  MOZ_ASSERT(mAsyncContainerHandle);
 }
 
 ImageContainer::~ImageContainer()
 {
   if (mNotifyCompositeListener) {
     mNotifyCompositeListener->ClearImageContainer();
   }
-  if (mAsyncContainerID) {
+  if (mAsyncContainerHandle) {
     if (RefPtr<ImageBridgeChild> imageBridge = ImageBridgeChild::GetSingleton()) {
-      imageBridge->ForgetImageContainer(mAsyncContainerID);
+      imageBridge->ForgetImageContainer(mAsyncContainerHandle);
     }
   }
 }
 
 RefPtr<PlanarYCbCrImage>
 ImageContainer::CreatePlanarYCbCrImage()
 {
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
@@ -339,24 +337,24 @@ ImageContainer::SetCurrentImagesInTransa
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   NS_ASSERTION(!mImageClient, "Should use async image transfer with ImageBridge.");
 
   SetCurrentImageInternal(aImages);
 }
 
 bool ImageContainer::IsAsync() const
 {
-  return mAsyncContainerID != sInvalidAsyncContainerId;
+  return !!mAsyncContainerHandle;
 }
 
-uint64_t ImageContainer::GetAsyncContainerID()
+CompositableHandle ImageContainer::GetAsyncContainerHandle()
 {
   NS_ASSERTION(IsAsync(),"Shared image ID is only relevant to async ImageContainers");
   EnsureImageClient(false);
-  return mAsyncContainerID;
+  return mAsyncContainerHandle;
 }
 
 bool
 ImageContainer::HasCurrentImage()
 {
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   return !mCurrentImages.IsEmpty();
--- a/gfx/layers/ImageContainer.h
+++ b/gfx/layers/ImageContainer.h
@@ -380,17 +380,17 @@ public:
 
   explicit ImageContainer(ImageContainer::Mode flag = SYNCHRONOUS);
 
   /**
    * Create ImageContainer just to hold another ASYNCHRONOUS ImageContainer's
    * async container ID.
    * @param aAsyncContainerID async container ID for which we are a proxy
    */
-  explicit ImageContainer(uint64_t aAsyncContainerID);
+  explicit ImageContainer(const CompositableHandle& aHandle);
 
   typedef uint32_t FrameID;
   typedef uint32_t ProducerID;
 
   RefPtr<PlanarYCbCrImage> CreatePlanarYCbCrImage();
 
   // Factory methods for shared image types.
   RefPtr<SharedRGBImage> CreateSharedRGBImage();
@@ -481,17 +481,17 @@ public:
   /**
    * If this ImageContainer uses ImageBridge, returns the ID associated to
    * this container, for use in the ImageBridge protocol.
    * Returns 0 if this ImageContainer does not use ImageBridge. Note that
    * 0 is always an invalid ID for asynchronous image containers.
    *
    * Can be called from any thread.
    */
-  uint64_t GetAsyncContainerID();
+  CompositableHandle GetAsyncContainerHandle();
 
   /**
    * Returns if the container currently has an image.
    * Can be called on any thread. This method takes mReentrantMonitor
    * when accessing thread-shared state.
    */
   bool HasCurrentImage();
 
@@ -644,17 +644,17 @@ private:
   // sucessfully created with ENABLE_ASYNC, or points to null otherwise.
   // 'unsuccessful' in this case only means that the ImageClient could not
   // be created, most likely because off-main-thread compositing is not enabled.
   // In this case the ImageContainer is perfectly usable, but it will forward
   // frames to the compositor through transactions in the main thread rather than
   // asynchronusly using the ImageBridge IPDL protocol.
   RefPtr<ImageClient> mImageClient;
 
-  uint64_t mAsyncContainerID;
+  CompositableHandle mAsyncContainerHandle;
 
   nsTArray<FrameID> mFrameIDsNotYetComposited;
   // ProducerID for last current image(s), including the frames in
   // mFrameIDsNotYetComposited
   ProducerID mCurrentProducerID;
 
   RefPtr<ImageContainerListener> mNotifyCompositeListener;
 
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -274,12 +274,42 @@ public:
   }
   uint64_t Value() const {
     return mHandle;
   }
 private:
   uint64_t mHandle;
 };
 
+// This is used to communicate Compositables across IPC channels. The Handle is valid
+// for layers in the same PLayerTransaction or PImageBridge. Handles are created by
+// ClientLayerManager or ImageBridgeChild, and are cached in the parent side on first
+// use.
+class CompositableHandle
+{
+  friend struct IPC::ParamTraits<mozilla::layers::CompositableHandle>;
+public:
+  CompositableHandle() : mHandle(0)
+  {}
+  CompositableHandle(const CompositableHandle& aOther) : mHandle(aOther.mHandle)
+  {}
+  explicit CompositableHandle(uint64_t aHandle) : mHandle(aHandle)
+  {}
+  bool IsValid() const {
+    return mHandle != 0;
+  }
+  explicit operator bool() const {
+    return IsValid();
+  }
+  bool operator ==(const CompositableHandle& aOther) const {
+    return mHandle == aOther.mHandle;
+  }
+  uint64_t Value() const {
+    return mHandle;
+  }
+private:
+  uint64_t mHandle;
+};
+
 } // namespace layers
 } // namespace mozilla
 
 #endif /* GFX_LAYERSTYPES_H */
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -50,24 +50,24 @@ CanvasClient::CreateCanvasClient(CanvasC
 void
 CanvasClientBridge::UpdateAsync(AsyncCanvasRenderer* aRenderer)
 {
   if (!GetForwarder() || !mLayer || !aRenderer ||
       !aRenderer->GetCanvasClient()) {
     return;
   }
 
-  uint64_t asyncID = aRenderer->GetCanvasClientAsyncID();
-  if (asyncID == 0 || mAsyncID == asyncID) {
+  CompositableHandle asyncID = aRenderer->GetCanvasClientAsyncHandle();
+  if (!asyncID || mAsyncHandle == asyncID) {
     return;
   }
 
   static_cast<ShadowLayerForwarder*>(GetForwarder())
     ->AttachAsyncCompositable(asyncID, mLayer);
-  mAsyncID = asyncID;
+  mAsyncHandle = asyncID;
 }
 
 void
 CanvasClient2D::UpdateFromTexture(TextureClient* aTexture)
 {
   MOZ_ASSERT(aTexture);
 
   if (!aTexture->IsSharedWithCompositor()) {
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -179,17 +179,16 @@ public:
  * only forward its AsyncID here
  */
 class CanvasClientBridge final : public CanvasClient
 {
 public:
   CanvasClientBridge(CompositableForwarder* aLayerForwarder,
                      TextureFlags aFlags)
     : CanvasClient(aLayerForwarder, aFlags)
-    , mAsyncID(0)
     , mLayer(nullptr)
   {
   }
 
   TextureInfo GetTextureInfo() const override
   {
     return TextureInfo(CompositableType::IMAGE);
   }
@@ -201,16 +200,16 @@ public:
   virtual void UpdateAsync(AsyncCanvasRenderer* aRenderer) override;
 
   void SetLayer(ShadowableLayer* aLayer)
   {
     mLayer = aLayer;
   }
 
 protected:
-  uint64_t mAsyncID;
+  CompositableHandle mAsyncHandle;
   ShadowableLayer* mLayer;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -23,23 +23,23 @@
 #include "IPDLActor.h"
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
-CompositableClient::InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID)
+CompositableClient::InitIPDLActor(PCompositableChild* aActor, const CompositableHandle& aAsyncHandle)
 {
   MOZ_ASSERT(aActor);
 
   mForwarder->AssertInForwarderThread();
 
-  mAsyncID = aAsyncID;
+  mAsyncHandle = aAsyncHandle;
   mCompositableChild = static_cast<CompositableChild*>(aActor);
   mCompositableChild->Init(this);
 }
 
 /* static */ RefPtr<CompositableClient>
 CompositableClient::FromIPDLActor(PCompositableChild* aActor)
 {
   MOZ_ASSERT(aActor);
@@ -52,17 +52,16 @@ CompositableClient::FromIPDLActor(PCompo
   client->mForwarder->AssertInForwarderThread();
   return client;
 }
 
 CompositableClient::CompositableClient(CompositableForwarder* aForwarder,
                                        TextureFlags aTextureFlags)
 : mForwarder(aForwarder)
 , mTextureFlags(aTextureFlags)
-, mAsyncID(0)
 {
 }
 
 CompositableClient::~CompositableClient()
 {
   Destroy();
 }
 
@@ -113,23 +112,23 @@ CompositableClient::Destroy()
   // Take away our IPDL's actor reference back to us.
   mCompositableChild->RevokeCompositableClient();
 
   // Schedule the IPDL actor to be destroyed on the forwarder's thread.
   mForwarder->Destroy(mCompositableChild);
   mCompositableChild = nullptr;
 }
 
-uint64_t
-CompositableClient::GetAsyncID() const
+CompositableHandle
+CompositableClient::GetAsyncHandle() const
 {
   if (mCompositableChild) {
-    return mAsyncID;
+    return mAsyncHandle;
   }
-  return 0; // zero is always an invalid async ID
+  return CompositableHandle();
 }
 
 already_AddRefed<TextureClient>
 CompositableClient::CreateBufferTextureClient(gfx::SurfaceFormat aFormat,
                                               gfx::IntSize aSize,
                                               gfx::BackendType aMoz2DBackend,
                                               TextureFlags aTextureFlags)
 {
--- a/gfx/layers/client/CompositableClient.h
+++ b/gfx/layers/client/CompositableClient.h
@@ -120,20 +120,20 @@ public:
     return mForwarder;
   }
 
   /**
    * This identifier is what lets us attach async compositables with a shadow
    * layer. It is not used if the compositable is used with the regular shadow
    * layer forwarder.
    *
-   * If this returns zero, it means the compositable is not async (it is used
+   * If this returns empty, it means the compositable is not async (it is used
    * on the main thread).
    */
-  uint64_t GetAsyncID() const;
+  CompositableHandle GetAsyncHandle() const;
 
   /**
    * Tells the Compositor to create a TextureHost for this TextureClient.
    */
   virtual bool AddTextureClient(TextureClient* aClient);
 
   /**
    * A hook for the when the Compositable is detached from it's layer.
@@ -157,17 +157,17 @@ public:
    * some platforms need to do some extra book keeping when this happens.
    *
    * See AutoRemoveTexture to automatically invoke this at the end of a scope.
    */
   virtual void RemoveTexture(TextureClient* aTexture);
 
   static RefPtr<CompositableClient> FromIPDLActor(PCompositableChild* aActor);
 
-  void InitIPDLActor(PCompositableChild* aActor, uint64_t aAsyncID = 0);
+  void InitIPDLActor(PCompositableChild* aActor, const CompositableHandle& aHandle);
 
   TextureFlags GetTextureFlags() const { return mTextureFlags; }
 
   TextureClientRecycleAllocator* GetTextureClientRecycler();
 
   bool HasTextureClientRecycler() { return !!mTextureClientRecycler; }
 
   static void DumpTextureClient(std::stringstream& aStream,
@@ -176,17 +176,18 @@ public:
 protected:
   RefPtr<CompositableChild> mCompositableChild;
   RefPtr<CompositableForwarder> mForwarder;
   // Some layers may want to enforce some flags to all their textures
   // (like disallowing tiling)
   TextureFlags mTextureFlags;
   RefPtr<TextureClientRecycleAllocator> mTextureClientRecycler;
 
-  uint64_t mAsyncID;
+  // Handle for IPDL operations.
+  CompositableHandle mAsyncHandle;
 
   friend class CompositableChild;
 };
 
 /**
  * Helper to call RemoveTexture at the end of a scope.
  */
 struct AutoRemoveTexture
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -273,28 +273,27 @@ ImageClient::ImageClient(CompositableFor
 , mLayer(nullptr)
 , mType(aType)
 , mLastUpdateGenerationCounter(0)
 {}
 
 ImageClientBridge::ImageClientBridge(CompositableForwarder* aFwd,
                                      TextureFlags aFlags)
 : ImageClient(aFwd, aFlags, CompositableType::IMAGE_BRIDGE)
-, mAsyncContainerID(0)
 {
 }
 
 bool
 ImageClientBridge::UpdateImage(ImageContainer* aContainer, uint32_t aContentFlags)
 {
   if (!GetForwarder() || !mLayer) {
     return false;
   }
-  if (mAsyncContainerID == aContainer->GetAsyncContainerID()) {
+  if (mAsyncContainerHandle == aContainer->GetAsyncContainerHandle()) {
     return true;
   }
-  mAsyncContainerID = aContainer->GetAsyncContainerID();
-  static_cast<ShadowLayerForwarder*>(GetForwarder())->AttachAsyncCompositable(mAsyncContainerID, mLayer);
+  mAsyncContainerHandle = aContainer->GetAsyncContainerHandle();
+  static_cast<ShadowLayerForwarder*>(GetForwarder())->AttachAsyncCompositable(mAsyncContainerHandle, mLayer);
   return true;
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/ImageClient.h
+++ b/gfx/layers/client/ImageClient.h
@@ -124,15 +124,15 @@ public:
   virtual bool Connect(ImageContainer* aImageContainer) override { return false; }
 
   virtual TextureInfo GetTextureInfo() const override
   {
     return TextureInfo(mType);
   }
 
 protected:
-  uint64_t mAsyncContainerID;
+  CompositableHandle mAsyncContainerHandle;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -391,24 +391,24 @@ ImageBridgeChild::Connect(CompositableCl
     mImageContainers.Put(id, aImageContainer);
   }
 
   PCompositableChild* child =
     SendPCompositableConstructor(aCompositable->GetTextureInfo(), id);
   if (!child) {
     return;
   }
-  aCompositable->InitIPDLActor(child, id);
+  aCompositable->InitIPDLActor(child, CompositableHandle(id));
 }
 
 void
-ImageBridgeChild::ForgetImageContainer(uint64_t aAsyncContainerID)
+ImageBridgeChild::ForgetImageContainer(const CompositableHandle& aHandle)
 {
   MutexAutoLock lock(mContainerMapLock);
-  mImageContainers.Remove(aAsyncContainerID);
+  mImageContainers.Remove(aHandle.Value());
 }
 
 PCompositableChild*
 ImageBridgeChild::AllocPCompositableChild(const TextureInfo& aInfo, const uint64_t& aID)
 {
   MOZ_ASSERT(CanSend());
   return AsyncCompositableChild::CreateActor(aID);
 }
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -265,17 +265,17 @@ public:
   virtual void UseTextures(CompositableClient* aCompositable,
                            const nsTArray<TimedTextureClient>& aTextures) override;
   virtual void UseComponentAlphaTextures(CompositableClient* aCompositable,
                                          TextureClient* aClientOnBlack,
                                          TextureClient* aClientOnWhite) override;
 
   void Destroy(CompositableChild* aCompositable) override;
 
-  void ForgetImageContainer(uint64_t aAsyncContainerID);
+  void ForgetImageContainer(const CompositableHandle& aHandle);
 
   /**
    * Hold TextureClient ref until end of usage on host side if TextureFlags::RECYCLE is set.
    * Host side's usage is checked via CompositableRef.
    */
   void HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient);
 
   /**
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -814,33 +814,33 @@ ShadowLayerForwarder::Connect(Compositab
   if (!IPCOpen()) {
     return;
   }
   PCompositableChild* actor =
     mShadowManager->SendPCompositableConstructor(aCompositable->GetTextureInfo());
   if (!actor) {
     return;
   }
-  aCompositable->InitIPDLActor(actor);
+  aCompositable->InitIPDLActor(actor, CompositableHandle());
 }
 
 void ShadowLayerForwarder::Attach(CompositableClient* aCompositable,
                                   ShadowableLayer* aLayer)
 {
   MOZ_ASSERT(aLayer);
   MOZ_ASSERT(aCompositable);
   mTxn->AddEdit(OpAttachCompositable(Shadow(aLayer), nullptr, aCompositable->GetIPDLActor()));
 }
 
-void ShadowLayerForwarder::AttachAsyncCompositable(uint64_t aCompositableID,
+void ShadowLayerForwarder::AttachAsyncCompositable(const CompositableHandle& aHandle,
                                                    ShadowableLayer* aLayer)
 {
   MOZ_ASSERT(aLayer);
-  MOZ_ASSERT(aCompositableID != 0); // zero is always an invalid compositable id.
-  mTxn->AddEdit(OpAttachAsyncCompositable(Shadow(aLayer), aCompositableID));
+  MOZ_ASSERT(aHandle);
+  mTxn->AddEdit(OpAttachAsyncCompositable(Shadow(aLayer), aHandle.Value()));
 }
 
 void ShadowLayerForwarder::SetShadowManager(PLayerTransactionChild* aShadowManager)
 {
   mShadowManager = static_cast<LayerTransactionChild*>(aShadowManager);
   mShadowManager->SetForwarder(this);
 }
 
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -177,17 +177,17 @@ public:
   /**
    * Adds an edit in the transaction in order to attach a Compositable that
    * is not managed by this ShadowLayerForwarder (for example, by ImageBridge
    * in the case of async-video).
    * Since the compositable is not managed by this forwarder, we can't use
    * the compositable or it's IPDL actor here, so we use an ID instead, that
    * is matched on the compositor side.
    */
-  void AttachAsyncCompositable(uint64_t aCompositableID,
+  void AttachAsyncCompositable(const CompositableHandle& aHandle,
                                ShadowableLayer* aLayer);
 
   /**
    * Begin recording a transaction to be forwarded atomically to a
    * LayerManagerComposite.
    */
   void BeginTransaction(const gfx::IntRect& aTargetBounds,
                         ScreenRotation aRotation,
--- a/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
+++ b/gfx/layers/ipc/SharedPlanarYCbCrImage.cpp
@@ -31,18 +31,17 @@ SharedPlanarYCbCrImage::SharedPlanarYCbC
 : mCompositable(aCompositable)
 {
   MOZ_COUNT_CTOR(SharedPlanarYCbCrImage);
 }
 
 SharedPlanarYCbCrImage::~SharedPlanarYCbCrImage() {
   MOZ_COUNT_DTOR(SharedPlanarYCbCrImage);
 
-  if (mCompositable->GetAsyncID() != 0 &&
-      !InImageBridgeChildThread()) {
+  if (mCompositable->GetAsyncHandle() && !InImageBridgeChildThread()) {
     if (mTextureClient) {
       ADDREF_MANUALLY(mTextureClient);
       ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
       mTextureClient = nullptr;
     }
   }
 }
 
--- a/gfx/layers/ipc/SharedRGBImage.cpp
+++ b/gfx/layers/ipc/SharedRGBImage.cpp
@@ -58,18 +58,17 @@ SharedRGBImage::SharedRGBImage(ImageClie
 {
   MOZ_COUNT_CTOR(SharedRGBImage);
 }
 
 SharedRGBImage::~SharedRGBImage()
 {
   MOZ_COUNT_DTOR(SharedRGBImage);
 
-  if (mCompositable->GetAsyncID() != 0 &&
-      !InImageBridgeChildThread()) {
+  if (mCompositable->GetAsyncHandle() && !InImageBridgeChildThread()) {
     ADDREF_MANUALLY(mTextureClient);
     ImageBridgeChild::DispatchReleaseTextureClient(mTextureClient);
     mTextureClient = nullptr;
   }
 }
 
 bool
 SharedRGBImage::Allocate(gfx::IntSize aSize, gfx::SurfaceFormat aFormat)
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -2205,17 +2205,17 @@ nsBaseWidget::CreateScrollCaptureContain
 {
   mScrollCaptureContainer =
     LayerManager::CreateImageContainer(ImageContainer::ASYNCHRONOUS);
   if (!mScrollCaptureContainer) {
     NS_WARNING("Failed to create ImageContainer for widget image capture.");
     return ImageContainer::sInvalidAsyncContainerId;
   }
 
-  return mScrollCaptureContainer->GetAsyncContainerID();
+  return mScrollCaptureContainer->GetAsyncContainerHandle().Value();
 }
 
 void
 nsBaseWidget::UpdateScrollCapture()
 {
   // Don't capture if no container or no size.
   if (!mScrollCaptureContainer || mBounds.width <= 0 || mBounds.height <= 0) {
     return;