Bug 1393031 - Expose webrender transactions at the ipc boundary. r=jrmuizel, r=kanru
authorNicolas Silva <nsilva@mozilla.com>
Mon, 04 Sep 2017 13:59:26 +0200
changeset 378851 44463d7234864ab61c9f6eb6605220d4f6e8c775
parent 378850 cf18746c20ea99f41fd12e467ad5f4d81d06451a
child 378852 36260b6ee764ec4250d6f6e1a307070337470dc7
push id32443
push userarchaeopteryx@coole-files.de
push dateTue, 05 Sep 2017 09:41:20 +0000
treeherdermozilla-central@3ecda4678c49 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, kanru
bugs1393031
milestone57.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 1393031 - Expose webrender transactions at the ipc boundary. r=jrmuizel, r=kanru
gfx/layers/ipc/PWebRenderBridge.ipdl
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/webrender_bindings/Cargo.toml
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/WebRenderTypes.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/src/lib.rs
gfx/webrender_bindings/webrender_ffi_generated.h
ipc/ipdl/sync-messages.ini
toolkit/library/rust/Cargo.lock
--- a/gfx/layers/ipc/PWebRenderBridge.ipdl
+++ b/gfx/layers/ipc/PWebRenderBridge.ipdl
@@ -42,38 +42,42 @@ parent:
   async ReleaseCompositable(CompositableHandle compositable);
 
   // Creates a set of mappings between TextureReadLocks and an associated
   // ReadLockHandle that can be used in Update, and persist until the
   // next Update call.
   async InitReadLocks(ReadLockInit[] locks);
 
   sync Create(IntSize aSize);
+  async UpdateResources(ByteBuffer aUpdates);
   async AddImage(ImageKey aImageKey, IntSize aSize, uint32_t aStride,
                  SurfaceFormat aFormat, ByteBuffer aBytes);
   async AddBlobImage(ImageKey aImageKey, IntSize aSize, uint32_t aStride,
                      SurfaceFormat aFormat, ByteBuffer aBytes);
   async UpdateImage(ImageKey aImageKey, IntSize aSize,
                    SurfaceFormat aFormat, ByteBuffer aBytes);
   async DeleteImage(ImageKey aImageKey);
   async DeleteCompositorAnimations(uint64_t[] aIds);
   async AddRawFont(FontKey aFontKey, ByteBuffer aBytes, uint32_t aFontIndex);
   async DeleteFont(FontKey aFontKey);
   async AddFontInstance(FontInstanceKey aInstanceKey, FontKey aFontKey, float aGlyphSize,
                         MaybeFontInstanceOptions aOptions, MaybeFontInstancePlatformOptions aPlatformOptions);
   async DeleteFontInstance(FontInstanceKey aInstanceKey);
-  async DPBegin(IntSize aSize);
-  async DPEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
-              LayoutSize aContentSize, ByteBuffer aDL, BuiltDisplayListDescriptor aDLDesc,
-              WebRenderScrollData aScrollData, IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
-  sync DPSyncEnd(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
-                 LayoutSize aContentSize, ByteBuffer aDL, BuiltDisplayListDescriptor aDLDesc,
-                 WebRenderScrollData aScrollData, IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
+  async SetDisplayList(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
+                       LayoutSize aContentSize, ByteBuffer aDL, BuiltDisplayListDescriptor aDLDesc,
+                       WebRenderScrollData aScrollData,
+                       ByteBuffer aResourceUpdates,
+                       IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
+  sync SetDisplayListSync(IntSize aSize, WebRenderParentCommand[] commands, OpDestroy[] toDestroy, uint64_t fwdTransactionId, uint64_t transactionId,
+                          LayoutSize aContentSize, ByteBuffer aDL, BuiltDisplayListDescriptor aDLDesc,
+                          WebRenderScrollData aScrollData,
+                          ByteBuffer aResourceUpdates,
+                          IdNamespace aIdNamespace, TimeStamp txnStartTime, TimeStamp fwdTime);
   async ParentCommands(WebRenderParentCommand[] commands);
-  sync DPGetSnapshot(PTexture texture);
+  sync GetSnapshot(PTexture texture);
   async AddPipelineIdForCompositable(PipelineId aImageId, CompositableHandle aHandle, bool aAsync);
   async RemovePipelineIdForCompositable(PipelineId aPipelineId);
   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();
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -66,22 +66,21 @@ WebRenderBridgeChild::AddWebRenderParent
 void
 WebRenderBridgeChild::AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands)
 {
   MOZ_ASSERT(mIsInTransaction);
   mParentCommands.AppendElements(aCommands);
 }
 
 bool
-WebRenderBridgeChild::DPBegin(const gfx::IntSize& aSize)
+WebRenderBridgeChild::BeginTransaction(const gfx::IntSize& aSize)
 {
   MOZ_ASSERT(!mDestroyed);
 
   UpdateFwdTransactionId();
-  this->SendDPBegin(aSize);
   mIsInTransaction = true;
   mReadLockSequenceNumber = 0;
   mReadLocks.AppendElement();
   return true;
 }
 
 void
 WebRenderBridgeChild::ClearReadLocks()
@@ -94,42 +93,50 @@ WebRenderBridgeChild::ClearReadLocks()
       }
     }
   }
 
   mReadLocks.Clear();
 }
 
 void
