Bug 1152051 - Gtest. r=Cwiiis,kats
authorBotond Ballo <botond@mozilla.com>
Wed, 29 Apr 2015 19:38:02 -0400
changeset 273477 e1b56bd22b3a87979022e26d234ac2c282dc5f3f
parent 273476 c7b25a8722359af4b8f1d29ddc522f7900c5d969
child 273478 91145ffa577469b6bf912f2bfa60d0ed04decd90
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCwiiis, kats
bugs1152051
milestone40.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 1152051 - Gtest. r=Cwiiis,kats
gfx/tests/gtest/TestAsyncPanZoomController.cpp
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -252,16 +252,27 @@ protected:
     AsyncPanZoomController::SetFrameTime(testStartTime);
 
     mcc = new NiceMock<MockContentControllerDelayed>();
     tm = new TestAPZCTreeManager();
     apzc = new TestAsyncPanZoomController(0, mcc, tm, mGestureBehavior);
     apzc->SetFrameMetrics(TestFrameMetrics());
   }
 
+  /**
+   * Get the APZC's scroll range in CSS pixels.
+   */
+  CSSRect GetScrollRange() const
+  {
+    const FrameMetrics& metrics = apzc->GetFrameMetrics();
+    return CSSRect(
+        metrics.GetScrollableRect().TopLeft(),
+        metrics.GetScrollableRect().Size() - metrics.CalculateCompositedSizeInCssPixels());
+  }
+
   virtual void TearDown()
   {
     apzc->Destroy();
   }
 
   void MakeApzcWaitForMainThread()
   {
     apzc->SetWaitForMainThread();
@@ -272,16 +283,59 @@ protected:
     apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToParentLayerScale(0.25f), CSSToParentLayerScale(4.0f)));
   }
 
   void MakeApzcUnzoomable()
   {
     apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToParentLayerScale(1.0f), CSSToParentLayerScale(1.0f)));
   }
 
+  void PanIntoOverscroll(int& aTime);
+
+  /**
+   * Sample animations once, 1 ms later than the last sample.
+   */
+  void SampleAnimationOnce()
+  {
+    const TimeDuration increment = TimeDuration::FromMilliseconds(1);
+    ParentLayerPoint pointOut;
+    ViewTransform viewTransformOut;
+    testStartTime += increment;
+    apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
+  }
+
+  /**
+   * Sample animations until we recover from overscroll.
+   * @param aExpectedScrollOffset the expected reported scroll offset
+   *                              throughout the animation
+   */
+  void SampleAnimationUntilRecoveredFromOverscroll(const ParentLayerPoint& aExpectedScrollOffset)
+  {
+    const TimeDuration increment = TimeDuration::FromMilliseconds(1);
+    bool recoveredFromOverscroll = false;
+    ParentLayerPoint pointOut;
+    ViewTransform viewTransformOut;
+    while (apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut)) {
+      // The reported scroll offset should be the same throughout.
+      EXPECT_EQ(aExpectedScrollOffset, pointOut);
+
+      // Trigger computation of the overscroll tranform, to make sure
+      // no assetions fire during the calculation.
+      apzc->GetOverscrollTransform();
+
+      if (!apzc->IsOverscrolled()) {
+        recoveredFromOverscroll = true;
+      }
+
+      testStartTime += increment;
+    }
+    EXPECT_TRUE(recoveredFromOverscroll);
+    apzc->AssertStateIsReset();
+  }
+
   void TestOverscroll();
 
   AsyncPanZoomController::GestureBehavior mGestureBehavior;
   TimeStamp testStartTime;
   nsRefPtr<MockContentControllerDelayed> mcc;
   nsRefPtr<TestAPZCTreeManager> tm;
   nsRefPtr<TestAsyncPanZoomController> apzc;
 };
@@ -1132,58 +1186,45 @@ TEST_F(APZCBasicTester, PanningTransform
   check.Call("Simple pan");
   ApzcPanNoFling(apzc, time, 50, 25);
   check.Call("Complex pan");
   Pan(apzc, time, 25, 45);
   apzc->AdvanceAnimationsUntilEnd(testStartTime);
   check.Call("Done");
 }
 
