Skip to content

Commit a01e994

Browse files
committed
Bug 1982053 - Don't remove pipelines in offscreen transactions. r=emilio
When the async pipeline of a video is removed or swapped, we change the display list that references it and remove the video's pipeline. Unfortunately when we are dealing with an offscreen transaction, the later can race ahead and cause the pipeline to be removed before it is un-referenced from the main display list. If anthing triggers a scene build between the offscreen transaction and the next main transaction, we get a missing pipeline crash. This patch fixes it by only pusing destroy operations to the transaction if it isn't offscreen. Differential Revision: https://phabricator.services.mozilla.com/D261087
1 parent 8bb39cb commit a01e994

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

gfx/layers/wr/WebRenderBridgeChild.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,16 @@ void WebRenderBridgeChild::AddWebRenderParentCommand(
7676
mParentCommands.AppendElement(aCmd);
7777
}
7878

79+
void WebRenderBridgeChild::AddWebRenderParentDestroyCommand(
80+
const WebRenderParentCommand& aCmd) {
81+
mParentDestroyCommands.AppendElement(aCmd);
82+
}
83+
84+
void WebRenderBridgeChild::MergeWebRenderParentCommands() {
85+
mParentCommands.AppendElements(std::move(mParentDestroyCommands));
86+
mParentDestroyCommands.Clear();
87+
}
88+
7989
void WebRenderBridgeChild::BeginTransaction() {
8090
MOZ_ASSERT(!mDestroyed);
8191

@@ -114,6 +124,9 @@ bool WebRenderBridgeChild::EndTransaction(
114124

115125
TimeStamp fwdTime = TimeStamp::Now();
116126

127+
if (!aRenderOffscreen) {
128+
MergeWebRenderParentCommands();
129+
}
117130
aDisplayListData.mCommands = std::move(mParentCommands);
118131
aDisplayListData.mIdNamespace = mIdNamespace;
119132

@@ -151,6 +164,7 @@ void WebRenderBridgeChild::EndEmptyTransaction(
151164
TimeStamp fwdTime = TimeStamp::Now();
152165

153166
if (aTransactionData) {
167+
MergeWebRenderParentCommands();
154168
aTransactionData->mCommands = std::move(mParentCommands);
155169
}
156170

@@ -175,7 +189,8 @@ void WebRenderBridgeChild::EndEmptyTransaction(
175189
void WebRenderBridgeChild::ProcessWebRenderParentCommands() {
176190
MOZ_ASSERT(!mDestroyed);
177191

178-
if (!mParentCommands.IsEmpty()) {
192+
if (HasWebRenderParentCommands()) {
193+
MergeWebRenderParentCommands();
179194
this->SendParentCommands(mIdNamespace, mParentCommands);
180195
mParentCommands.Clear();
181196
}
@@ -190,7 +205,8 @@ void WebRenderBridgeChild::AddPipelineIdForCompositable(
190205

191206
void WebRenderBridgeChild::RemovePipelineIdForCompositable(
192207
const wr::PipelineId& aPipelineId) {
193-
AddWebRenderParentCommand(OpRemovePipelineIdForCompositable(aPipelineId));
208+
AddWebRenderParentDestroyCommand(
209+
OpRemovePipelineIdForCompositable(aPipelineId));
194210
}
195211

196212
wr::ExternalImageId WebRenderBridgeChild::GetNextExternalImageId() {
@@ -201,7 +217,7 @@ wr::ExternalImageId WebRenderBridgeChild::GetNextExternalImageId() {
201217
}
202218

203219
void WebRenderBridgeChild::ReleaseTextureOfImage(const wr::ImageKey& aKey) {
204-
AddWebRenderParentCommand(OpReleaseTextureOfImage(aKey));
220+
AddWebRenderParentDestroyCommand(OpReleaseTextureOfImage(aKey));
205221
}
206222

207223
struct FontFileDataSink {
@@ -412,7 +428,7 @@ void WebRenderBridgeChild::RemoveTextureFromCompositable(
412428
return;
413429
}
414430

415-
AddWebRenderParentCommand(CompositableOperation(
431+
AddWebRenderParentDestroyCommand(CompositableOperation(
416432
aCompositable->GetIPCHandle(),
417433
OpRemoveTexture(WrapNotNull(aTexture->GetIPDLActor()))));
418434
}

gfx/layers/wr/WebRenderBridgeChild.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,14 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
6565
explicit WebRenderBridgeChild(const wr::PipelineId& aPipelineId);
6666

6767
void AddWebRenderParentCommand(const WebRenderParentCommand& aCmd);
68-
bool HasWebRenderParentCommands() { return !mParentCommands.IsEmpty(); }
68+
/// Similar to AddWebRenderParentCommand, with the exception that ops are not
69+
/// picked up by off-screen transactions. Typically useful for operations that
70+
/// remove resources and should not be applied before we have un-referenced
71+
/// the resources from the main display list.
72+
void AddWebRenderParentDestroyCommand(const WebRenderParentCommand& aCmd);
73+
bool HasWebRenderParentCommands() {
74+
return !mParentCommands.IsEmpty() || !mParentDestroyCommands.IsEmpty();
75+
}
6976

7077
void UpdateResources(wr::IpcResourceUpdateQueue& aResources);
7178
void BeginTransaction();
@@ -190,6 +197,8 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
190197

191198
~WebRenderBridgeChild();
192199

200+
void MergeWebRenderParentCommands();
201+
193202
wr::ExternalImageId GetNextExternalImageId();
194203

195204
// CompositableForwarder
@@ -236,6 +245,7 @@ class WebRenderBridgeChild final : public PWebRenderBridgeChild,
236245

237246
nsTArray<OpDestroy> mDestroyedActors;
238247
nsTArray<WebRenderParentCommand> mParentCommands;
248+
nsTArray<WebRenderParentCommand> mParentDestroyCommands;
239249
nsTHashMap<nsUint64HashKey, CompositableClient*> mCompositables;
240250
bool mIsInTransaction;
241251
bool mIsInClearCachedResources;

0 commit comments

Comments
 (0)