-WebRenderBridgeChild::DPEnd(wr::DisplayListBuilder &aBuilder,
-                            const gfx::IntSize& aSize,
-                            bool aIsSync,
-                            uint64_t aTransactionId,
-                            const WebRenderScrollData& aScrollData,
-                            const mozilla::TimeStamp& aTxnStartTime)
+WebRenderBridgeChild::EndTransaction(wr::DisplayListBuilder &aBuilder,
+                                     const gfx::IntSize& aSize,
+                                     bool aIsSync,
+                                     uint64_t aTransactionId,
+                                     const WebRenderScrollData& aScrollData,
+                                     const mozilla::TimeStamp& aTxnStartTime)
 {
   MOZ_ASSERT(!mDestroyed);
   MOZ_ASSERT(mIsInTransaction);
 
   wr::BuiltDisplayList dl;
   wr::LayoutSize contentSize;
   aBuilder.Finalize(contentSize, dl);
   ByteBuffer dlData(Move(dl.dl));
 
   TimeStamp fwdTime;
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   fwdTime = TimeStamp::Now();
 #endif
 
+  // TODO(nical)
+  wr::ResourceUpdateQueue updates;
+  wr::ByteBuffer serializedUpdates(Move(updates.Serialize()));
+
   if (aIsSync) {
-    this->SendDPSyncEnd(aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
-                        contentSize, dlData, dl.dl_desc, aScrollData, mIdNamespace, aTxnStartTime, fwdTime);
+    this->SendSetDisplayListSync(aSize, mParentCommands, mDestroyedActors,
+                                 GetFwdTransactionId(), aTransactionId,
+                                 contentSize, dlData, dl.dl_desc, aScrollData,
+                                 serializedUpdates, mIdNamespace, aTxnStartTime, fwdTime);
   } else {
-    this->SendDPEnd(aSize, mParentCommands, mDestroyedActors, GetFwdTransactionId(), aTransactionId,
-                    contentSize, dlData, dl.dl_desc, aScrollData, mIdNamespace, aTxnStartTime, fwdTime);
+    this->SendSetDisplayList(aSize, mParentCommands, mDestroyedActors,
+                             GetFwdTransactionId(), aTransactionId,
+                             contentSize, dlData, dl.dl_desc, aScrollData,
+                             serializedUpdates, mIdNamespace, aTxnStartTime, fwdTime);
   }
 
   mParentCommands.Clear();
   mDestroyedActors.Clear();
   mIsInTransaction = false;
 }
 
 void
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -59,18 +59,18 @@ class WebRenderBridgeChild final : publi
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderBridgeChild, override)
 
 public:
   explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
 
   void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
   void AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands);
 
-  bool DPBegin(const  gfx::IntSize& aSize);
-  void DPEnd(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize,
+  bool BeginTransaction(const  gfx::IntSize& aSize);
+  void EndTransaction(wr::DisplayListBuilder &aBuilder, const gfx::IntSize& aSize,
              bool aIsSync, uint64_t aTransactionId,
              const WebRenderScrollData& aScrollData,
              const mozilla::TimeStamp& aTxnStartTime);
   void ProcessWebRenderParentCommands();
 
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   wr::PipelineId GetPipeline() { return mPipelineId; }
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -217,16 +217,23 @@ WebRenderBridgeParent::Destroy()
   if (mDestroyed) {
     return;
   }
   mDestroyed = true;
   ClearResources();
 }
 
 mozilla::ipc::IPCResult
+WebRenderBridgeParent::RecvUpdateResources(const wr::ByteBuffer& aUpdates)
+{
+  wr::ResourceUpdateQueue updates = wr::ResourceUpdateQueue::Deserialize(aUpdates.AsSlice());
+  mApi->UpdateResources(updates);
+}
+
+ mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvAddImage(const wr::ImageKey& aImageKey,
                                     const gfx::IntSize& aSize,
                                     const uint32_t& aStride,
                                     const gfx::SurfaceFormat& aFormat,
                                     const ByteBuffer& aBuffer)
 {
   if (mDestroyed) {
     return IPC_OK();
@@ -403,70 +410,16 @@ WebRenderBridgeParent::RecvDeleteComposi
     } else {
       NS_ERROR("Tried to delete invalid animation");
     }
   }
 
   return IPC_OK();
 }
 
