Bug 1363958 - Fix WebRenderLayerManager::FlushRendering() r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Fri, 02 Jun 2017 08:07:59 +0900
changeset 361979 63cd7aaf05d865a5ffc030a3c336b4cec40f45f2
parent 361978 b0e196c8fcd770b9ce8be81ff0fbcffabc7b8808
child 361980 a9f2f087d8242123e8d3f44d64e3f68d910903bb
push id31953
push usercbook@mozilla.com
push dateFri, 02 Jun 2017 12:22:33 +0000
treeherdermozilla-central@2a8478029a0c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1363958
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1363958 - Fix WebRenderLayerManager::FlushRendering() r=nical
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/webrender_bindings/WebRenderAPI.h
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -527,26 +527,36 @@ mozilla::ipc::IPCResult
 CompositorBridgeParent::RecvWaitOnTransactionProcessed()
 {
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 CompositorBridgeParent::RecvFlushRendering()
 {
+  if (gfxVars::UseWebRender()) {
+    mWrBridge->FlushRendering(/* aSync */ true);
+    return IPC_OK();
+  }
+
   if (mCompositorScheduler->NeedsComposite()) {
     CancelCurrentCompositeTask();
     ForceComposeToTarget(nullptr);
   }
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 CompositorBridgeParent::RecvFlushRenderingAsync()
 {
+  if (gfxVars::UseWebRender()) {
+    mWrBridge->FlushRendering(/* aSync */ false);
+    return IPC_OK();
+  }
+
   return RecvFlushRendering();
 }
 
 mozilla::ipc::IPCResult
 CompositorBridgeParent::RecvForcePresent()
 {
   // During the shutdown sequence mLayerManager may be null
   if (mLayerManager) {
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -118,17 +118,17 @@ WebRenderBridgeParent::WebRenderBridgePa
   , mCompositableHolder(aHolder)
   , mCompositorScheduler(aScheduler)
   , mChildLayerObserverEpoch(0)
   , mParentLayerObserverEpoch(0)
   , mWrEpoch(0)
   , mIdNameSpace(AllocIdNameSpace())
   , mPaused(false)
   , mDestroyed(false)
-  , mIsSnapshotting(false)
+  , mForceRendering(false)
 {
   MOZ_ASSERT(mCompositableHolder);
   mCompositableHolder->AddPipeline(mPipelineId);
   if (mWidget) {
     MOZ_ASSERT(!mCompositorScheduler);
     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
   }
 }
@@ -613,26 +613,26 @@ WebRenderBridgeParent::RecvDPGetSnapshot
   // We only support B8G8R8A8 for now.
   MOZ_ASSERT(buffer);
   MOZ_ASSERT(bufferTexture->GetFormat() == SurfaceFormat::B8G8R8A8);
   uint32_t buffer_size = size.width * size.height * 4;
 
   // 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();
     mCompositorScheduler->ForceComposeToTarget(nullptr, nullptr);
   }
 
   mApi->Readback(size, buffer, buffer_size);
 
-  mIsSnapshotting = false;
+  mForceRendering = false;
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 WebRenderBridgeParent::RecvAddExternalImageId(const ExternalImageId& aImageId,
                                               const CompositableHandle& aHandle)
 {
@@ -817,17 +817,17 @@ void
 WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
   if (mPaused) {
     return;
   }
 
   const uint32_t maxPendingFrameCount = 2;
 
-  if (!mIsSnapshotting &&
+  if (!mForceRendering &&
       wr::RenderThread::Get()->GetPendingFrameCount(mApi->GetId()) > maxPendingFrameCount) {
     // Render thread is busy, try next time.
     ScheduleComposition();
     return;
   }
 
   bool scheduleComposite = false;
   nsTArray<WrOpacityProperty> opacityArray;
@@ -934,16 +934,36 @@ void
 WebRenderBridgeParent::ScheduleComposition()
 {
   if (mCompositorScheduler) {
     mCompositorScheduler->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()
 {
   MOZ_ASSERT(mWidget);
 #ifdef MOZ_WIDGET_ANDROID
   if (!mWidget || mDestroyed) {
     return;
   }
   mApi->Pause();
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -172,16 +172,18 @@ public:
 
   void UpdateAPZ();
   const WebRenderScrollData& GetScrollData() const;
 
   static uint32_t AllocIdNameSpace() {
     return ++sIdNameSpace;
   }
 
+  void FlushRendering(bool aIsSync);
+
 private:
   virtual ~WebRenderBridgeParent();
 
   uint64_t GetLayersId() const;
   void DeleteOldImages();
   void ProcessWebRenderCommands(const gfx::IntSize &aSize,
                                 InfallibleTArray<WebRenderParentCommand>& commands,
                                 const wr::Epoch& aEpoch,
@@ -247,17 +249,17 @@ private:
   uint64_t mParentLayerObserverEpoch;
 
   std::queue<PendingTransactionId> mPendingTransactionIds;
   uint32_t mWrEpoch;
   uint32_t mIdNameSpace;
 
   bool mPaused;
   bool mDestroyed;
-  bool mIsSnapshotting;
+  bool mForceRendering;
 
   // Can only be accessed on the compositor thread.
   WebRenderScrollData mScrollData;
 
   static uint32_t sIdNameSpace;
 };
 
 } // namespace layers
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -459,19 +459,26 @@ void
 WebRenderLayerManager::RemoveDidCompositeObserver(DidCompositeObserver* aObserver)
 {
   mDidCompositeObservers.RemoveElement(aObserver);
 }
 
 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();
   }
 }
 
 void
 WebRenderLayerManager::WaitOnTransactionProcessed()
 {
   CompositorBridgeChild* bridge = GetCompositorBridgeChild();
   if (bridge) {
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -18,16 +18,17 @@
 namespace mozilla {
 
 namespace widget {
 class CompositorWidget;
 }
 
 namespace layers {
 class CompositorBridgeParentBase;
+class WebRenderBridgeParent;
 }
 
 namespace wr {
 
 class DisplayListBuilder;
 class RendererOGL;
 class RendererEvent;
 
@@ -120,16 +121,17 @@ protected:
   void WaitFlushed();
 
   WrAPI* mWrApi;
   wr::WindowId mId;
   GLint mMaxTextureSize;
   bool mUseANGLE;
 
   friend class DisplayListBuilder;
+  friend class layers::WebRenderBridgeParent;
 };
 
 /// 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,