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
--- 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);