-
-mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvDPBegin(const gfx::IntSize& aSize)
-{
-  if (mDestroyed) {
-    return IPC_OK();
-  }
-  return IPC_OK();
-}
-
-void
-WebRenderBridgeParent::HandleDPEnd(const gfx::IntSize& aSize,
-                                 InfallibleTArray<WebRenderParentCommand>&& aCommands,
-                                 InfallibleTArray<OpDestroy>&& aToDestroy,
-                                 const uint64_t& aFwdTransactionId,
-                                 const uint64_t& aTransactionId,
-                                 const wr::LayoutSize& aContentSize,
-                                 const wr::ByteBuffer& dl,
-                                 const wr::BuiltDisplayListDescriptor& dlDesc,
-                                 const WebRenderScrollData& aScrollData,
-                                 const wr::IdNamespace& aIdNamespace,
-                                 const TimeStamp& aTxnStartTime,
-                                 const TimeStamp& aFwdTime)
-{
-  AutoProfilerTracing tracing("Paint", "DPTransaction");
-  UpdateFwdTransactionId(aFwdTransactionId);
-  AutoClearReadLocks clearLocks(mReadLocks);
-
-  if (mDestroyed) {
-    for (const auto& op : aToDestroy) {
-      DestroyActor(op);
-    }
-    return;
-  }
-  // This ensures that destroy operations are always processed. It is not safe
-  // to early-return from RecvDPEnd without doing so.
-  AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
-
-  uint32_t wrEpoch = GetNextWrEpoch();
-  ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(wrEpoch),
-                           aContentSize, dl, dlDesc, aIdNamespace);
-  HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
-
-  mScrollData = aScrollData;
-  UpdateAPZ();
-
-  if (mIdNamespace != aIdNamespace) {
-    // Pretend we composited since someone is wating for this event,
-    // though DisplayList was not pushed to webrender.
-    TimeStamp now = TimeStamp::Now();
-    mCompositorBridge->DidComposite(wr::AsUint64(mPipelineId), now, now);
-  }
-}
-
 CompositorBridgeParent*
 WebRenderBridgeParent::GetRootCompositorBridgeParent() const
 {
   if (!mCompositorBridge) {
     return nullptr;
   }
 
   if (mWidget) {
@@ -531,57 +484,83 @@ WebRenderBridgeParent::PushAPZStateToWR(
 const WebRenderScrollData&
 WebRenderBridgeParent::GetScrollData() const
 {
   MOZ_ASSERT(mozilla::layers::CompositorThreadHolder::IsInCompositorThread());
   return mScrollData;
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvDPEnd(const gfx::IntSize& aSize,
-                                 InfallibleTArray<WebRenderParentCommand>&& aCommands,
-                                 InfallibleTArray<OpDestroy>&& aToDestroy,
-                                 const uint64_t& aFwdTransactionId,
-                                 const uint64_t& aTransactionId,
-                                 const wr::LayoutSize& aContentSize,
-                                 const wr::ByteBuffer& dl,
-                                 const wr::BuiltDisplayListDescriptor& dlDesc,
-                                 const WebRenderScrollData& aScrollData,
-                                 const wr::IdNamespace& aIdNamespace,
-                                 const TimeStamp& aTxnStartTime,
-                                 const TimeStamp& aFwdTime)
+WebRenderBridgeParent::RecvSetDisplayList(const gfx::IntSize& aSize,
+                                          InfallibleTArray<WebRenderParentCommand>&& aCommands,
+                                          InfallibleTArray<OpDestroy>&& aToDestroy,
+                                          const uint64_t& aFwdTransactionId,
+                                          const uint64_t& aTransactionId,
+                                          const wr::LayoutSize& aContentSize,
+                                          const wr::ByteBuffer& dl,
+                                          const wr::BuiltDisplayListDescriptor& dlDesc,
+                                          const WebRenderScrollData& aScrollData,
+                                          const wr::ByteBuffer& aResourceUpdates,
+                                          const wr::IdNamespace& aIdNamespace,
+                                          const TimeStamp& aTxnStartTime,
+                                          const TimeStamp& aFwdTime)
 {
   if (mDestroyed) {
+    for (const auto& op : aToDestroy) {
+      DestroyActor(op);
+    }
     return IPC_OK();
   }
-  HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
-              aContentSize, dl, dlDesc, aScrollData, aIdNamespace, aTxnStartTime, aFwdTime);
+
+  AutoProfilerTracing tracing("Paint", "SetDisplayList");
+  UpdateFwdTransactionId(aFwdTransactionId);
+  AutoClearReadLocks clearLocks(mReadLocks);
+
+  // This ensures that destroy operations are always processed. It is not safe
+  // to early-return from RecvDPEnd without doing so.
+  AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
+
+  wr::ResourceUpdateQueue resources = wr::ResourceUpdateQueue::Deserialize(aResourceUpdates.AsSlice());
+
+  uint32_t wrEpoch = GetNextWrEpoch();
+  ProcessWebRenderCommands(aSize, aCommands, wr::NewEpoch(wrEpoch),
+                           aContentSize, dl, dlDesc, resources, aIdNamespace);
+  HoldPendingTransactionId(wrEpoch, aTransactionId, aTxnStartTime, aFwdTime);
+
+  mScrollData = aScrollData;
+  UpdateAPZ();
+
+  if (mIdNamespace != aIdNamespace) {
+    // Pretend we composited since someone is wating for this event,
+    // though DisplayList was not pushed to webrender.
+    TimeStamp now = TimeStamp::Now();
+    mCompositorBridge->DidComposite(wr::AsUint64(mPipelineId), now, now);
+  }
+
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvDPSyncEnd(const gfx::IntSize &aSize,
-                                     InfallibleTArray<WebRenderParentCommand>&& aCommands,
-                                     InfallibleTArray<OpDestroy>&& aToDestroy,
-                                     const uint64_t& aFwdTransactionId,
-                                     const uint64_t& aTransactionId,
-                                     const wr::LayoutSize& aContentSize,
-                                     const wr::ByteBuffer& dl,
-                                     const wr::BuiltDisplayListDescriptor& dlDesc,
-                                     const WebRenderScrollData& aScrollData,
-                                     const wr::IdNamespace& aIdNamespace,
-                                     const TimeStamp& aTxnStartTime,
-                                     const TimeStamp& aFwdTime)
+WebRenderBridgeParent::RecvSetDisplayListSync(const gfx::IntSize &aSize,
+                                              InfallibleTArray<WebRenderParentCommand>&& aCommands,
+                                              InfallibleTArray<OpDestroy>&& aToDestroy,
+                                              const uint64_t& aFwdTransactionId,
+                                              const uint64_t& aTransactionId,
+                                              const wr::LayoutSize& aContentSize,
+                                              const wr::ByteBuffer& dl,
+                                              const wr::BuiltDisplayListDescriptor& dlDesc,
+                                              const WebRenderScrollData& aScrollData,
+                                              const wr::ByteBuffer& aResourceUpdates,
+                                              const wr::IdNamespace& aIdNamespace,
+                                              const TimeStamp& aTxnStartTime,
+                                              const TimeStamp& aFwdTime)
 {
-  if (mDestroyed) {
-    return IPC_OK();
-  }
-  HandleDPEnd(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
-              aContentSize, dl, dlDesc, aScrollData, aIdNamespace, aTxnStartTime, aFwdTime);
-  return IPC_OK();
+  return RecvSetDisplayList(aSize, Move(aCommands), Move(aToDestroy), aFwdTransactionId, aTransactionId,
+                            aContentSize, dl, dlDesc, aScrollData, aResourceUpdates,
+                            aIdNamespace, aTxnStartTime, aFwdTime);
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvParentCommands(nsTArray<WebRenderParentCommand>&& aCommands)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
@@ -683,16 +662,17 @@ WebRenderBridgeParent::ProcessWebRenderP
   }
 }
 
 void
 WebRenderBridgeParent::ProcessWebRenderCommands(const gfx::IntSize &aSize,
                                                 InfallibleTArray<WebRenderParentCommand>& aCommands, const wr::Epoch& aEpoch,
                                                 const wr::LayoutSize& aContentSize, const wr::ByteBuffer& dl,
                                                 const wr::BuiltDisplayListDescriptor& dlDesc,
+                                                wr::ResourceUpdateQueue& aResourceUpdates,
                                                 const wr::IdNamespace& aIdNamespace)
 {
   mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
   ProcessWebRenderParentCommands(aCommands);
 
   // The command is obsoleted.
   // Do not set the command to webrender since it causes crash in webrender.
   if (mIdNamespace != aIdNamespace) {
@@ -701,28 +681,29 @@ WebRenderBridgeParent::ProcessWebRenderC
 
   if (mWidget) {
     LayoutDeviceIntSize size = mWidget->GetClientSize();
     mApi->SetWindowParameters(size);
   }
   gfx::Color color = mWidget ? gfx::Color(0.3f, 0.f, 0.f, 1.f) : gfx::Color(0.f, 0.f, 0.f, 0.f);
   mApi->SetDisplayList(color, aEpoch, LayerSize(aSize.width, aSize.height),
                        mPipelineId, aContentSize,
-                       dlDesc, dl.mData, dl.mLength);
+                       dlDesc, dl.mData, dl.mLength,
+                       &aResourceUpdates);
 
   ScheduleComposition();
   DeleteOldImages();
 
   if (ShouldParentObserveEpoch()) {
     mCompositorBridge->ObserveLayerUpdate(GetLayersId(), GetChildLayerObserverEpoch(), true);
   }
 }
 
 mozilla::ipc::IPCResult
-WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture)
+WebRenderBridgeParent::RecvGetSnapshot(PTextureParent* aTexture)
 {
   if (mDestroyed) {
     return IPC_OK();
   }
   MOZ_ASSERT(!mPaused);
 
   RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
   if (!texture) {
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -67,16 +67,17 @@ public:
                                               const TextureInfo& aInfo) override;
   mozilla::ipc::IPCResult RecvReleaseCompositable(const CompositableHandle& aHandle) override;
 
   mozilla::ipc::IPCResult RecvInitReadLocks(ReadLockArray&& aReadLocks) override;
 
   mozilla::ipc::IPCResult RecvCreate(const gfx::IntSize& aSize) override;
   mozilla::ipc::IPCResult RecvShutdown() override;
   mozilla::ipc::IPCResult RecvShutdownSync() override;
+  mozilla::ipc::IPCResult RecvUpdateResources(const wr::ByteBuffer& aUpdates) override;
   mozilla::ipc::IPCResult RecvAddImage(const wr::ImageKey& aImageKey,
                                        const gfx::IntSize& aSize,
                                        const uint32_t& aStride,
                                        const gfx::SurfaceFormat& aFormat,
                                        const ByteBuffer& aBuffer) override;
   mozilla::ipc::IPCResult RecvAddBlobImage(const wr::ImageKey& aImageKey,
                                            const gfx::IntSize& aSize,
                                            const uint32_t& aStride,
@@ -93,43 +94,44 @@ public:
                                          const uint32_t& aFontIndex) override;
   mozilla::ipc::IPCResult RecvDeleteFont(const wr::FontKey& aFontKey) override;
   mozilla::ipc::IPCResult RecvAddFontInstance(const wr::FontInstanceKey& aInstanceKey,
                                               const wr::FontKey& aFontKey,
                                               const float& aGlyphSize,
                                               const MaybeFontInstanceOptions& aOptions,
                                               const MaybeFontInstancePlatformOptions& aPlatformOptions) override;
   mozilla::ipc::IPCResult RecvDeleteFontInstance(const wr::FontInstanceKey& aInstanceKey) override;
-  mozilla::ipc::IPCResult RecvDPBegin(const gfx::IntSize& aSize) override;
-  mozilla::ipc::IPCResult RecvDPEnd(const gfx::IntSize& aSize,
-                                    InfallibleTArray<WebRenderParentCommand>&& aCommands,
-                                    InfallibleTArray<OpDestroy>&& aToDestroy,
-                                    const uint64_t& aFwdTransactionId,
-                                    const uint64_t& aTransactionId,
-                                    const wr::LayoutSize& aContentSize,
-                                    const wr::ByteBuffer& dl,
-                                    const wr::BuiltDisplayListDescriptor& dlDesc,
-                                    const WebRenderScrollData& aScrollData,
-                                    const wr::IdNamespace& aIdNamespace,
-                                    const TimeStamp& aTxnStartTime,
-                                    const TimeStamp& aFwdTime) override;
-  mozilla::ipc::IPCResult RecvDPSyncEnd(const gfx::IntSize& aSize,
-                                        InfallibleTArray<WebRenderParentCommand>&& aCommands,
-                                        InfallibleTArray<OpDestroy>&& aToDestroy,
-                                        const uint64_t& aFwdTransactionId,
-                                        const uint64_t& aTransactionId,
-                                        const wr::LayoutSize& aContentSize,
-                                        const wr::ByteBuffer& dl,
-                                        const wr::BuiltDisplayListDescriptor& dlDesc,
-                                        const WebRenderScrollData& aScrollData,
-                                        const wr::IdNamespace& aIdNamespace,
-                                        const TimeStamp& aTxnStartTime,
-                                        const TimeStamp& aFwdTime) override;
+  mozilla::ipc::IPCResult RecvSetDisplayList(const gfx::IntSize& aSize,
+                                             InfallibleTArray<WebRenderParentCommand>&& aCommands,
+                                             InfallibleTArray<OpDestroy>&& aToDestroy,
+                                             const uint64_t& aFwdTransactionId,
+                                             const uint64_t& aTransactionId,
+                                             const wr::LayoutSize& aContentSize,
+                                             const wr::ByteBuffer& dl,
+                                             const wr::BuiltDisplayListDescriptor& dlDesc,
+                                             const WebRenderScrollData& aScrollData,
+                                             const wr::ByteBuffer& aResourceUpdates,
+                                             const wr::IdNamespace& aIdNamespace,
+                                             const TimeStamp& aTxnStartTime,
+                                             const TimeStamp& aFwdTime) override;
+  mozilla::ipc::IPCResult RecvSetDisplayListSync(const gfx::IntSize& aSize,
+                                                 InfallibleTArray<WebRenderParentCommand>&& aCommands,
+                                                 InfallibleTArray<OpDestroy>&& aToDestroy,
+                                                 const uint64_t& aFwdTransactionId,
+                                                 const uint64_t& aTransactionId,
+                                                 const wr::LayoutSize& aContentSize,
+                                                 const wr::ByteBuffer& dl,
+                                                 const wr::BuiltDisplayListDescriptor& dlDesc,
+                                                 const WebRenderScrollData& aScrollData,
+                                                 const wr::ByteBuffer& aResourceUpdates,
+                                                 const wr::IdNamespace& aIdNamespace,
+                                                 const TimeStamp& aTxnStartTime,
+                                                 const TimeStamp& aFwdTime) override;
   mozilla::ipc::IPCResult RecvParentCommands(nsTArray<WebRenderParentCommand>&& commands) override;
-  mozilla::ipc::IPCResult RecvDPGetSnapshot(PTextureParent* aTexture) override;
+  mozilla::ipc::IPCResult RecvGetSnapshot(PTextureParent* aTexture) override;
 
   mozilla::ipc::IPCResult RecvAddPipelineIdForCompositable(const wr::PipelineId& aPipelineIds,
                                                            const CompositableHandle& aHandle,
                                                            const bool& aAsync) override;
   mozilla::ipc::IPCResult RecvRemovePipelineIdForCompositable(const wr::PipelineId& aPipelineId) override;
 
   mozilla::ipc::IPCResult RecvAddExternalImageIdForCompositable(const ExternalImageId& aImageId,
                                                                 const CompositableHandle& aHandle) override;
@@ -211,32 +213,21 @@ private:
   void DeleteOldImages();
   void ProcessWebRenderParentCommands(InfallibleTArray<WebRenderParentCommand>& aCommands);
   void ProcessWebRenderCommands(const gfx::IntSize &aSize,
                                 InfallibleTArray<WebRenderParentCommand>& commands,
                                 const wr::Epoch& aEpoch,
                                 const wr::LayoutSize& aContentSize,
                                 const wr::ByteBuffer& dl,
                                 const wr::BuiltDisplayListDescriptor& dlDesc,
+                                wr::ResourceUpdateQueue& aResourceUpdates,
                                 const wr::IdNamespace& aIdNamespace);
   void ClearResources();
   uint64_t GetChildLayerObserverEpoch() const { return mChildLayerObserverEpoch; }
   bool ShouldParentObserveEpoch();
-  void HandleDPEnd(const gfx::IntSize& aSize,
-                   InfallibleTArray<WebRenderParentCommand>&& aCommands,
-                   InfallibleTArray<OpDestroy>&& aToDestroy,
-                   const uint64_t& aFwdTransactionId,
-                   const uint64_t& aTransactionId,
-                   const wr::LayoutSize& aContentSize,
-                   const wr::ByteBuffer& dl,
-                   const wr::BuiltDisplayListDescriptor& dlDesc,
-                   const WebRenderScrollData& aScrollData,
-                   const wr::IdNamespace& aIdNamespace,
-                   const TimeStamp& aTxnStartTime,
-                   const TimeStamp& aFwdTime);
   mozilla::ipc::IPCResult HandleShutdown();
 
   void AdvanceAnimations();
   void SampleAnimations(nsTArray<wr::WrOpacityProperty>& aOpacityArray,
                         nsTArray<wr::WrTransformProperty>& aTransformArray);
 
   CompositorBridgeParent* GetRootCompositorBridgeParent() const;
 
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -694,17 +694,17 @@ WebRenderLayerManager::EndTransactionInt
   if (gfxPrefs::LayersDump()) {
     this->Dump();
   }
 
   // Since we don't do repeat transactions right now, just set the time
   mAnimationReadyTime = TimeStamp::Now();
 
   LayoutDeviceIntSize size = mWidget->GetClientSize();
-  if (!WrBridge()->DPBegin(size.ToUnknownSize())) {
+  if (!WrBridge()->BeginTransaction(size.ToUnknownSize())) {
     return false;
   }
   DiscardCompositorAnimations();
 
   wr::LayoutSize contentSize { (float)size.width, (float)size.height };
   wr::DisplayListBuilder builder(WrBridge()->GetPipeline(), contentSize);
 
   if (mEndTransactionWithoutLayers) {
@@ -810,17 +810,18 @@ WebRenderLayerManager::EndTransactionInt
     if (WrBridge()->GetSyncObject() &&
         WrBridge()->GetSyncObject()->IsSyncObjectValid()) {
       WrBridge()->GetSyncObject()->Synchronize();
     }
   }
   {
     AutoProfilerTracing
       tracing("Paint", sync ? "ForwardDPTransactionSync":"ForwardDPTransaction");
-    WrBridge()->DPEnd(builder, size.ToUnknownSize(), sync, mLatestTransactionId, mScrollData, transactionStart);
+    WrBridge()->EndTransaction(builder, size.ToUnknownSize(), sync,
+                               mLatestTransactionId, mScrollData, transactionStart);
   }
 
   MakeSnapshotIfRequired(size);
   mNeedsComposite = false;
 
   ClearDisplayItemLayers();
 
   // this may result in Layers being deleted, which results in
@@ -865,17 +866,17 @@ WebRenderLayerManager::MakeSnapshotIfReq
   }
 
   texture->InitIPDLActor(WrBridge());
   if (!texture->GetIPDLActor()) {
     return;
   }
 
   IntRect bounds = ToOutsideIntRect(mTarget->GetClipExtents());
-  if (!WrBridge()->SendDPGetSnapshot(texture->GetIPDLActor())) {
+  if (!WrBridge()->SendGetSnapshot(texture->GetIPDLActor())) {
     return;
   }
 
   TextureClientAutoLock autoLock(texture, OpenMode::OPEN_READ_ONLY);
   if (!autoLock.Succeeded()) {
     return;
   }
   RefPtr<DrawTarget> drawTarget = texture->BorrowDrawTarget();
--- a/gfx/webrender_bindings/Cargo.toml
+++ b/gfx/webrender_bindings/Cargo.toml
@@ -1,16 +1,17 @@
 [package]
 name = "webrender_bindings"
 version = "0.1.0"
 authors = ["The Mozilla Project Developers"]
 license = "MPL-2.0"
 
 [dependencies]
 webrender_api = {path = "../webrender_api", version = "0.50.0"}
+bincode = "0.8"
 rayon = "0.8"
 thread_profiler = "0.1.1"
 euclid = "0.15"
 app_units = "0.5"
 gleam = "0.4"
 
 [dependencies.webrender]
 path = "../webrender"
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -230,28 +230,36 @@ WebRenderAPI::GenerateFrame(const nsTArr
 void
 WebRenderAPI::SetDisplayList(gfx::Color aBgColor,
                              Epoch aEpoch,
                              mozilla::LayerSize aViewportSize,
                              wr::WrPipelineId pipeline_id,
                              const LayoutSize& content_size,
                              wr::BuiltDisplayListDescriptor dl_descriptor,
                              uint8_t *dl_data,
-                             size_t dl_size)
+                             size_t dl_size,
+                             ResourceUpdateQueue* aResources)
 {
-    wr_api_set_display_list(mDocHandle,
-                            ToColorF(aBgColor),
-                            aEpoch,
-                            aViewportSize.width, aViewportSize.height,
-                            pipeline_id,
-                            content_size,
-                            dl_descriptor,
-                            dl_data,
-                            dl_size,
-                            mResources.Raw());
+  ResourceUpdateQueue* resources = aResources ? aResources : &mResources;
+  if (aResources) {
+    // TODO(nical) properly separate ResourceUpdateQueue from the api object.
+    // In the mean time, it makes sense to flush mResources it has updates
+    // and we pass another resource update queue.
+    UpdateResources(mResources);
+  }
+  wr_api_set_display_list(mDocHandle,
+                          ToColorF(aBgColor),
+                          aEpoch,
+                          aViewportSize.width, aViewportSize.height,
+                          pipeline_id,
+                          content_size,
+                          dl_descriptor,
+                          dl_data,
+                          dl_size,
+                          resources->Raw());
 }
 
 void
 WebRenderAPI::ClearDisplayList(Epoch aEpoch,
                                wr::WrPipelineId pipeline_id)
 {
   wr_api_clear_display_list(mDocHandle, aEpoch, pipeline_id, mResources.Raw());
 }
@@ -451,16 +459,34 @@ ResourceUpdateQueue::operator=(ResourceU
 
 ResourceUpdateQueue::~ResourceUpdateQueue()
 {
   if (mUpdates) {
     wr_resource_updates_delete(mUpdates);
   }
 }
 
+ByteBuffer
+ResourceUpdateQueue::Serialize()
+{
+  VecU8 data;
+  wr_resource_updates_serialize(mUpdates, &data);
+  ByteBuffer result(Move(data));
+  return result;
+}
+
+//static
+ResourceUpdateQueue
+ResourceUpdateQueue::Deserialize(Range<uint8_t> aData)
+{
+  auto slice = wr::RangeToByteSlice(aData);
+  ResourceUpdateQueue result(wr_resource_updates_deserialize(slice));
+  return result;
+}
+
 void
 ResourceUpdateQueue::AddImage(ImageKey key, const ImageDescriptor& aDescriptor,
                               Range<uint8_t> aBytes)
 {
   wr_resource_updates_add_image(mUpdates,
                                 key,
                                 &aDescriptor,
                                 RangeToByteSlice(aBytes));
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -54,16 +54,21 @@ class ResourceUpdateQueue {
 public:
   ResourceUpdateQueue();
   ~ResourceUpdateQueue();
   ResourceUpdateQueue(ResourceUpdateQueue&&);
   ResourceUpdateQueue(const ResourceUpdateQueue&) = delete;
   ResourceUpdateQueue& operator=(ResourceUpdateQueue&&);
   ResourceUpdateQueue& operator=(const ResourceUpdateQueue&) = delete;
 
+  /// Serializes into a buffer of bytes and clears the queue.
+  ByteBuffer Serialize();
+
+  static ResourceUpdateQueue Deserialize(Range<uint8_t> aData);
+
   void AddImage(wr::ImageKey aKey,
                 const ImageDescriptor& aDescriptor,
                 Range<uint8_t> aBytes);
 
   void AddBlobImage(wr::ImageKey aKey,
                     const ImageDescriptor& aDescriptor,
                     Range<uint8_t> aBytes);
 
@@ -104,16 +109,19 @@ public:
                        const wr::FontInstancePlatformOptions* aPlatformOptions);
 
   void DeleteFontInstance(wr::FontInstanceKey aKey);
 
   // Try to avoid using this when possible.
   wr::ResourceUpdates* Raw() { return mUpdates; }
 
 protected:
+  ResourceUpdateQueue(wr::ResourceUpdates* aUpdates)
+  : mUpdates(aUpdates) {}
+
   wr::ResourceUpdates* mUpdates;
 };
 
 class WebRenderAPI
 {
   NS_INLINE_DECL_REFCOUNTING(WebRenderAPI);
 
 public:
@@ -138,17 +146,18 @@ public:
 
   void SetDisplayList(gfx::Color aBgColor,
                       Epoch aEpoch,
                       mozilla::LayerSize aViewportSize,
                       wr::WrPipelineId pipeline_id,
                       const wr::LayoutSize& content_size,
                       wr::BuiltDisplayListDescriptor dl_descriptor,
                       uint8_t *dl_data,
-                      size_t dl_size);
+                      size_t dl_size,
+                      ResourceUpdateQueue* aResources = nullptr);
 
   void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId pipeline_id);
 
   void SetRootPipeline(wr::PipelineId aPipeline);
 
   void UpdateResources(ResourceUpdateQueue& aUpdates);
 
   ResourceUpdateQueue& Resources() { return mResources; }
--- a/gfx/webrender_bindings/WebRenderTypes.h
+++ b/gfx/webrender_bindings/WebRenderTypes.h
@@ -582,16 +582,26 @@ struct ByteBuffer
       mOwned = true;
     } else {
       mOwned = false;
       mData = nullptr;
       mLength = 0;
     }
   }
 
+  ByteBuffer(ByteBuffer&& aFrom)
+  : mLength(aFrom.mLength)
+  , mData(aFrom.mData)
+  , mOwned(aFrom.mOwned)
+  {
+    aFrom.mLength = 0;
+    aFrom.mData = nullptr;
+    aFrom.mOwned = false;
+  }
+
   ByteBuffer()
     : mLength(0)
     , mData(nullptr)
     , mOwned(false)
   {}
 
   bool
   Allocate(size_t aLength)
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -10,16 +10,17 @@ use webrender::{ReadPixelsFormat, Render
 use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource};
 use webrender::DebugFlags;
 use webrender::{ApiRecordingReceiver, BinaryRecorder};
 use thread_profiler::register_thread_with_profiler;
 use moz2d_renderer::Moz2dImageRenderer;
 use app_units::Au;
 use rayon;
 use euclid::SideOffsets2D;
+use bincode;
 
 extern crate webrender_api;
 
 /// cbindgen:field-names=[mNamespace, mHandle]
 type WrExternalImageBufferType = ExternalImageType;
 
 /// cbindgen:field-names=[mHandle]
 /// cbindgen:derive-lt=true
@@ -960,16 +961,32 @@ pub extern "C" fn wr_resource_updates_ne
 #[no_mangle]
 pub extern "C" fn wr_resource_updates_delete(updates: *mut ResourceUpdates) {
     unsafe {
         Box::from_raw(updates);
     }
 }
 
 #[no_mangle]
+pub extern "C" fn wr_resource_updates_serialize(resources: &mut ResourceUpdates, into: &mut VecU8) {
+    let mut data = Vec::new();
+    bincode::serialize_into(&mut data, &resources.updates, bincode::Infinite).unwrap();
+    resources.updates.clear();
+    *into = data;
+}
+
+#[no_mangle]
+pub extern "C" fn wr_resource_updates_deserialize(data: ByteSlice) -> *mut ResourceUpdates {
+    let resources: Box<ResourceUpdates> = Box::new(
+        bincode::deserialize_from(&mut data.as_slice(), bincode::Infinite).expect("Invalid wr::ResourceUpdate serialization?")
+    );
+    Box::into_raw(resources)
+}
+
+#[no_mangle]
 pub unsafe extern "C" fn wr_api_get_namespace(dh: &mut DocumentHandle) -> WrIdNamespace {
     dh.api.get_namespace_id()
 }
 
 // RenderThread WIP notes:
 // In order to separate the compositor thread (or ipc receiver) and the render
 // thread, some of the logic below needs to be rewritten. In particular
 // the WrWindowState and Notifier implementations aren't designed to work with
--- a/gfx/webrender_bindings/src/lib.rs
+++ b/gfx/webrender_bindings/src/lib.rs
@@ -6,12 +6,13 @@
 
 extern crate webrender;
 extern crate webrender_api;
 extern crate euclid;
 extern crate app_units;
 extern crate gleam;
 extern crate rayon;
 extern crate thread_profiler;
+extern crate bincode;
 
 #[allow(non_snake_case)]
 pub mod bindings;
 pub mod moz2d_renderer;
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1220,20 +1220,29 @@ void wr_resource_updates_delete_font_ins
 WR_FUNC;
 
 WR_INLINE
 void wr_resource_updates_delete_image(ResourceUpdates *aResources,
                                       WrImageKey aKey)
 WR_FUNC;
 
 WR_INLINE
+ResourceUpdates *wr_resource_updates_deserialize(ByteSlice aData)
+WR_FUNC;
+
+WR_INLINE
 ResourceUpdates *wr_resource_updates_new()
 WR_FUNC;
 
 WR_INLINE
+void wr_resource_updates_serialize(ResourceUpdates *aResources,
+                                   VecU8 *aInto)
+WR_FUNC;
+
+WR_INLINE
 void wr_resource_updates_update_blob_image(ResourceUpdates *aResources,
                                            WrImageKey aImageKey,
                                            const WrImageDescriptor *aDescriptor,
                                            ByteSlice aBytes)
 WR_FUNC;
 
 WR_INLINE
 void wr_resource_updates_update_external_image(ResourceUpdates *aResources,
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -1022,19 +1022,19 @@ description = bug 1350634
 [PUiCompositorController::Pause]
 description =
 [PUiCompositorController::Resume]
 description =
 [PUiCompositorController::ResumeAndResize]
 description =
 [PWebRenderBridge::Create]
 description =
-[PWebRenderBridge::DPSyncEnd]
+[PWebRenderBridge::SetDisplayListSync]
 description =
-[PWebRenderBridge::DPGetSnapshot]
+[PWebRenderBridge::GetSnapshot]
 description =
 [PWebRenderBridge::SetTestSampleTime]
 description = test only
 [PWebRenderBridge::LeaveTestMode]
 description = test only
 [PWebRenderBridge::GetAnimationOpacity]
 description = test only
 [PWebRenderBridge::GetAnimationTransform]
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -1495,16 +1495,17 @@ dependencies = [
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender_bindings"
 version = "0.1.0"
 dependencies = [
  "app_units 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "webrender 0.50.0",
  "webrender_api 0.50.0",
 ]