Bug 1455597 - Flush the transaction to remove the pipeline before shutting down the WebRenderAPI. r?sotaro
MozReview-Commit-ID: GuQJjMzzQUE
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -492,26 +492,32 @@ CompositorBridgeParent::StopAndClearReso
lts->mParent = nullptr;
});
mLayerManager->Destroy();
mLayerManager = nullptr;
mCompositionManager = nullptr;
}
if (mWrBridge) {
+ // Ensure we are not holding the sIndirectLayerTreesLock when destroying
+ // the WebRenderBridgeParent instances because it may block on WR.
+ std::vector<RefPtr<WebRenderBridgeParent>> indirectBridgeParents;
{ // scope lock
MonitorAutoLock lock(*sIndirectLayerTreesLock);
- ForEachIndirectLayerTree([] (LayerTreeState* lts, LayersId) -> void {
+ ForEachIndirectLayerTree([&] (LayerTreeState* lts, LayersId) -> void {
if (lts->mWrBridge) {
- lts->mWrBridge->Destroy();
- lts->mWrBridge = nullptr;
+ indirectBridgeParents.emplace_back(lts->mWrBridge.forget());
}
lts->mParent = nullptr;
});
}
+ for (const RefPtr<WebRenderBridgeParent>& bridge : indirectBridgeParents) {
+ bridge->Destroy();
+ }
+ indirectBridgeParents.clear();
// Ensure we are not holding the sIndirectLayerTreesLock here because we
// are going to block on WR threads in order to shut it down properly.
mWrBridge->Destroy();
mWrBridge = nullptr;
if (mAsyncImageManager) {
mAsyncImageManager->Destroy();
// WebRenderAPI should be already destructed
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -1610,16 +1610,24 @@ WebRenderBridgeParent::ClearResources()
mAnimStorage->ClearById(*iter);
}
mActiveAnimations.clear();
std::queue<CompositorAnimationIdsForEpoch>().swap(mCompositorAnimationsToDelete); // clear queue
if (mWidget) {
mCompositorScheduler->Destroy();
}
+
+ // Before tearing down mApi we should make sure the above transaction has been
+ // flushed back to the render backend thread. Otherwise the cleanup messages
+ // that the WebRenderAPI destructor triggers can race ahead of the transaction
+ // (because it goes directly to the RB thread, bypassing the scene builder
+ // thread) and clear caches etc. that are still in use.
+ FlushSceneBuilds();
+
mAnimStorage = nullptr;
mCompositorScheduler = nullptr;
mAsyncImageManager = nullptr;
mApi = nullptr;
mCompositorBridge = nullptr;
}
bool