diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index e77157236564..506c00e26d4c 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -1841,12 +1841,14 @@ CompositorBridgeParent::DidComposite(TimeStamp& aCompositeStart, void CompositorBridgeParent::NotifyDidCompositeToPipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) { + if (!mWrBridge) { + return; + } + mWrBridge->CompositableHolder()->Update(aPipelineId, aEpoch); + if (mPaused) { return; } - MOZ_ASSERT(mWrBridge); - - mWrBridge->CompositableHolder()->Update(aPipelineId, aEpoch); if (mWrBridge->PipelineId() == aPipelineId) { uint64_t transactionId = mWrBridge->FlushTransactionIdsForEpoch(aEpoch); diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index a88d859e3fa5..306a23bdc5df 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -863,26 +863,26 @@ WebRenderBridgeParent::Resume() void WebRenderBridgeParent::ClearResources() { - if (mApi) { - ++mWrEpoch; // Update webrender epoch - mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId); - for (auto iter = mActiveKeys.Iter(); !iter.Done(); iter.Next()) { - mKeysToDelete.push_back(iter.Data()); - iter.Remove(); - } - if (!mKeysToDelete.empty()) { - // XXX Sync wait. - mApi->WaitFlushed(); - DeleteOldImages(); - } + if (!mApi) { + return; } + + ++mWrEpoch; // Update webrender epoch + mApi->ClearRootDisplayList(wr::NewEpoch(mWrEpoch), mPipelineId); + // Schedule composition to clean up Pipeline + mCompositorScheduler->ScheduleComposition(); + for (auto iter = mActiveKeys.Iter(); !iter.Done(); iter.Next()) { + mKeysToDelete.push_back(iter.Data()); + iter.Remove(); + } + DeleteOldImages(); for (auto iter = mExternalImageIds.Iter(); !iter.Done(); iter.Next()) { iter.Data()->SetWrBridge(nullptr); } mExternalImageIds.Clear(); - mCompositableHolder->RemovePipeline(mPipelineId); + mCompositableHolder->RemovePipeline(mPipelineId, wr::NewEpoch(mWrEpoch)); - if (mWidget && mCompositorScheduler) { + if (mWidget) { mCompositorScheduler->Destroy(); } mCompositorScheduler = nullptr; diff --git a/gfx/layers/wr/WebRenderCompositableHolder.cpp b/gfx/layers/wr/WebRenderCompositableHolder.cpp index 59807772ba47..9c91e7648802 100644 --- a/gfx/layers/wr/WebRenderCompositableHolder.cpp +++ b/gfx/layers/wr/WebRenderCompositableHolder.cpp @@ -8,6 +8,7 @@ #include "CompositableHost.h" #include "mozilla/layers/WebRenderImageHost.h" #include "mozilla/layers/WebRenderTextureHost.h" +#include "mozilla/webrender/WebRenderAPI.h" namespace mozilla { @@ -25,7 +26,6 @@ WebRenderCompositableHolder::WebRenderCompositableHolder(uint32_t aIdNamespace) WebRenderCompositableHolder::~WebRenderCompositableHolder() { MOZ_COUNT_DTOR(WebRenderCompositableHolder); - MOZ_ASSERT(mPipelineTexturesHolders.IsEmpty()); } void @@ -39,18 +39,22 @@ WebRenderCompositableHolder::AddPipeline(const wr::PipelineId& aPipelineId) } void -WebRenderCompositableHolder::RemovePipeline(const wr::PipelineId& aPipelineId) +WebRenderCompositableHolder::RemovePipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch) { - uint64_t id = wr::AsUint64(aPipelineId); - if (mPipelineTexturesHolders.Get(id)) { - mPipelineTexturesHolders.Remove(id); + PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId)); + MOZ_ASSERT(holder); + if (!holder) { + return; } + MOZ_ASSERT(holder->mDestroyedEpoch.isNothing()); + holder->mDestroyedEpoch = Some(aEpoch); } void WebRenderCompositableHolder::HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture) { MOZ_ASSERT(aTexture); + PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId)); MOZ_ASSERT(holder); if (!holder) { @@ -64,10 +68,17 @@ void WebRenderCompositableHolder::Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch) { PipelineTexturesHolder* holder = mPipelineTexturesHolders.Get(wr::AsUint64(aPipelineId)); - if (!holder || holder->mTextureHosts.empty()) { + if (!holder) { return; } + // Remove Pipeline + if (holder->mDestroyedEpoch.isSome() && holder->mDestroyedEpoch.ref() <= aEpoch) { + mPipelineTexturesHolders.Remove(wr::AsUint64(aPipelineId)); + return; + } + + // Release TextureHosts based on Epoch while (!holder->mTextureHosts.empty()) { if (aEpoch <= holder->mTextureHosts.front().mEpoch) { break; diff --git a/gfx/layers/wr/WebRenderCompositableHolder.h b/gfx/layers/wr/WebRenderCompositableHolder.h index 98fac30001f1..a8e89a7aff06 100644 --- a/gfx/layers/wr/WebRenderCompositableHolder.h +++ b/gfx/layers/wr/WebRenderCompositableHolder.h @@ -9,6 +9,7 @@ #include #include "mozilla/layers/TextureHost.h" +#include "mozilla/Maybe.h" #include "mozilla/webrender/WebRenderTypes.h" #include "nsClassHashtable.h" @@ -35,7 +36,7 @@ protected: public: void AddPipeline(const wr::PipelineId& aPipelineId); - void RemovePipeline(const wr::PipelineId& aPipelineId); + void RemovePipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch); void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture); void Update(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch); @@ -61,9 +62,9 @@ public: uint32_t GetNextResourceId() { return ++mResourceId; } uint32_t GetNamespace() { return mIdNamespace; } - WrImageKey GetImageKey() + wr::ImageKey GetImageKey() { - WrImageKey key; + wr::ImageKey key; key.mNamespace = GetNamespace(); key.mHandle = GetNextResourceId(); return key; @@ -83,6 +84,7 @@ private: struct PipelineTexturesHolder { // Holds forwarding WebRenderTextureHosts. std::queue mTextureHosts; + Maybe mDestroyedEpoch; }; uint32_t mIdNamespace; diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index b56e35baf113..8d37e9dc8404 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -23,7 +23,6 @@ class CompositorWidget; namespace layers { class CompositorBridgeParentBase; -class WebRenderBridgeParent; } namespace wr { @@ -124,7 +123,6 @@ protected: bool mUseANGLE; friend class DisplayListBuilder; - friend class layers::WebRenderBridgeParent; }; /// This is a simple C++ wrapper around WrState defined in the rust bindings.