+void APZCBasicTester::PanIntoOverscroll(int& aTime)
+{
+  int touchStart = 500;
+  int touchEnd = 10;
+  Pan(apzc, aTime, touchStart, touchEnd);
+  EXPECT_TRUE(apzc->IsOverscrolled());
+}
+
 void APZCBasicTester::TestOverscroll()
 {
   // Pan sufficiently to hit overscroll behavior
   int time = 0;
-  int touchStart = 500;
-  int touchEnd = 10;
-  Pan(apzc, time, touchStart, touchEnd);
-  EXPECT_TRUE(apzc->IsOverscrolled());
+  PanIntoOverscroll(time);
 
   // Check that we recover from overscroll via an animation.
-  const TimeDuration increment = TimeDuration::FromMilliseconds(1);
-  bool recoveredFromOverscroll = false;
-  ParentLayerPoint pointOut;
-  ViewTransform viewTransformOut;
-  while (apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut)) {
-    // The reported scroll offset should be the same throughout.
-    EXPECT_EQ(ParentLayerPoint(0, 90), pointOut);
-
-    // Trigger computation of the overscroll tranform, to make sure
-    // no assetions fire during the calculation.
-    apzc->GetOverscrollTransform();
-
-    if (!apzc->IsOverscrolled()) {
-      recoveredFromOverscroll = true;
-    }
-
-    testStartTime += increment;
-  }
-  EXPECT_TRUE(recoveredFromOverscroll);
-  apzc->AssertStateIsReset();
+  ParentLayerPoint expectedScrollOffset(0, GetScrollRange().YMost());
+  SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
 }
 
 
 TEST_F(APZCBasicTester, OverScrollPanning) {
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   TestOverscroll();
 }
 
 // Tests that an overscroll animation doesn't trigger an assertion failure
 // in the case where a sample has a velocity of zero.
-TEST_F(APZCBasicTester, OverScroll_Bug1152051) {
+TEST_F(APZCBasicTester, OverScroll_Bug1152051a) {
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   // Doctor the prefs to make the velocity zero at the end of the first sample.
 
   // This ensures our incoming velocity to the overscroll animation is
   // a round(ish) number, 4.9 (that being the distance of the pan before
   // overscroll, which is 500 - 10 = 490 pixels, divided by the duration of
   // the pan, which is 100 ms).
@@ -1192,16 +1233,54 @@ TEST_F(APZCBasicTester, OverScroll_Bug11
   // To ensure the velocity after the first sample is 0, set the spring
   // stiffness to the incoming velocity (4.9) divided by the overscroll
   // (400 pixels) times the step duration (1 ms).
   SCOPED_GFX_PREF(APZOverscrollSpringStiffness, float, 0.01225f);
 
   TestOverscroll();
 }
 
+// Tests that ending an overscroll animation doesn't leave around state that
+// confuses the next overscroll animation.
+TEST_F(APZCBasicTester, OverScroll_Bug1152051b) {
+  SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
+
+  SCOPED_GFX_PREF(APZOverscrollStopDistanceThreshold, float, 0.1f);
+
+  // Pan sufficiently to hit overscroll behavior
+  int time = 0;
+  PanIntoOverscroll(time);
+
+  // Sample animations once, to give the fling animation started on touch-up
+  // a chance to realize it's overscrolled, and schedule a call to
+  // HandleFlingOverscroll().
+  SampleAnimationOnce();
+
+  // Give the call to HandleFlingOverscroll() a chance to occur, creating
+  // an overscroll animation.
+  mcc->RunThroughDelayedTasks();
+
+  // Sample the overscroll animation once, to get it to initialize
+  // the first overscroll sample.
+  SampleAnimationOnce();
+
+  // Do a touch-down to cancel the overscroll animation, and then a touch-up
+  // to schedule a new one since we're still overscrolled. We don't pan because
+  // panning can trigger functions that clear the overscroll animation state
+  // in other ways.
+  TouchDown(apzc, 10, 10, time, nullptr);
+  TouchUp(apzc, 10, 10, time);
+
+  // Sample the second overscroll animation to its end.
+  // If the ending of the first overscroll animation fails to clear state
+  // properly, this will assert.
+  ParentLayerPoint expectedScrollOffset(0, GetScrollRange().YMost());
+  SampleAnimationUntilRecoveredFromOverscroll(expectedScrollOffset);
+}
+
 TEST_F(APZCBasicTester, OverScrollAbort) {
   SCOPED_GFX_PREF(APZOverscrollEnabled, bool, true);
 
   // Pan sufficiently to hit overscroll behavior
   int time = 0;
   int touchStart = 500;
   int touchEnd = 10;
   Pan(apzc, time, touchStart, touchEnd);