Bug 1459714 - Use a single transaction for all things associated with a new display list. r?sotaro draft
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 08 May 2018 08:49:44 -0400
changeset 792472 39663dff16cad617b1747100f1ca732369efce03
parent 792471 df7e70b8723b8eba042df014a110aef24c99ebc4
push id109112
push userkgupta@mozilla.com
push dateTue, 08 May 2018 12:50:51 +0000
reviewerssotaro
bugs1459714
milestone62.0a1
Bug 1459714 - Use a single transaction for all things associated with a new display list. r?sotaro This ensures the commands to delete compositables are received by WR in the same transaction as the updates to the display list that removes the references to those compositables. Otherwise, WR can try to do a scene build on the intermediate state which results in missing pipeline errors. MozReview-Commit-ID: ByOHCFWSSjt
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/webrender_bindings/WebRenderAPI.h
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -614,18 +614,19 @@ WebRenderBridgeParent::RecvSetDisplayLis
   // to early-return from RecvDPEnd without doing so.
   AutoWebRenderBridgeParentAsyncMessageSender autoAsyncMessageSender(this, &aToDestroy);
 
   wr::Epoch wrEpoch = GetNextWrEpoch();
 
   mAsyncImageManager->SetCompositionTime(TimeStamp::Now());
 
   wr::TransactionBuilder txn;
+  wr::AutoTransactionSender sender(mApi, &txn);
+
   ProcessWebRenderParentCommands(aCommands, txn);
-  mApi->SendTransaction(txn);
 
   if (!UpdateResources(aResourceUpdates, aSmallShmems, aLargeShmems, txn)) {
     return IPC_FAIL(this, "Failed to deserialize resource updates");
   }
 
   mReceivedDisplayList = true;
 
   // aScrollData is moved into this function but that is not reflected by the
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -232,16 +232,40 @@ protected:
   // for each document).
   RefPtr<wr::WebRenderAPI> mRootApi;
   RefPtr<wr::WebRenderAPI> mRootDocumentApi;
 
   friend class DisplayListBuilder;
   friend class layers::WebRenderBridgeParent;
 };
 
+// This is a RAII class that automatically sends the transaction on
+// destruction. This is useful for code that has multiple exit points and we
+// want to ensure that the stuff accumulated in the transaction gets sent
+// regardless of which exit we take. Note that if the caller explicitly calls
+// mApi->SendTransaction() that's fine too because that empties out the
+// TransactionBuilder and leaves it as a valid empty transaction, so calling
+// SendTransaction on it again ends up being a no-op.
+class MOZ_RAII AutoTransactionSender
+{
+public:
+  AutoTransactionSender(WebRenderAPI* aApi, TransactionBuilder* aTxn)
+    : mApi(aApi)
+    , mTxn(aTxn)
+  {}
+
+  ~AutoTransactionSender() {
+    mApi->SendTransaction(*mTxn);
+  }
+
+private:
+  WebRenderAPI* mApi;
+  TransactionBuilder* mTxn;
+};
+
 /// This is a simple C++ wrapper around WrState defined in the rust bindings.
 /// We may want to turn this into a direct wrapper on top of WebRenderFrameBuilder
 /// instead, so the interface may change a bit.
 class DisplayListBuilder {
 public:
   explicit DisplayListBuilder(wr::PipelineId aId,
                               const wr::LayoutSize& aContentSize,
                               size_t aCapacity = 0);