Bug 1357644 - Use wr::ExternalImageId instead of uint64_t for external image id r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Wed, 19 Apr 2017 18:59:53 +0900
changeset 355148 765939ca757ddeca3dae3a653c60973be3f6721c
parent 355147 9c846a7169412b6e2635c1873c9d1b0b6ec3b367
child 355149 a7152802939cf43c8413ce2475bbedb593f1ac1a
push id31723
push userkwierso@gmail.com
push dateThu, 27 Apr 2017 18:22:49 +0000
treeherdermozilla-central@c5c2b95e9d7b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1357644
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 1357644 - Use wr::ExternalImageId instead of uint64_t for external image id r=nical
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/ipc/WebRenderMessages.ipdlh
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderCanvasLayer.h
gfx/layers/wr/WebRenderDisplayItemLayer.cpp
gfx/layers/wr/WebRenderDisplayItemLayer.h
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderImageLayer.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
gfx/layers/wr/WebRenderMessageUtils.h
gfx/layers/wr/WebRenderPaintedLayer.cpp
gfx/layers/wr/WebRenderPaintedLayer.h
gfx/layers/wr/WebRenderTextureHost.cpp
gfx/layers/wr/WebRenderTextureHost.h
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -1178,23 +1178,23 @@ CompositorBridgeChild::AllocPWebRenderBr
 bool
 CompositorBridgeChild::DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor)
 {
   WebRenderBridgeChild* child = static_cast<WebRenderBridgeChild*>(aActor);
   child->ReleaseIPDLReference();
   return true;
 }
 
-uint64_t
+wr::ExternalImageId
 CompositorBridgeChild::GetNextExternalImageId()
 {
   static uint32_t sNextID = 1;
   ++sNextID;
   MOZ_RELEASE_ASSERT(sNextID != UINT32_MAX);
 
   uint64_t imageId = mNamespace;
   imageId = imageId << 32 | sNextID;
-  return imageId;
+  return wr::ToExternalImageId(imageId);
 }
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -8,16 +8,17 @@
 #define mozilla_layers_CompositorBridgeChild_h
 
 #include "base/basictypes.h"            // for DISALLOW_EVIL_CONSTRUCTORS
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/Attributes.h"         // for override
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/layers/PCompositorBridgeChild.h"
 #include "mozilla/layers/TextureForwarder.h" // for TextureForwarder
+#include "mozilla/webrender/WebRenderTypes.h"
 #include "nsClassHashtable.h"           // for nsClassHashtable
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsHashKeys.h"                 // for nsUint64HashKey
 #include "nsISupportsImpl.h"            // for NS_INLINE_DECL_REFCOUNTING
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "nsWeakReference.h"
 
 namespace mozilla {
@@ -229,17 +230,17 @@ public:
                                                     TextureFactoryIdentifier*,
                                                     uint32_t*) override;
   bool DeallocPWebRenderBridgeChild(PWebRenderBridgeChild* aActor) override;
 
   uint64_t DeviceResetSequenceNumber() const {
     return mDeviceResetSequenceNumber;
   }
 
-  uint64_t GetNextExternalImageId();
+  wr::ExternalImageId GetNextExternalImageId();
 
 private:
   // Private destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeChild();
 
   void InitIPDL();
   void DeallocPCompositorBridgeChild() override;
 
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -1151,22 +1151,22 @@ ImageBridgeChild::CanSend() const
 }
 
 void
 ImageBridgeChild::HandleFatalError(const char* aName, const char* aMsg) const
 {
   dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
 }
 
