Bug 1331194 - Don't cancel wheel-scroll animations when starting a new wheel block. r=botond a=gchang
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 23 Jan 2017 18:10:20 -0500
changeset 376165 76e8397a0bdae9599f9cafb5ba8909868b71bba8
parent 376164 795d6097a2de64dc19938e3a2d0b22e2e6cb9cbb
child 376166 252e3d832683eeb0b7f5a49b504d31168cabdd7e
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond, gchang
bugs1331194
milestone53.0a2
Bug 1331194 - Don't cancel wheel-scroll animations when starting a new wheel block. r=botond a=gchang MozReview-Commit-ID: AU36ABfXYNQ
gfx/layers/apz/src/APZUtils.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/InputQueue.cpp
gfx/layers/apz/src/InputQueue.h
--- a/gfx/layers/apz/src/APZUtils.h
+++ b/gfx/layers/apz/src/APZUtils.h
@@ -24,17 +24,18 @@ enum HitTestResult {
   HitLayerTouchActionPanY,
   HitLayerTouchActionPanXY,
   HitDispatchToContentRegion,
 };
 
 enum CancelAnimationFlags : uint32_t {
   Default = 0x0,            /* Cancel all animations */
   ExcludeOverscroll = 0x1,  /* Don't clear overscroll */
-  ScrollSnap = 0x2          /* Snap to snap points */
+  ScrollSnap = 0x2,         /* Snap to snap points */
+  ExcludeWheel = 0x4,       /* Don't stop wheel smooth-scroll animations */
 };
 
 inline CancelAnimationFlags
 operator|(CancelAnimationFlags a, CancelAnimationFlags b)
 {
   return static_cast<CancelAnimationFlags>(static_cast<int>(a)
                                          | static_cast<int>(b));
 }
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -2621,17 +2621,22 @@ void AsyncPanZoomController::StartAnimat
   ReentrantMonitorAutoEnter lock(mMonitor);
   mAnimation = aAnimation;
   mLastSampleTime = GetFrameTime();
   ScheduleComposite();
 }
 
 void AsyncPanZoomController::CancelAnimation(CancelAnimationFlags aFlags) {
   ReentrantMonitorAutoEnter lock(mMonitor);
-  APZC_LOG("%p running CancelAnimation in state %d\n", this, mState);
+  APZC_LOG("%p running CancelAnimation(0x%x) in state %d\n", this, aFlags, mState);
+
+  if ((aFlags & ExcludeWheel) && mState == WHEEL_SCROLL) {
+    return;
+  }
+
   SetState(NOTHING);
   mAnimation = nullptr;
   // Since there is no animation in progress now the axes should
   // have no velocity either. If we are dropping the velocity from a non-zero
   // value we should trigger a repaint as the displayport margins are dependent
   // on the velocity and the last repaint request might not have good margins
   // any more.
   bool repaint = !IsZero(GetVelocityVector());
--- a/gfx/layers/apz/src/InputQueue.cpp
+++ b/gfx/layers/apz/src/InputQueue.cpp
@@ -236,17 +236,17 @@ InputQueue::ReceiveScrollWheelInput(cons
 
   if (!block) {
     block = new WheelBlockState(aTarget, aTargetConfirmed, aEvent);
     INPQ_LOG("started new scroll wheel block %p id %" PRIu64 " for target %p\n",
         block, block->GetBlockId(), aTarget.get());
 
     mActiveWheelBlock = block;
 
-    CancelAnimationsForNewBlock(block);
+    CancelAnimationsForNewBlock(block, ExcludeWheel);
     MaybeRequestContentResponse(aTarget, block);
   } else {
     INPQ_LOG("received new event in block %p\n", block);
   }
 
   if (aOutInputBlockId) {
     *aOutInputBlockId = block->GetBlockId();
   }
@@ -344,26 +344,28 @@ InputQueue::ReceivePanGestureInput(const
   // ProcessQueue() does.
   mQueuedInputs.AppendElement(MakeUnique<QueuedInput>(event, *block));
   ProcessQueue();
 
   return result;
 }
 
 void
-InputQueue::CancelAnimationsForNewBlock(CancelableBlockState* aBlock)
+InputQueue::CancelAnimationsForNewBlock(CancelableBlockState* aBlock,
+                                        CancelAnimationFlags aExtraFlags)
 {
   // We want to cancel animations here as soon as possible (i.e. without waiting for
   // content responses) because a finger has gone down and we don't want to keep moving
   // the content under the finger. However, to prevent "future" touchstart events from
   // interfering with "past" animations (i.e. from a previous touch block that is still
   // being processed) we only do this animation-cancellation if there are no older
   // touch blocks still in the queue.
   if (mQueuedInputs.IsEmpty()) {
-    aBlock->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll | ScrollSnap);
+    aBlock->GetOverscrollHandoffChain()->CancelAnimations(
+        aExtraFlags | ExcludeOverscroll | ScrollSnap);
   }
 }
 
 void
 InputQueue::MaybeRequestContentResponse(const RefPtr<AsyncPanZoomController>& aTarget,
                                         CancelableBlockState* aBlock)
 {
   bool waitForMainThread = false;
--- a/gfx/layers/apz/src/InputQueue.h
+++ b/gfx/layers/apz/src/InputQueue.h
@@ -138,17 +138,18 @@ private:
   TouchBlockState* StartNewTouchBlock(const RefPtr<AsyncPanZoomController>& aTarget,
                                       bool aTargetConfirmed,
                                       bool aCopyPropertiesFromCurrent);
 
   /**
    * If animations are present for the current pending input block, cancel
    * them as soon as possible.
    */
-  void CancelAnimationsForNewBlock(CancelableBlockState* aBlock);
+  void CancelAnimationsForNewBlock(CancelableBlockState* aBlock,
+                                   CancelAnimationFlags aExtraFlags = Default);
 
   /**
    * If we need to wait for a content response, schedule that now.
    */
   void MaybeRequestContentResponse(const RefPtr<AsyncPanZoomController>& aTarget,
                                    CancelableBlockState* aBlock);
 
   nsEventStatus ReceiveTouchInput(const RefPtr<AsyncPanZoomController>& aTarget,