Bug 1456978 - Ensure that all generate_frame transactions end up clearing the pending frame count. r?sotaro draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 27 Apr 2018 07:41:03 -0400
changeset 789027 fde3cf26e68f7bf8847e63ec4d2c1ffab9ac119b
parent 789026 f47cffd517195527051d4409e103b45774fff62c
push id108135
push userkgupta@mozilla.com
push dateFri, 27 Apr 2018 11:41:59 +0000
reviewerssotaro
bugs1456978
milestone61.0a1
Bug 1456978 - Ensure that all generate_frame transactions end up clearing the pending frame count. r?sotaro This prevents us from getting stuck in the frame throttling code where TooManyPendingFrames always returns true. MozReview-Commit-ID: 92tybPOaOTP
gfx/webrender_bindings/RenderThread.cpp
gfx/webrender_bindings/RenderThread.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -379,16 +379,35 @@ RenderThread::IncPendingFrameCount(wr::W
     return;
   }
   // Update pending frame count.
   info.mPendingCount = info.mPendingCount + 1;
   mWindowInfos.Put(AsUint64(aWindowId), info);
 }
 
 void
+RenderThread::DecPendingFrameCount(wr::WindowId aWindowId)
+{
+  MutexAutoLock lock(mFrameCountMapLock);
+  // Get the old count.
+  WindowInfo info;
+  if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
+    MOZ_ASSERT(false);
+    return;
+  }
+  MOZ_ASSERT(info.mPendingCount > 0);
+  if (info.mPendingCount <= 0) {
+    return;
+  }
+  // Update pending frame count.
+  info.mPendingCount = info.mPendingCount - 1;
+  mWindowInfos.Put(AsUint64(aWindowId), info);
+}
+
+void
 RenderThread::IncRenderingFrameCount(wr::WindowId aWindowId)
 {
   MutexAutoLock lock(mFrameCountMapLock);
   // Get the old count.
   WindowInfo info;
   if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
     MOZ_ASSERT(false);
     return;
@@ -531,25 +550,19 @@ void wr_notifier_wake_up(mozilla::wr::Wr
   mozilla::wr::RenderThread::Get()->WakeUp(aWindowId);
 }
 
 void wr_notifier_new_frame_ready(mozilla::wr::WrWindowId aWindowId)
 {
   NewFrameReady(aWindowId);
 }
 
-void wr_notifier_new_scroll_frame_ready(mozilla::wr::WrWindowId aWindowId, bool aCompositeNeeded)
+void wr_notifier_nop_frame_done(mozilla::wr::WrWindowId aWindowId)
 {
-  // If we sent a transaction that contained both scrolling updates and a
-  // GenerateFrame, we can get this function called with aCompositeNeeded=true
-  // instead of wr_notifier_new_frame_ready. In that case we want to update the
-  // rendering.
-  if (aCompositeNeeded) {
-    NewFrameReady(aWindowId);
-  }
+  mozilla::wr::RenderThread::Get()->DecPendingFrameCount(aWindowId);
 }
 
 void wr_notifier_external_event(mozilla::wr::WrWindowId aWindowId, size_t aRawEvent)
 {
   mozilla::UniquePtr<mozilla::wr::RendererEvent> evt(
     reinterpret_cast<mozilla::wr::RendererEvent*>(aRawEvent));
   mozilla::wr::RenderThread::Get()->RunEvent(mozilla::wr::WindowId(aWindowId),
                                              mozilla::Move(evt));
--- a/gfx/webrender_bindings/RenderThread.h
+++ b/gfx/webrender_bindings/RenderThread.h
@@ -148,16 +148,18 @@ public:
   bool IsDestroyed(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void SetDestroyed(wr::WindowId aWindowId);
   /// Can be called from any thread.
   bool TooManyPendingFrames(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void IncPendingFrameCount(wr::WindowId aWindowId);
   /// Can be called from any thread.
+  void DecPendingFrameCount(wr::WindowId aWindowId);
+  /// Can be called from any thread.
   void IncRenderingFrameCount(wr::WindowId aWindowId);
   /// Can be called from any thread.
   void FrameRenderingComplete(wr::WindowId aWindowId);
 
   /// Can be called from any thread.
   WebRenderThreadPool& ThreadPool() { return mThreadPool; }
 
   /// Can only be called from the render thread.
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -490,18 +490,17 @@ struct CppNotifier {
     window_id: WrWindowId,
 }
 
 unsafe impl Send for CppNotifier {}
 
 extern "C" {
     fn wr_notifier_wake_up(window_id: WrWindowId);
     fn wr_notifier_new_frame_ready(window_id: WrWindowId);
-    fn wr_notifier_new_scroll_frame_ready(window_id: WrWindowId,
-                                          composite_needed: bool);
+    fn wr_notifier_nop_frame_done(window_id: WrWindowId);
     fn wr_notifier_external_event(window_id: WrWindowId,
                                   raw_event: usize);
 }
 
 impl RenderNotifier for CppNotifier {
     fn clone(&self) -> Box<RenderNotifier> {
         Box::new(CppNotifier {
             window_id: self.window_id,
@@ -511,23 +510,23 @@ impl RenderNotifier for CppNotifier {
     fn wake_up(&self) {
         unsafe {
             wr_notifier_wake_up(self.window_id);
         }
     }
 
     fn new_frame_ready(&self,
                        _: DocumentId,
-                       scrolled: bool,
+                       _scrolled: bool,
                        composite_needed: bool) {
         unsafe {
-            if scrolled {
-                wr_notifier_new_scroll_frame_ready(self.window_id, composite_needed);
-            } else if composite_needed {
+            if composite_needed {
                 wr_notifier_new_frame_ready(self.window_id);
+            } else {
+                wr_notifier_nop_frame_done(self.window_id);
             }
         }
     }
 
     fn external_event(&self,
                       event: ExternalEvent) {
         unsafe {
             wr_notifier_external_event(self.window_id, event.unwrap());
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1363,18 +1363,17 @@ extern bool wr_moz2d_render_cb(ByteSlice
                                const DeviceUintRect *aDirtyRect,
                                MutByteSlice aOutput);
 
 extern void wr_notifier_external_event(WrWindowId aWindowId,
                                        uintptr_t aRawEvent);
 
 extern void wr_notifier_new_frame_ready(WrWindowId aWindowId);
 
-extern void wr_notifier_new_scroll_frame_ready(WrWindowId aWindowId,
-                                               bool aCompositeNeeded);
+extern void wr_notifier_nop_frame_done(WrWindowId aWindowId);
 
 extern void wr_notifier_wake_up(WrWindowId aWindowId);
 
 WR_INLINE
 void wr_pipeline_info_delete(WrPipelineInfo aInfo)
 WR_DESTRUCTOR_SAFE_FUNC;
 
 WR_INLINE