-uint64_t
+wr::ExternalImageId
 ImageBridgeChild::GetNextExternalImageId()
 {
   static uint32_t sNextID = 1;
   ++sNextID;
   MOZ_RELEASE_ASSERT(sNextID != UINT32_MAX);
 
   uint64_t imageId = mNamespace;
   imageId = imageId << 32 | sNextID;
-  return imageId;
+  return wr::ToExternalImageId(imageId);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -12,16 +12,17 @@
 #include "mozilla/Atomics.h"
 #include "mozilla/RefPtr.h"             // for already_AddRefed
 #include "mozilla/ipc/SharedMemory.h"   // for SharedMemory, etc
 #include "mozilla/layers/CanvasClient.h"
 #include "mozilla/layers/CompositableForwarder.h"
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/PImageBridgeChild.h"
 #include "mozilla/Mutex.h"
+#include "mozilla/webrender/WebRenderTypes.h"
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsIObserver.h"
 #include "nsRegion.h"                   // for nsIntRegion
 #include "mozilla/gfx/Rect.h"
 #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitor, etc
 
 class MessageLoop;
 
@@ -334,17 +335,17 @@ public:
   virtual uint64_t GetFwdTransactionId() override { return mFwdTransactionId; }
 
   bool InForwarderThread() override {
     return InImageBridgeChildThread();
   }
 
   virtual void HandleFatalError(const char* aName, const char* aMsg) const override;
 
-  uint64_t GetNextExternalImageId();
+  wr::ExternalImageId GetNextExternalImageId();
 
 protected:
   explicit ImageBridgeChild(uint32_t aNamespace);
   bool DispatchAllocShmemInternal(size_t aSize,
                                   SharedMemory::SharedMemoryType aType,
                                   Shmem* aShmem,
                                   bool aUnsafe);
 
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -12,16 +12,17 @@ include "mozilla/layers/WebRenderMessage
 
 include WebRenderMessages;
 include protocol PCompositorBridge;
 include protocol PTexture;
 
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using mozilla::layers::CompositableHandle from "mozilla/layers/LayersTypes.h";
 using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
+using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::ImageKey from "mozilla/webrender/WebRenderTypes.h";
 using WrBuiltDisplayListDescriptor from "mozilla/webrender/webrender_ffi.h";
 using WrAuxiliaryListsDescriptor from "mozilla/webrender/webrender_ffi.h";
 
 namespace mozilla {
 namespace layers {
 
 sync protocol PWebRenderBridge
@@ -48,19 +49,19 @@ parent:
   async AddRawFont(FontKey aFontKey, ByteBuffer aBytes, uint32_t aFontIndex);
   async DeleteFont(FontKey aFontKey);
   async DPBegin(IntSize aSize);
   async DPEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
               ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
   sync DPSyncEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
                  ByteBuffer aDL, WrBuiltDisplayListDescriptor aDLDesc, ByteBuffer aAux, WrAuxiliaryListsDescriptor aAuxDesc);
   sync DPGetSnapshot(PTexture texture);
-  async AddExternalImageId(uint64_t aImageId, CompositableHandle aHandle);
-  async AddExternalImageIdForCompositable(uint64_t aImageId, CompositableHandle aHandle);
-  async RemoveExternalImageId(uint64_t aImageId);
+  async AddExternalImageId(ExternalImageId aImageId, CompositableHandle aHandle);
+  async AddExternalImageIdForCompositable(ExternalImageId aImageId, CompositableHandle aHandle);
+  async RemoveExternalImageId(ExternalImageId aImageId);
   async SetLayerObserverEpoch(uint64_t layerObserverEpoch);
   async ClearCachedResources();
   // Schedule a composite if one isn't already scheduled.
   async ForceComposite();
 
   async Shutdown();
 child:
   async __delete__();
--- a/gfx/layers/ipc/WebRenderMessages.ipdlh
+++ b/gfx/layers/ipc/WebRenderMessages.ipdlh
@@ -18,27 +18,28 @@ using WrPoint from "mozilla/webrender/we
 using WrGradientStop from "mozilla/webrender/webrender_ffi.h";
 using WrGradientExtendMode from "mozilla/webrender/webrender_ffi.h";
 using WrGlyphArray from "mozilla/webrender/webrender_ffi.h";
 using WrMixBlendMode from "mozilla/webrender/webrender_ffi.h";
 using WrBoxShadowClipMode from "mozilla/webrender/webrender_ffi.h";
 using MaybeImageMask from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
 using mozilla::wr::ByteBuffer from "mozilla/webrender/WebRenderTypes.h";
+using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::PipelineId from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::ImageRendering from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::ImageKey from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::wr::FontKey from "mozilla/webrender/WebRenderTypes.h";
 using mozilla::LayerIntRegion from "Units.h";
 
 namespace mozilla {
 namespace layers {
 
 struct OpAddExternalImage {
-  uint64_t externalImageId;
+  ExternalImageId externalImageId;
   ImageKey key;
 };
 
 struct OpAddCompositorAnimations {
   CompositorAnimations data;
 };
 
 struct OpRemoveCompositorAnimations {
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -103,53 +103,51 @@ WebRenderBridgeChild::DPEnd(wr::DisplayL
   }
 
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mReadLocks.Clear();
   mIsInTransaction = false;
 }
 
-uint64_t
+wr::ExternalImageId
 WebRenderBridgeChild::GetNextExternalImageId()
 {
   return GetCompositorBridgeChild()->GetNextExternalImageId();
 }
 
-uint64_t
+wr::ExternalImageId
 WebRenderBridgeChild::AllocExternalImageId(const CompositableHandle& aHandle)
 {
   MOZ_ASSERT(!mDestroyed);
 
-  uint64_t imageId = GetNextExternalImageId();
+  wr::ExternalImageId imageId = GetNextExternalImageId();
   SendAddExternalImageId(imageId, aHandle);
   return imageId;
 }
 
-uint64_t
+wr::ExternalImageId
 WebRenderBridgeChild::AllocExternalImageIdForCompositable(CompositableClient* aCompositable)
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(aCompositable->IsConnected());
 
-  uint64_t imageId = GetNextExternalImageId();
+  wr::ExternalImageId imageId = GetNextExternalImageId();
   SendAddExternalImageIdForCompositable(imageId, aCompositable->GetIPCHandle());
   return imageId;
 }
 
 void
-WebRenderBridgeChild::DeallocExternalImageId(uint64_t aImageId)
+WebRenderBridgeChild::DeallocExternalImageId(wr::ExternalImageId& aImageId)
 {
   if (mDestroyed) {
     // This can happen if the IPC connection was torn down, because, e.g.
     // the GPU process died.
     return;
   }
-
-  MOZ_ASSERT(aImageId);
   SendRemoveExternalImageId(aImageId);
 }
 
 struct FontFileData
 {
   wr::ByteBuffer mFontBuffer;
   uint32_t mFontIndex;
 };
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -65,19 +65,19 @@ public:
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   wr::PipelineId GetPipeline() { return mPipelineId; }
 
   // KnowsCompositor
   TextureForwarder* GetTextureForwarder() override;
   LayersIPCActor* GetLayersIPCActor() override;
 
-  uint64_t AllocExternalImageId(const CompositableHandle& aHandle);
-  uint64_t AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
-  void DeallocExternalImageId(uint64_t aImageId);
+  wr::ExternalImageId AllocExternalImageId(const CompositableHandle& aHandle);
+  wr::ExternalImageId AllocExternalImageIdForCompositable(CompositableClient* aCompositable);
+  void DeallocExternalImageId(wr::ExternalImageId& aImageId);
 
   /**
    * Clean this up, finishing with SendShutDown() which will cause __delete__
    * to be sent from the parent side.
    */
   void Destroy();
   bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
   bool IsDestroyed() const { return mDestroyed; }
@@ -97,17 +97,17 @@ public:
 
   void RemoveExpiredFontKeys();
 
 private:
   friend class CompositorBridgeChild;
 
   ~WebRenderBridgeChild() {}
 
-  uint64_t GetNextExternalImageId();
+  wr::ExternalImageId GetNextExternalImageId();
 
   // CompositableForwarder
   void Connect(CompositableClient* aCompositable,
                ImageContainer* aImageContainer = nullptr) override;
   void UseTiledLayerBuffer(CompositableClient* aCompositable,
                            const SurfaceDescriptorTiles& aTiledDescriptor) override;
   void UpdateTextureRegion(CompositableClient* aCompositable,
                            const ThebesBufferData& aThebesBufferData,
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -349,21 +349,21 @@ WebRenderBridgeParent::ProcessWebRenderC
 {
 
   for (InfallibleTArray<WebRenderParentCommand>::index_type i = 0; i < aCommands.Length(); ++i) {
     const WebRenderParentCommand& cmd = aCommands[i];
     switch (cmd.type()) {
       case WebRenderParentCommand::TOpAddExternalImage: {
         const OpAddExternalImage& op = cmd.get_OpAddExternalImage();
         wr::ImageKey key = op.key();
-        MOZ_ASSERT(mExternalImageIds.Get(op.externalImageId()).get());
+        MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(op.externalImageId())).get());
         MOZ_ASSERT(!mActiveKeys.Get(wr::AsUint64(key), nullptr));
         mActiveKeys.Put(wr::AsUint64(key), key);
 
-        RefPtr<CompositableHost> host = mExternalImageIds.Get(op.externalImageId());
+        RefPtr<CompositableHost> host = mExternalImageIds.Get(wr::AsUint64(op.externalImageId()));
         if (!host) {
           NS_ERROR("CompositableHost does not exist");
           break;
         }
         // XXX select Texture for video in CompositeToTarget().
         TextureHost* texture = host->GetAsTextureHost();
         if (!texture) {
           NS_ERROR("TextureHost does not exist");
@@ -509,74 +509,74 @@ WebRenderBridgeParent::RecvDPGetSnapshot
   }
 
   mApi->Readback(size, buffer, buffer_size);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvAddExternalImageId(const uint64_t& aImageId,
+WebRenderBridgeParent::RecvAddExternalImageId(const ExternalImageId& aImageId,
                                               const CompositableHandle& aHandle)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
 
-  MOZ_ASSERT(!mExternalImageIds.Get(aImageId).get());
+  MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
 
   ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(OtherPid());
   if (!imageBridge) {
      return IPC_FAIL_NO_REASON(this);
   }
   RefPtr<CompositableHost> host = imageBridge->FindCompositable(aHandle);
   if (!host) {
     NS_ERROR("CompositableHost not found in the map!");
     return IPC_FAIL_NO_REASON(this);
   }
   MOZ_ASSERT(host->AsWebRenderImageHost());
   if (!host->AsWebRenderImageHost()) {
     NS_ERROR("Incompatible CompositableHost");
     return IPC_OK();
   }
 
-  mExternalImageIds.Put(aImageId, host);
+  mExternalImageIds.Put(wr::AsUint64(aImageId), host);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const uint64_t& aImageId,
+WebRenderBridgeParent::RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
                                                              const CompositableHandle& aHandle)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
-  MOZ_ASSERT(!mExternalImageIds.Get(aImageId).get());
+  MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
 
   RefPtr<CompositableHost> host = FindCompositable(aHandle);
   MOZ_ASSERT(host->AsWebRenderImageHost());
   if (!host->AsWebRenderImageHost()) {
     NS_ERROR("Incompatible CompositableHost");
     return IPC_OK();
   }
 
-  mExternalImageIds.Put(aImageId, host);
+  mExternalImageIds.Put(wr::AsUint64(aImageId), host);
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvRemoveExternalImageId(const uint64_t& aImageId)
+WebRenderBridgeParent::RecvRemoveExternalImageId(const ExternalImageId& aImageId)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
-  MOZ_ASSERT(mExternalImageIds.Get(aImageId).get());
-  mExternalImageIds.Remove(aImageId);
+  MOZ_ASSERT(mExternalImageIds.Get(wr::AsUint64(aImageId)).get());
+  mExternalImageIds.Remove(wr::AsUint64(aImageId));
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch)
 {
   mChildLayerObserverEpoch = aLayerObserverEpoch;
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -98,21 +98,21 @@ public:
                                         const uint64_t& aFwdTransactionId,
                                         const uint64_t& aTransactionId,
                                         const ByteBuffer& dl,
                                         const WrBuiltDisplayListDescriptor& dlDesc,
                                         const ByteBuffer& aux,
                                         const WrAuxiliaryListsDescriptor& auxDesc) override;
   mozilla::ipc::IPCResult RecvDPGetSnapshot(PTextureParent* aTexture) override;
 
-  mozilla::ipc::IPCResult RecvAddExternalImageId(const uint64_t& aImageId,
+  mozilla::ipc::IPCResult RecvAddExternalImageId(const ExternalImageId& aImageId,
                                                  const CompositableHandle& aHandle) override;
-  mozilla::ipc::IPCResult RecvAddExternalImageIdForCompositable(const uint64_t& aImageId,
+  mozilla::ipc::IPCResult RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
                                                                 const CompositableHandle& aHandle) override;
-  mozilla::ipc::IPCResult RecvRemoveExternalImageId(const uint64_t& aImageId) override;
+  mozilla::ipc::IPCResult RecvRemoveExternalImageId(const ExternalImageId& aImageId) override;
   mozilla::ipc::IPCResult RecvSetLayerObserverEpoch(const uint64_t& aLayerObserverEpoch) override;
 
   mozilla::ipc::IPCResult RecvClearCachedResources() override;
   mozilla::ipc::IPCResult RecvForceComposite() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void SetWebRenderProfilerEnabled(bool aEnabled);
 
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -21,18 +21,18 @@
 
 namespace mozilla {
 namespace layers {
 
 WebRenderCanvasLayer::~WebRenderCanvasLayer()
 {
   MOZ_COUNT_DTOR(WebRenderCanvasLayer);
 
-  if (mExternalImageId) {
-    WrBridge()->DeallocExternalImageId(mExternalImageId);
+  if (mExternalImageId.isSome()) {
+    WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
   }
 }
 
 void
 WebRenderCanvasLayer::Initialize(const Data& aData)
 {
   ShareableCanvasLayer::Initialize(aData);
 
@@ -45,22 +45,20 @@ WebRenderCanvasLayer::Initialize(const D
   screen->Morph(Move(factory));
 }
 
 void
 WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
 {
   UpdateCompositableClient();
 
-  if (!mExternalImageId) {
-    mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mCanvasClient);
+  if (mExternalImageId.isNothing()) {
+    mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mCanvasClient));
   }
 
-  MOZ_ASSERT(mExternalImageId);
-
   gfx::Matrix4x4 transform = GetTransform();
   const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
   if (needsYFlip) {
     transform.PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1);
   }
 
   gfx::Rect relBounds = GetWrRelBounds();
   gfx::Rect rect = RelativeToVisible(gfx::Rect(0, 0, mBounds.width, mBounds.height));
@@ -75,17 +73,17 @@ WebRenderCanvasLayer::RenderLayer(wr::Di
   DumpLayerInfo("CanvasLayer", rect);
   if (gfxPrefs::LayersDump()) {
     printf_stderr("CanvasLayer %p texture-filter=%s\n",
                   this->GetLayer(),
                   Stringify(filter).c_str());
   }
 
   WrImageKey key = GetImageKey();
-  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
+  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
   Manager()->AddImageKeyForDiscard(key);
 
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                                1.0f,
                                //GetAnimations(),
                                transform,
                                mixBlendMode);
   aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
--- a/gfx/layers/wr/WebRenderCanvasLayer.h
+++ b/gfx/layers/wr/WebRenderCanvasLayer.h
@@ -17,17 +17,16 @@ class SourceSurface;
 namespace layers {
 
 class WebRenderCanvasLayer : public WebRenderLayer,
                              public ShareableCanvasLayer
 {
 public:
   explicit WebRenderCanvasLayer(WebRenderLayerManager* aLayerManager)
     : ShareableCanvasLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
-    , mExternalImageId(0)
   {
     MOZ_COUNT_CTOR(WebRenderCanvasLayer);
   }
 
   virtual void Initialize(const Data& aData) override;
 
   virtual CompositableForwarder* GetForwarder() override;
 
@@ -40,15 +39,15 @@ protected:
     return static_cast<WebRenderLayerManager*>(mManager);
   }
 
 public:
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
 
 protected:
-  uint64_t mExternalImageId;
+  Maybe<wr::ExternalImageId> mExternalImageId;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERCANVASLAYER_H
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
@@ -17,18 +17,18 @@ namespace mozilla {
 namespace layers {
 
 WebRenderDisplayItemLayer::~WebRenderDisplayItemLayer()
 {
   MOZ_COUNT_DTOR(WebRenderDisplayItemLayer);
   if (mKey.isSome()) {
     WrManager()->AddImageKeyForDiscard(mKey.value());
   }
-  if (mExternalImageId) {
-    WrBridge()->DeallocExternalImageId(mExternalImageId);
+  if (mExternalImageId.isSome()) {
+    WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
   }
 }
 
 void
 WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
 {
   if (mVisibleRegion.IsEmpty()) {
     return;
@@ -78,27 +78,27 @@ WebRenderDisplayItemLayer::SendImageCont
                                                     WrBridge(),
                                                     TextureFlags::DEFAULT);
       if (!mImageClient) {
         return Nothing();
       }
       mImageClient->Connect();
     }
 
-    if (!mExternalImageId) {
+    if (mExternalImageId.isNothing()) {
       MOZ_ASSERT(mImageClient);
-      mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
+      mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
     }
-    MOZ_ASSERT(mExternalImageId);
+    MOZ_ASSERT(mExternalImageId.isSome());
     MOZ_ASSERT(mImageClient->AsImageClientSingle());
 
     mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
                           aContainer,
                           mKey,
-                          mExternalImageId);
+                          mExternalImageId.ref());
 
     mImageContainer = aContainer;
   }
 
   return mKey;
 }
 
 bool
@@ -114,19 +114,19 @@ WebRenderDisplayItemLayer::PushItemAsIma
                                                   WrBridge(),
                                                   TextureFlags::DEFAULT);
     if (!mImageClient) {
       return false;
     }
     mImageClient->Connect();
   }
 
-  if (!mExternalImageId) {
+  if (mExternalImageId.isNothing()) {
     MOZ_ASSERT(mImageClient);
-    mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
+    mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
   }
 
   bool snap;
   gfx::Rect bounds = mozilla::NSRectToRect(mItem->GetBounds(mBuilder, &snap),
                                       mItem->Frame()->PresContext()->AppUnitsPerDevPixel());
   gfx::IntSize imageSize = RoundedToInt(bounds.Size());
 
   UpdateImageHelper helper(mImageContainer, mImageClient, imageSize);
@@ -150,17 +150,17 @@ WebRenderDisplayItemLayer::PushItemAsIma
   if (!helper.UpdateImage()) {
     return false;
   }
 
   gfx::Rect dest = RelativeToParent(gfx::Rect(0, 0, imageSize.width, imageSize.height)) + offset;
   WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(dest));
   WrImageKey key = GetImageKey();
   aParentCommands.AppendElement(layers::OpAddExternalImage(
-                                mExternalImageId,
+                                mExternalImageId.value(),
                                 key));
   aBuilder.PushImage(wr::ToWrRect(dest),
                      clipRegion,
                      WrImageRendering::Auto,
                      key);
 
   return true;
 }
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.h
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.h
@@ -16,17 +16,16 @@
 namespace mozilla {
 namespace layers {
 
 class WebRenderDisplayItemLayer : public WebRenderLayer,
                                   public DisplayItemLayer {
 public:
   explicit WebRenderDisplayItemLayer(WebRenderLayerManager* aLayerManager)
     : DisplayItemLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
-    , mExternalImageId(0)
   {
     MOZ_COUNT_CTOR(WebRenderDisplayItemLayer);
   }
 
   Maybe<wr::ImageKey> SendImageContainer(ImageContainer* aContainer,
                                          nsTArray<layers::WebRenderParentCommand>& aParentCommands);
   bool PushItemAsImage(wr::DisplayListBuilder& aBuilder,
                        nsTArray<layers::WebRenderParentCommand>& aParentCommands);
@@ -38,16 +37,16 @@ public:
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
 
 private:
   wr::BuiltDisplayList mBuiltDisplayList;
   nsTArray<WebRenderParentCommand> mParentCommands;
   RefPtr<ImageClient> mImageClient;
   RefPtr<ImageContainer> mImageContainer;
-  uint64_t mExternalImageId;
+  Maybe<wr::ExternalImageId> mExternalImageId;
   Maybe<wr::ImageKey> mKey;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERDisplayItemLayer_H
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -15,30 +15,29 @@
 
 namespace mozilla {
 namespace layers {
 
 using namespace gfx;
 
 WebRenderImageLayer::WebRenderImageLayer(WebRenderLayerManager* aLayerManager)
   : ImageLayer(aLayerManager, static_cast<WebRenderLayer*>(this))
-  , mExternalImageId(0)
   , mImageClientTypeContainer(CompositableType::UNKNOWN)
 {
   MOZ_COUNT_CTOR(WebRenderImageLayer);
 }
 
 WebRenderImageLayer::~WebRenderImageLayer()
 {
   MOZ_COUNT_DTOR(WebRenderImageLayer);
   if (mKey.isSome()) {
     WrManager()->AddImageKeyForDiscard(mKey.value());
   }
-  if (mExternalImageId) {
-    WrBridge()->DeallocExternalImageId(mExternalImageId);
+  if (mExternalImageId.isSome()) {
+    WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
   }
 }
 
 CompositableType
 WebRenderImageLayer::GetImageClientType()
 {
   if (mImageClientTypeContainer != CompositableType::UNKNOWN) {
     return mImageClientTypeContainer;
@@ -101,49 +100,49 @@ WebRenderImageLayer::RenderLayer(wr::Dis
                                                   WrBridge(),
                                                   TextureFlags::DEFAULT);
     if (!mImageClient) {
       return;
     }
     mImageClient->Connect();
   }
 
-  if (!mExternalImageId) {
+  if (mExternalImageId.isNothing()) {
     if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
       MOZ_ASSERT(!mImageClient);
-      mExternalImageId = WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle());
+      mExternalImageId = Some(WrBridge()->AllocExternalImageId(mContainer->GetAsyncContainerHandle()));
     } else {
       // Handle CompositableType::IMAGE case
       MOZ_ASSERT(mImageClient);
-      mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
+      mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
     }
   }
-  MOZ_ASSERT(mExternalImageId);
+  MOZ_ASSERT(mExternalImageId.isSome());
 
   // XXX Not good for async ImageContainer case.
   AutoLockImage autoLock(mContainer);
   Image* image = autoLock.GetImage();
   if (!image) {
     return;
   }
   gfx::IntSize size = image->GetSize();
 
   if (GetImageClientType() == CompositableType::IMAGE_BRIDGE) {
     // Always allocate key
     WrImageKey key = GetImageKey();
-    WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
+    WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
     Manager()->AddImageKeyForDiscard(key);
     mKey = Some(key);
   } else {
     // Handle CompositableType::IMAGE case
     MOZ_ASSERT(mImageClient->AsImageClientSingle());
     mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
                           mContainer,
                           mKey,
-                          mExternalImageId);
+                          mExternalImageId.ref());
   }
 
   if (mKey.isNothing()) {
     return;
   }
 
   gfx::Matrix4x4 transform = GetTransform();
   gfx::Rect relBounds = GetWrRelBounds();
@@ -201,32 +200,31 @@ WebRenderImageLayer::RenderMaskLayer(con
                                                   WrBridge(),
                                                   TextureFlags::DEFAULT);
     if (!mImageClient) {
       return Nothing();
     }
     mImageClient->Connect();
   }
 
-  if (!mExternalImageId) {
-    mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
+  if (mExternalImageId.isNothing()) {
+    mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
   }
-  MOZ_ASSERT(mExternalImageId);
 
   AutoLockImage autoLock(mContainer);
   Image* image = autoLock.GetImage();
   if (!image) {
     return Nothing();
   }
 
   MOZ_ASSERT(mImageClient->AsImageClientSingle());
   mKey = UpdateImageKey(mImageClient->AsImageClientSingle(),
                         mContainer,
                         mKey,
-                        mExternalImageId);
+                        mExternalImageId.ref());
   if (mKey.isNothing()) {
     return Nothing();
   }
 
   gfx::IntSize size = image->GetSize();
   WrImageMask imageMask;
   imageMask.image = mKey.value();
   Rect maskRect = aTransform.TransformBounds(Rect(0, 0, size.width, size.height));
--- a/gfx/layers/wr/WebRenderImageLayer.h
+++ b/gfx/layers/wr/WebRenderImageLayer.h
@@ -33,17 +33,17 @@ protected:
 public:
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
   Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform) override;
 
 protected:
   CompositableType GetImageClientType();
 
-  uint64_t mExternalImageId;
+  Maybe<wr::ExternalImageId> mExternalImageId;
   Maybe<wr::ImageKey> mKey;
   RefPtr<ImageClient> mImageClient;
   CompositableType mImageClientTypeContainer;
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -174,21 +174,20 @@ WebRenderLayer::GetWrRelBounds()
 
   return RelativeToParent(bounds);
 }
 
 Maybe<wr::ImageKey>
 WebRenderLayer::UpdateImageKey(ImageClientSingle* aImageClient,
                                ImageContainer* aContainer,
                                Maybe<wr::ImageKey>& aOldKey,
-                               uint64_t aExternalImageId)
+                               wr::ExternalImageId& aExternalImageId)
 {
   MOZ_ASSERT(aImageClient);
   MOZ_ASSERT(aContainer);
-  MOZ_ASSERT(aExternalImageId);
 
   uint32_t oldCounter = aImageClient->GetLastUpdateGenerationCounter();
 
   bool ret = aImageClient->UpdateImage(aContainer, /* unused */0);
   if (!ret || aImageClient->IsEmpty()) {
     // Delete old key
     if (aOldKey.isSome()) {
       WrManager()->AddImageKeyForDiscard(aOldKey.value());
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -42,17 +42,17 @@ public:
   ToWebRenderLayer(Layer* aLayer)
   {
     return static_cast<WebRenderLayer*>(aLayer->ImplData());
   }
 
   Maybe<wr::ImageKey> UpdateImageKey(ImageClientSingle* aImageClient,
                                      ImageContainer* aContainer,
                                      Maybe<wr::ImageKey>& aOldKey,
-                                     uint64_t aExternalImageId);
+                                     wr::ExternalImageId& aExternalImageId);
 
   WebRenderLayerManager* WrManager();
   WebRenderBridgeChild* WrBridge();
   WrImageKey GetImageKey();
 
   gfx::Rect RelativeToVisible(gfx::Rect aRect);
   gfx::Rect RelativeToTransformedVisible(gfx::Rect aRect);
   gfx::Rect ParentStackingContextBounds();
--- a/gfx/layers/wr/WebRenderMessageUtils.h
+++ b/gfx/layers/wr/WebRenderMessageUtils.h
@@ -67,16 +67,32 @@ struct ParamTraits<mozilla::wr::FontKey>
   Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::FontKey* aResult)
   {
     return ReadParam(aMsg, aIter, &aResult->mNamespace)
         && ReadParam(aMsg, aIter, &aResult->mHandle);
   }
 };
 
 template<>
+struct ParamTraits<mozilla::wr::ExternalImageId>
+{
+  static void
+  Write(Message* aMsg, const mozilla::wr::ExternalImageId& aParam)
+  {
+    WriteParam(aMsg, aParam.mHandle);
+  }
+
+  static bool
+  Read(const Message* aMsg, PickleIterator* aIter, mozilla::wr::ExternalImageId* aResult)
+  {
+    return ReadParam(aMsg, aIter, &aResult->mHandle);
+  }
+};
+
+template<>
 struct ParamTraits<mozilla::wr::PipelineId>
 {
   static void
   Write(Message* aMsg, const mozilla::wr::PipelineId& aParam)
   {
     WriteParam(aMsg, aParam.mNamespace);
     WriteParam(aMsg, aParam.mHandle);
   }
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -129,19 +129,18 @@ WebRenderPaintedLayer::RenderLayer(wr::D
                                                   WrBridge(),
                                                   TextureFlags::DEFAULT);
     if (!mImageClient) {
       return;
     }
     mImageClient->Connect();
   }
 
-  if (!mExternalImageId) {
-    mExternalImageId = WrBridge()->AllocExternalImageIdForCompositable(mImageClient);
-    MOZ_ASSERT(mExternalImageId);
+  if (mExternalImageId.isNothing()) {
+    mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mImageClient));
   }
 
   LayerIntRegion visibleRegion = GetVisibleRegion();
   LayerIntRect bounds = visibleRegion.GetBounds();
   LayerIntSize size = bounds.Size();
   if (size.IsEmpty()) {
       if (gfxPrefs::LayersDump()) {
         printf_stderr("PaintedLayer %p skipping\n", this->GetLayer());
@@ -187,17 +186,17 @@ WebRenderPaintedLayer::RenderLayer(wr::D
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
 
   wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
   DumpLayerInfo("PaintedLayer", rect);
 
   WrImageKey key = GetImageKey();
-  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
+  WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
   Manager()->AddImageKeyForDiscard(key);
 
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                               1.0f,
                               //GetAnimations(),
                               transform,
                               mixBlendMode);
   aBuilder.PushImage(wr::ToWrRect(rect), clip, wr::ImageRendering::Auto, key);
--- a/gfx/layers/wr/WebRenderPaintedLayer.h
+++ b/gfx/layers/wr/WebRenderPaintedLayer.h
@@ -17,36 +17,35 @@ namespace layers {
 
 class WebRenderPaintedLayer : public WebRenderLayer,
                               public PaintedLayer {
 public:
   typedef RotatedContentBuffer::PaintState PaintState;
   typedef RotatedContentBuffer::ContentType ContentType;
 
   explicit WebRenderPaintedLayer(WebRenderLayerManager* aLayerManager)
-    : PaintedLayer(aLayerManager, static_cast<WebRenderLayer*>(this), LayerManager::NONE),
-      mExternalImageId(0)
+    : PaintedLayer(aLayerManager, static_cast<WebRenderLayer*>(this), LayerManager::NONE)
   {
     MOZ_COUNT_CTOR(WebRenderPaintedLayer);
   }
 
 protected:
   virtual ~WebRenderPaintedLayer()
   {
     MOZ_COUNT_DTOR(WebRenderPaintedLayer);
-    if (mExternalImageId) {
-      WrBridge()->DeallocExternalImageId(mExternalImageId);
+    if (mExternalImageId.isSome()) {
+      WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
     }
   }
   WebRenderLayerManager* Manager()
   {
     return static_cast<WebRenderLayerManager*>(mManager);
   }
 
-  uint64_t mExternalImageId;
+  Maybe<wr::ExternalImageId> mExternalImageId;
 
 public:
   virtual void InvalidateRegion(const nsIntRegion& aRegion) override
   {
     mInvalidRegion.Add(aRegion);
     mValidRegion.Sub(mValidRegion, mInvalidRegion.GetRegion());
   }
 
--- a/gfx/layers/wr/WebRenderTextureHost.cpp
+++ b/gfx/layers/wr/WebRenderTextureHost.cpp
@@ -20,29 +20,29 @@ namespace mozilla {
 namespace layers {
 
 uint64_t WebRenderTextureHost::sSerialCounter(0);
 
 WebRenderTextureHost::WebRenderTextureHost(const SurfaceDescriptor& aDesc,
                                            TextureFlags aFlags,
                                            TextureHost* aTexture)
   : TextureHost(aFlags)
-  , mExternalImageId(++sSerialCounter)
+  , mExternalImageId(wr::ToExternalImageId(++sSerialCounter))
   , mIsWrappingNativeHandle(false)
 {
   MOZ_COUNT_CTOR(WebRenderTextureHost);
   mWrappedTextureHost = aTexture;
 
   CreateRenderTextureHost(aDesc, aTexture);
 }
 
 WebRenderTextureHost::~WebRenderTextureHost()
 {
   MOZ_COUNT_DTOR(WebRenderTextureHost);
-  wr::RenderThread::Get()->UnregisterExternalImage(mExternalImageId);
+  wr::RenderThread::Get()->UnregisterExternalImage(wr::AsUint64(mExternalImageId));
 }
 
 void
 WebRenderTextureHost::CreateRenderTextureHost(const layers::SurfaceDescriptor& aDesc,
                                               TextureHost* aTexture)
 {
   RefPtr<wr::RenderTextureHost> texture;
 
@@ -63,17 +63,17 @@ WebRenderTextureHost::CreateRenderTextur
       mIsWrappingNativeHandle = true;
       break;
     }
 #endif
     default:
       gfxCriticalError() << "No WR implement for texture type:" << aDesc.type();
   }
 
-  wr::RenderThread::Get()->RegisterExternalImage(mExternalImageId, texture);
+  wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(mExternalImageId), texture);
 }
 
 bool
 WebRenderTextureHost::Lock()
 {
   MOZ_ASSERT_UNREACHABLE("unexpected to be called");
   return false;
 }
--- a/gfx/layers/wr/WebRenderTextureHost.h
+++ b/gfx/layers/wr/WebRenderTextureHost.h
@@ -2,16 +2,17 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #ifndef MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
 #define MOZILLA_GFX_WEBRENDERTEXTUREHOST_H
 
 #include "mozilla/layers/TextureHost.h"
+#include "mozilla/webrender/WebRenderTypes.h"
 
 namespace mozilla {
 namespace layers {
 
 class SurfaceDescriptor;
 
 // This textureHost is specialized for WebRender usage. With WebRender, there is
 // no Compositor during composition. Instead, we use RendererOGL for composition.
@@ -52,27 +53,27 @@ public:
   virtual gfx::IntSize GetSize() const override;
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() override { return "WebRenderTextureHost"; }
 #endif
 
   virtual WebRenderTextureHost* AsWebRenderTextureHost() override { return this; }
 
-  uint64_t GetExternalImageKey() { return mExternalImageId; }
+  wr::ExternalImageId GetExternalImageKey() { return mExternalImageId; }
 
   int32_t GetRGBStride();
 
   bool IsWrappingNativeHandle() { return mIsWrappingNativeHandle; }
 
 protected:
   void CreateRenderTextureHost(const SurfaceDescriptor& aDesc, TextureHost* aTexture);
 
   RefPtr<TextureHost> mWrappedTextureHost;
-  uint64_t mExternalImageId;
+  wr::ExternalImageId mExternalImageId;
 
   bool mIsWrappingNativeHandle;
 
   static uint64_t sSerialCounter;
 };
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -408,28 +408,28 @@ WebRenderAPI::AddBlobImage(ImageKey key,
                         key,
                         &aDescriptor,
                         RangeToByteSlice(aBytes));
 }
 
 void
 WebRenderAPI::AddExternalImageHandle(ImageKey key,
                                      const ImageDescriptor& aDescriptor,
-                                     uint64_t aHandle)
+                                     ExternalImageId aHandle)
 {
   wr_api_add_external_image_handle(mWrApi,
                                    key,
                                    &aDescriptor,
                                    aHandle);
 }
 
 void
 WebRenderAPI::AddExternalImageBuffer(ImageKey key,
                                      const ImageDescriptor& aDescriptor,
-                                     uint64_t aHandle)
+                                     ExternalImageId aHandle)
 {
   wr_api_add_external_image_buffer(mWrApi,
                                    key,
                                    &aDescriptor,
                                    aHandle);
 }
 
 void
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -70,21 +70,21 @@ public:
                 Range<uint8_t> aBytes);
 
   void AddBlobImage(wr::ImageKey aKey,
                     const ImageDescriptor& aDescriptor,
                     Range<uint8_t> aBytes);
 
   void AddExternalImageHandle(ImageKey key,
                               const ImageDescriptor& aDescriptor,
-                              uint64_t aHandle);
+                              ExternalImageId aHandle);
 
   void AddExternalImageBuffer(ImageKey key,
                               const ImageDescriptor& aDescriptor,
-                              uint64_t aHandle);
+                              ExternalImageId aHandle);
 
   void UpdateImageBuffer(wr::ImageKey aKey,
                          const ImageDescriptor& aDescriptor,
                          Range<uint8_t> aBytes);
 
   void DeleteImage(wr::ImageKey aKey);
 
   void AddRawFont(wr::FontKey aKey, Range<uint8_t> aBytes);
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -24,16 +24,17 @@ typedef WrGradientExtendMode GradientExt
 typedef WrMixBlendMode MixBlendMode;
 typedef WrImageRendering ImageRendering;
 typedef WrImageFormat ImageFormat;
 typedef WrWindowId WindowId;
 typedef WrPipelineId PipelineId;
 typedef WrImageKey ImageKey;
 typedef WrFontKey FontKey;
 typedef WrEpoch Epoch;
+typedef WrExternalImageId ExternalImageId;
 
 inline WindowId NewWindowId(uint64_t aId) {
   WindowId id;
   id.mHandle = aId;
   return id;
 }
 
 inline Epoch NewEpoch(uint32_t aEpoch) {
@@ -374,19 +375,24 @@ static inline WrComplexClipRegion ToWrCo
                                                         const LayerSize& size)
 {
   WrComplexClipRegion complex_clip;
   complex_clip.rect = wr::ToWrRect(rect);
   complex_clip.radii = wr::ToWrUniformBorderRadius(size);
   return complex_clip;
 }
 
-static inline WrExternalImageId ToWrExternalImageId(uint64_t aID)
+// Whenever possible, use wr::ExternalImageId instead of manipulating uint64_t.
+inline uint64_t AsUint64(const ExternalImageId& aId) {
+  return static_cast<uint64_t>(aId.mHandle);
+}
+
+static inline ExternalImageId ToExternalImageId(uint64_t aID)
 {
-  WrExternalImageId Id;
+  ExternalImageId Id;
   Id.mHandle = aID;
   return Id;
 }
 
 static inline WrExternalImage RawDataToWrExternalImage(const uint8_t* aBuff,
                                                        size_t size)
 {
   return WrExternalImage {
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -929,37 +929,37 @@ pub extern "C" fn wr_api_add_blob_image(
                   ImageData::new_blob_image(copied_bytes),
                   None);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_api_add_external_image_handle(api: &mut WrAPI,
                                                    image_key: WrImageKey,
                                                    descriptor: &WrImageDescriptor,
-                                                   external_image_id: u64) {
+                                                   external_image_id: WrExternalImageId) {
     assert!(unsafe { is_in_compositor_thread() });
     api.add_image(image_key,
                   descriptor.into(),
                   ImageData::External(ExternalImageData {
-                                          id: ExternalImageId(external_image_id),
+                                          id: external_image_id.into(),
                                           image_type: ExternalImageType::Texture2DHandle,
                                       }),
                   None);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_api_add_external_image_buffer(api: &mut WrAPI,
                                                    image_key: WrImageKey,
                                                    descriptor: &WrImageDescriptor,
-                                                   external_image_id: u64) {
+                                                   external_image_id: WrExternalImageId) {
     assert!(unsafe { is_in_compositor_thread() });
     api.add_image(image_key,
                   descriptor.into(),
                   ImageData::External(ExternalImageData {
-                                          id: ExternalImageId(external_image_id),
+                                          id: external_image_id.into(),
                                           image_type: ExternalImageType::ExternalBuffer,
                                       }),
                   None);
 }
 
 #[no_mangle]
 pub extern "C" fn wr_api_update_image(api: &mut WrAPI,
                                       key: WrImageKey,
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1,12 +1,14 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
+/* Generated with cbindgen:0.1.5 */
+
 /* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
  * To generate this file, clone `https://github.com/rlhunt/cbindgen` or run `cargo install cbindgen`,
  * then run `cbindgen -c wr gfx/webrender_bindings/ gfx/webrender_bindings/webrender_ffi_generated.h` */
 
 enum class WrBorderStyle : uint32_t {
   None = 0,
   Solid = 1,
   Double = 2,
@@ -44,16 +46,17 @@ enum class WrGradientExtendMode : uint32
 };
 
 enum class WrImageFormat : uint32_t {
   Invalid = 0,
   A8 = 1,
   RGB8 = 2,
   RGBA8 = 3,
   RGBAF32 = 4,
+  RG8 = 5,
 
   Sentinel /* this must be last for serialization purposes. */
 };
 
 enum class WrImageRendering : uint32_t {
   Auto = 0,
   CrispEdges = 1,
   Pixelated = 2,
@@ -124,16 +127,24 @@ struct WrByteSlice {
   size_t len;
 
   bool operator==(const WrByteSlice& aOther) const {
     return buffer == aOther.buffer &&
       len == aOther.len;
   }
 };
 
+struct WrExternalImageId {
+  uint64_t mHandle;
+
+  bool operator==(const WrExternalImageId& aOther) const {
+    return mHandle == aOther.mHandle;
+  }
+};
+
 struct WrFontKey {
   uint32_t mNamespace;
   uint32_t mHandle;
 
   bool operator==(const WrFontKey& aOther) const {
     return mNamespace == aOther.mNamespace &&
       mHandle == aOther.mHandle;
   }
@@ -458,24 +469,16 @@ struct WrExternalImage {
       v0 == aOther.v0 &&
       u1 == aOther.u1 &&
       v1 == aOther.v1 &&
       buff == aOther.buff &&
       size == aOther.size;
   }
 };
 
-struct WrExternalImageId {
-  uint64_t mHandle;
-
-  bool operator==(const WrExternalImageId& aOther) const {
-    return mHandle == aOther.mHandle;
-  }
-};
-
 typedef WrExternalImage (*LockExternalImageCallback)(void*, WrExternalImageId);
 
 typedef void (*UnlockExternalImageCallback)(void*, WrExternalImageId);
 
 typedef void (*ReleaseExternalImageCallback)(void*, WrExternalImageId);
 
 struct WrExternalImageHandler {
   void* external_image_obj;
@@ -517,24 +520,24 @@ wr_api_add_blob_image(WrAPI* api,
     const WrImageDescriptor* descriptor,
     WrByteSlice bytes)
 WR_FUNC;
 
 WR_INLINE void
 wr_api_add_external_image_buffer(WrAPI* api,
     WrImageKey image_key,
     const WrImageDescriptor* descriptor,
-    uint64_t external_image_id)
+    WrExternalImageId external_image_id)
 WR_FUNC;
 
 WR_INLINE void
 wr_api_add_external_image_handle(WrAPI* api,
     WrImageKey image_key,
     const WrImageDescriptor* descriptor,
-    uint64_t external_image_id)
+    WrExternalImageId external_image_id)
 WR_FUNC;
 
 WR_INLINE void
 wr_api_add_image(WrAPI* api,
     WrImageKey image_key,
     const WrImageDescriptor* descriptor,
     WrByteSlice bytes)
 WR_FUNC;