From e155c862e7230be8d057a08dc5f5465250d85020 Mon Sep 17 00:00:00 2001 From: sotaro Date: Fri, 2 Jun 2017 08:07:59 +0900 Subject: [PATCH] Bug 1363958 - Fix WebRenderLayerManager::FlushRendering() r=nical --- gfx/layers/ipc/CompositorBridgeParent.cpp | 10 ++++++++ gfx/layers/wr/WebRenderBridgeParent.cpp | 28 +++++++++++++++++++---- gfx/layers/wr/WebRenderBridgeParent.h | 4 +++- gfx/layers/wr/WebRenderLayerManager.cpp | 13 ++++++++--- gfx/webrender_bindings/WebRenderAPI.h | 2 ++ 5 files changed, 49 insertions(+), 8 deletions(-) diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp index 5b518ea8ae18..c884bb88ec16 100644 --- a/gfx/layers/ipc/CompositorBridgeParent.cpp +++ b/gfx/layers/ipc/CompositorBridgeParent.cpp @@ -532,6 +532,11 @@ CompositorBridgeParent::RecvWaitOnTransactionProcessed() mozilla::ipc::IPCResult CompositorBridgeParent::RecvFlushRendering() { + if (gfxVars::UseWebRender()) { + mWrBridge->FlushRendering(/* aSync */ true); + return IPC_OK(); + } + if (mCompositorScheduler->NeedsComposite()) { CancelCurrentCompositeTask(); ForceComposeToTarget(nullptr); @@ -542,6 +547,11 @@ CompositorBridgeParent::RecvFlushRendering() mozilla::ipc::IPCResult CompositorBridgeParent::RecvFlushRenderingAsync() { + if (gfxVars::UseWebRender()) { + mWrBridge->FlushRendering(/* aSync */ false); + return IPC_OK(); + } + return RecvFlushRendering(); } diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index c525b55f6c72..a16b52055e1d 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -123,7 +123,7 @@ WebRenderBridgeParent::WebRenderBridgeParent(CompositorBridgeParentBase* aCompos , mIdNameSpace(AllocIdNameSpace()) , mPaused(false) , mDestroyed(false) - , mIsSnapshotting(false) + , mForceRendering(false) { MOZ_ASSERT(mCompositableHolder); mCompositableHolder->AddPipeline(mPipelineId); @@ -618,7 +618,7 @@ WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture) // Assert the stride of the buffer is what webrender expects MOZ_ASSERT((uint32_t)(size.width * 4) == stride); - mIsSnapshotting = true; + mForceRendering = true; if (mCompositorScheduler->NeedsComposite()) { mCompositorScheduler->CancelCurrentCompositeTask(); @@ -627,7 +627,7 @@ WebRenderBridgeParent::RecvDPGetSnapshot(PTextureParent* aTexture) mApi->Readback(size, buffer, buffer_size); - mIsSnapshotting = false; + mForceRendering = false; return IPC_OK(); } @@ -822,7 +822,7 @@ WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::In const uint32_t maxPendingFrameCount = 2; - if (!mIsSnapshotting && + if (!mForceRendering && wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) > maxPendingFrameCount) { // Render thread is busy, try next time. ScheduleComposition(); @@ -938,6 +938,26 @@ WebRenderBridgeParent::ScheduleComposition() } } +void +WebRenderBridgeParent::FlushRendering(bool aIsSync) +{ + if (mDestroyed) { + return; + } + + if (!mCompositorScheduler->NeedsComposite()) { + return; + } + + mForceRendering = true; + mCompositorScheduler->CancelCurrentCompositeTask(); + mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr); + if (aIsSync) { + mApi->WaitFlushed(); + } + mForceRendering = false; +} + void WebRenderBridgeParent::Pause() { diff --git a/gfx/layers/wr/WebRenderBridgeParent.h b/gfx/layers/wr/WebRenderBridgeParent.h index 09af6ebad670..269a38f66153 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.h +++ b/gfx/layers/wr/WebRenderBridgeParent.h @@ -177,6 +177,8 @@ public: return ++sIdNameSpace; } + void FlushRendering(bool aIsSync); + private: virtual ~WebRenderBridgeParent(); @@ -252,7 +254,7 @@ private: bool mPaused; bool mDestroyed; - bool mIsSnapshotting; + bool mForceRendering; // Can only be accessed on the compositor thread. WebRenderScrollData mScrollData; diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index ec4d6cd5c91f..5c55eb48d88f 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -464,9 +464,16 @@ WebRenderLayerManager::RemoveDidCompositeObserver(DidCompositeObserver* aObserve void WebRenderLayerManager::FlushRendering() { - CompositorBridgeChild* bridge = GetCompositorBridgeChild(); - if (bridge) { - bridge->SendFlushRendering(); + CompositorBridgeChild* cBridge = GetCompositorBridgeChild(); + if (!cBridge) { + return; + } + MOZ_ASSERT(mWidget); + + if (mWidget->SynchronouslyRepaintOnResize() || gfxPrefs::LayersForceSynchronousResize()) { + cBridge->SendFlushRendering(); + } else { + cBridge->SendFlushRenderingAsync(); } } diff --git a/gfx/webrender_bindings/WebRenderAPI.h b/gfx/webrender_bindings/WebRenderAPI.h index 5b8e6d2fac86..ea72b897fa72 100644 --- a/gfx/webrender_bindings/WebRenderAPI.h +++ b/gfx/webrender_bindings/WebRenderAPI.h @@ -23,6 +23,7 @@ class CompositorWidget; namespace layers { class CompositorBridgeParentBase; +class WebRenderBridgeParent; } namespace wr { @@ -125,6 +126,7 @@ protected: bool mUseANGLE; friend class DisplayListBuilder; + friend class layers::WebRenderBridgeParent; }; /// This is a simple C++ wrapper around WrState defined in the rust bindings.