Bug 1383912 - Ensure we always get a composite for the latest async scroll offset. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Mon, 24 Jul 2017 17:51:15 -0400
changeset 614661 b118a97674cadef1359e7658539e4e0e9cb785b8
parent 614544 462d7561089c98e33382384896434861ad7bc491
child 614789 eb298ddc4208b06aec4dc30dd90e20324267864e
push id70085
push userbballo@mozilla.com
push dateMon, 24 Jul 2017 21:51:32 +0000
reviewerskats
bugs1383912, 1375949
milestone56.0a1
Bug 1383912 - Ensure we always get a composite for the latest async scroll offset. r=kats This fixes a regression with apz.frame_delay.enabled=true introduced in bug 1375949. MozReview-Commit-ID: AIcGA7c2Co0
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3233,17 +3233,17 @@ bool AsyncPanZoomController::UpdateAnima
   // per composition so we need to deduplicate these calls first.
   if (mLastSampleTime == aSampleTime) {
     return false;
   }
 
   // Sample the composited async transform once per composite. Note that we
   // call this after the |mLastSampleTime == aSampleTime| check, to ensure
   // it's only called once per APZC on each composite.
-  SampleCompositedAsyncTransform();
+  bool needComposite = SampleCompositedAsyncTransform();
 
   TimeDuration sampleTimeDelta = aSampleTime - mLastSampleTime;
   mLastSampleTime = aSampleTime;
 
   if (mAnimation) {
     bool continueAnimation = mAnimation->Sample(mFrameMetrics, sampleTimeDelta);
     bool wantsRepaints = mAnimation->WantsRepaints();
     *aOutDeferredTasks = mAnimation->TakeDeferredTasks();
@@ -3253,19 +3253,19 @@ bool AsyncPanZoomController::UpdateAnima
     }
     // Request a repaint at the end of the animation in case something such as a
     // call to NotifyLayersUpdated was invoked during the animation and Gecko's
     // current state is some intermediate point of the animation.
     if (!continueAnimation || wantsRepaints) {
       RequestContentRepaint();
     }
     UpdateSharedCompositorFrameMetrics();
-    return true;
+    needComposite = true;
   }
-  return false;
+  return needComposite;
 }
 
 AsyncTransformComponentMatrix
 AsyncPanZoomController::GetOverscrollTransform(AsyncTransformConsumer aMode) const
 {
   ReentrantMonitorAutoEnter lock(mMonitor);
 
   if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
@@ -3416,22 +3416,27 @@ CSSToParentLayerScale2D
 AsyncPanZoomController::GetEffectiveZoom(AsyncTransformConsumer aMode) const
 {
   if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
     return mCompositedZoom;
   }
   return mFrameMetrics.GetZoom();
 }
 
-void
+bool
 AsyncPanZoomController::SampleCompositedAsyncTransform()
 {
   ReentrantMonitorAutoEnter lock(mMonitor);
-  mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
-  mCompositedZoom = mFrameMetrics.GetZoom();
+  if (mCompositedScrollOffset != mFrameMetrics.GetScrollOffset() ||
+      mCompositedZoom != mFrameMetrics.GetZoom()) {
+    mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
+    mCompositedZoom = mFrameMetrics.GetZoom();
+    return true;
+  }
+  return false;
 }
 
 AsyncTransformComponentMatrix
 AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const
 {
   return AsyncTransformComponentMatrix(GetCurrentAsyncTransform(aMode))
        * GetOverscrollTransform(aMode);
 }
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -845,21 +845,24 @@ public:
   AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const;
 
 private:
   /**
    * Samples the composited async transform, making the result of
    * |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
    * the async scroll offset and zoom stored in |mFrameMetrics|.
    *
+   * Returns true if the newly sampled value is different from the previously
+   * sampled value.
+   *
    * (This is only relevant when |gfxPrefs::APZFrameDelayEnabled() == true|.
    * Otherwise, GetCurrentAsyncTransform() always reflects what's stored in
    * |mFrameMetrics| immediately, without any delay.)
    */
-  void SampleCompositedAsyncTransform();
+  bool SampleCompositedAsyncTransform();
 
   /*
    * Helper functions to query the async scroll offset and zoom either
    * directly from |mFrameMetrics|, or from cached variables that store
    * the scroll offset and zoom from the last time it was sampled by
    * calling SampleCompositedAsyncTransform(), depending on who is asking.
    */
   CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const;