Bug 1510899 - Try catch up composites with WR. r=jrmuizel,sotaro
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 29 Nov 2018 18:30:06 +0000
changeset 508067 55abd0f51161498eaa0c5a875895a54179c52b73
parent 508066 e0192f22b98385887f84b19a76170d42843d595b
child 508068 982d3f5bc88baf588df2ed03c8a7f6f34b3b4a74
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel, sotaro
bugs1510899
milestone65.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 1510899 - Try catch up composites with WR. r=jrmuizel,sotaro MozReview-Commit-ID: LXIpsvZZ96U Differential Revision: https://phabricator.services.mozilla.com/D13377
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/webrender_bindings/RenderThread.cpp
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -328,16 +328,17 @@ WebRenderBridgeParent::WebRenderBridgePa
   , mChildLayersObserverEpoch{0}
   , mParentLayersObserverEpoch{0}
   , mWrEpoch{0}
   , mIdNamespace(aApi->GetNamespace())
   , mPaused(false)
   , mDestroyed(false)
   , mReceivedDisplayList(false)
   , mIsFirstPaint(true)
+  , mSkippedComposite(false)
 {
   MOZ_ASSERT(mAsyncImageManager);
   MOZ_ASSERT(mAnimStorage);
   mAsyncImageManager->AddPipeline(mPipelineId, this);
   if (IsRootWebRenderBridgeParent()) {
     MOZ_ASSERT(!mCompositorScheduler);
     mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
   }
@@ -349,16 +350,17 @@ WebRenderBridgeParent::WebRenderBridgePa
   , mChildLayersObserverEpoch{0}
   , mParentLayersObserverEpoch{0}
   , mWrEpoch{0}
   , mIdNamespace{0}
   , mPaused(false)
   , mDestroyed(true)
   , mReceivedDisplayList(false)
   , mIsFirstPaint(false)
+  , mSkippedComposite(false)
 {
 }
 
 /* static */ WebRenderBridgeParent*
 WebRenderBridgeParent::CreateDestroyed(const wr::PipelineId& aPipelineId)
 {
   return new WebRenderBridgeParent(aPipelineId);
 }
@@ -1772,35 +1774,44 @@ WebRenderBridgeParent::SampleAnimations(
       }
     }
   }
 
   return isAnimating;
 }
 
 void
+WebRenderBridgeParent::CompositeIfNeeded()
+{
+  if (mSkippedComposite) {
+    mSkippedComposite = false;
+    CompositeToTarget(nullptr, nullptr);
+  }
+}
+
+void
 WebRenderBridgeParent::CompositeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect)
 {
   // This function should only get called in the root WRBP
   MOZ_ASSERT(IsRootWebRenderBridgeParent());
 
   // The two arguments are part of the CompositorVsyncSchedulerOwner API but in
   // this implementation they should never be non-null.
   MOZ_ASSERT(aTarget == nullptr);
   MOZ_ASSERT(aRect == nullptr);
 
   AUTO_PROFILER_TRACING("Paint", "CompositeToTarget");
   if (mPaused || !mReceivedDisplayList) {
     mPreviousFrameTimeStamp = TimeStamp();
     return;
   }
 
-  if (wr::RenderThread::Get()->TooManyPendingFrames(mApi->GetId())) {
+  if (mSkippedComposite || wr::RenderThread::Get()->TooManyPendingFrames(mApi->GetId())) {
     // Render thread is busy, try next time.
-    mCompositorScheduler->ScheduleComposition();
+    mSkippedComposite = true;
     mPreviousFrameTimeStamp = TimeStamp();
 
     // Record that we skipped presenting a frame for
     // all pending transactions that have finished scene building.
     for (auto& id : mPendingTransactionIds) {
       if (id.mSceneBuiltTime) {
         id.mSkippedComposites++;
       }
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -175,16 +175,18 @@ public:
                                             const TimeStamp& aCompositeStartTime,
                                             const TimeStamp& aRenderStartTime,
                                             const TimeStamp& aEndTime,
                                             UiCompositorControllerParent* aUiController,
                                             wr::RendererStats* aStats = nullptr,
                                             nsTArray<FrameStats>* aOutputStats = nullptr);
   void NotifySceneBuiltForEpoch(const wr::Epoch& aEpoch, const TimeStamp& aEndTime);
 
+  void CompositeIfNeeded();
+
   TextureFactoryIdentifier GetTextureFactoryIdentifier();
 
   void ExtractImageCompositeNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications);
 
   wr::Epoch GetCurrentEpoch() const { return mWrEpoch; }
   wr::IdNamespace GetIdNamespace()
   {
     return mIdNamespace;
@@ -380,14 +382,15 @@ private:
   std::queue<CompositorAnimationIdsForEpoch> mCompositorAnimationsToDelete;
   wr::Epoch mWrEpoch;
   wr::IdNamespace mIdNamespace;
 
   bool mPaused;
   bool mDestroyed;
   bool mReceivedDisplayList;
   bool mIsFirstPaint;
+  bool mSkippedComposite;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // mozilla_layers_WebRenderBridgeParent_h
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -361,16 +361,20 @@ NotifyDidRender(layers::CompositorBridge
     aBridge->NotifyPipelineRendered(
         info.epochs.data[i].pipeline_id,
         info.epochs.data[i].epoch,
         aCompositeStart,
         aRenderStart,
         aEnd,
         &aStats);
   }
+
+  if (aBridge->GetWrBridge()) {
+    aBridge->GetWrBridge()->CompositeIfNeeded();
+  }
 }
 
 void
 RenderThread::UpdateAndRender(wr::WindowId aWindowId,
                               const TimeStamp& aStartTime,
                               bool aRender,
                               const Maybe<gfx::IntSize>& aReadbackSize,
                               const Maybe<Range<uint8_t>>& aReadbackBuffer,