Bug 1383912 - Ensure we always get a composite for the latest async scroll offset. r=kats
authorBotond Ballo <botond@mozilla.com>
Mon, 24 Jul 2017 17:51:15 -0400
changeset 371225 6f27d2157170d46c8ac75a9778542e250c21c839
parent 371224 ee7761772725d1c985112aebe792b3fd032a1d0a
child 371226 f6ecdab2e8ee8be316d0e8fb34ce6c3e1a2680be
push id93049
push usercbook@mozilla.com
push dateThu, 27 Jul 2017 09:30:07 +0000
treeherdermozilla-inbound@5e9f7561c2eb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1383912, 1375949
milestone56.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 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;