Bug 976605 - Have APZ notify GeckoCC on start of touch. r=kats
authorBotond Ballo <botond@mozilla.com>
Wed, 09 Apr 2014 14:07:47 -0400
changeset 197188 50ee3a60f9ebc09926ab79f95c0dcdc98149cf89
parent 197187 1eb0c794e09cfee8dba37f5038e31e202b5c954d
child 197189 a1a415eab04c50344cf3d45c8ce81c9b60955938
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs976605
milestone31.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 976605 - Have APZ notify GeckoCC on start of touch. r=kats
gfx/layers/composite/APZCTreeManager.cpp
gfx/layers/composite/APZCTreeManager.h
gfx/layers/ipc/AsyncPanZoomController.cpp
gfx/layers/ipc/AsyncPanZoomController.h
gfx/layers/ipc/Axis.cpp
gfx/layers/ipc/Axis.h
gfx/layers/ipc/GeckoContentController.h
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -774,17 +774,16 @@ APZCTreeManager::HandOffFling(AsyncPanZo
   ScreenPoint endPoint = startPoint + aVelocity;
   TransformDisplacement(this, aPrev, next, startPoint, endPoint);
   ScreenPoint transformedVelocity = endPoint - startPoint;
 
   // Tell |next| to start a fling with the transformed velocity.
   next->TakeOverFling(transformedVelocity);
 }
 
-
 bool
 APZCTreeManager::FlushRepaintsForOverscrollHandoffChain()
 {
   MonitorAutoLock lock(mTreeLock);  // to access mOverscrollHandoffChain
   if (mOverscrollHandoffChain.length() == 0) {
     return false;
   }
   for (uint32_t i = 0; i < mOverscrollHandoffChain.length(); i++) {
@@ -792,16 +791,40 @@ APZCTreeManager::FlushRepaintsForOverscr
     if (item) {
       item->FlushRepaintForOverscrollHandoff();
     }
   }
   return true;
 }
 
 bool
+APZCTreeManager::CanBePanned(AsyncPanZoomController* aApzc)
+{
+  MonitorAutoLock lock(mTreeLock);  // to access mOverscrollHandoffChain
+
+  // Find |aApzc| in the handoff chain.
+  uint32_t i;
+  for (i = 0; i < mOverscrollHandoffChain.length(); ++i) {
+    if (mOverscrollHandoffChain[i] == aApzc) {
+      break;
+    }
+  }
+
+  // See whether any APZC in the handoff chain starting from |aApzc|
+  // has room to be panned.
+  for (uint32_t j = i; j < mOverscrollHandoffChain.length(); ++j) {
+    if (mOverscrollHandoffChain[j]->IsPannable()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+bool
 APZCTreeManager::HitTestAPZC(const ScreenIntPoint& aPoint)
 {
   MonitorAutoLock lock(mTreeLock);
   nsRefPtr<AsyncPanZoomController> target;
   // The root may have siblings, so check those too
   gfxPoint point(aPoint.x, aPoint.y);
   for (AsyncPanZoomController* apzc = mRootApzc; apzc; apzc = apzc->GetPrevSibling()) {
     target = GetAPZCAtPoint(apzc, point);
--- a/gfx/layers/composite/APZCTreeManager.h
+++ b/gfx/layers/composite/APZCTreeManager.h
@@ -266,16 +266,23 @@ public:
    * @param aApzc the APZC that is handing off the fling
    * @param aVelocity the current velocity of the fling, in |aApzc|'s screen
    *                  pixels per millisecond
    */
   void HandOffFling(AsyncPanZoomController* aApzc, ScreenPoint aVelocity);
 
   bool FlushRepaintsForOverscrollHandoffChain();
 
+  /**
+   * Determine whether |aApzc|, or any APZC along its overscroll handoff chain,
+   * has room to be panned.
+   * Expects the overscroll handoff chain to already be built.
+   */
+  bool CanBePanned(AsyncPanZoomController* aApzc);
+
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   virtual ~APZCTreeManager();
 
   /**
    * Debug-build assertion that can be called to ensure code is running on the
    * compositor thread.
    */
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -611,21 +611,28 @@ nsEventStatus AsyncPanZoomController::On
         RequestContentRepaint();
         ScheduleComposite();
         UpdateSharedCompositorFrameMetrics();
       }
       // Fall through.
     case FLING:
       CancelAnimation();
       // Fall through.
-    case NOTHING:
+    case NOTHING: {
       mX.StartTouch(point.x);
       mY.StartTouch(point.y);
+      APZCTreeManager* treeManagerLocal = mTreeManager;
+      if (treeManagerLocal) {
+        bool touchCanBePan = treeManagerLocal->CanBePanned(this);
+        mGeckoContentController->NotifyAPZStateChange(
+            GetGuid(), APZStateChange::StartTouch, touchCanBePan);
+      }
       SetState(TOUCHING);
       break;
+    }
     case TOUCHING:
     case PANNING:
     case PANNING_LOCKED_X:
     case PANNING_LOCKED_Y:
     case CROSS_SLIDING_X:
     case CROSS_SLIDING_Y:
     case PINCHING:
     case WAITING_CONTENT_RESPONSE:
@@ -1441,16 +1448,21 @@ void AsyncPanZoomController::ScheduleCom
 }
 
 void AsyncPanZoomController::FlushRepaintForOverscrollHandoff() {
   ReentrantMonitorAutoEnter lock(mMonitor);
   RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
+bool AsyncPanZoomController::IsPannable() const {
+  ReentrantMonitorAutoEnter lock(mMonitor);
+  return mX.HasRoomToPan() || mY.HasRoomToPan();
+}
+
 void AsyncPanZoomController::RequestContentRepaint() {
   RequestContentRepaint(mFrameMetrics);
 }
 
 void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics) {
   aFrameMetrics.SetDisplayPortMargins(
     CalculatePendingDisplayPort(aFrameMetrics,
                                 GetVelocityVector(),
@@ -1989,20 +2001,20 @@ void AsyncPanZoomController::SetState(Pa
     ReentrantMonitorAutoEnter lock(mMonitor);
     oldState = mState;
     mState = aNewState;
   }
 
   if (mGeckoContentController) {
     if (!IsTransformingState(oldState) && IsTransformingState(aNewState)) {
       mGeckoContentController->NotifyAPZStateChange(
-        GetGuid(), APZStateChange::TransformBegin);
+          GetGuid(), APZStateChange::TransformBegin);
     } else if (IsTransformingState(oldState) && !IsTransformingState(aNewState)) {
       mGeckoContentController->NotifyAPZStateChange(
-        GetGuid(), APZStateChange::TransformEnd);
+          GetGuid(), APZStateChange::TransformEnd);
     }
   }
 }
 
 bool AsyncPanZoomController::IsTransformingState(PanZoomState aState) {
   return !(aState == NOTHING || aState == TOUCHING || aState == WAITING_CONTENT_RESPONSE);
 }
 
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -327,16 +327,21 @@ public:
   /**
    * Set an extra offset for testing async scrolling.
    */
   void SetTestAsyncScrollOffset(const CSSPoint& aPoint)
   {
     mTestAsyncScrollOffset = aPoint;
   }
 
+  /**
+   * Returns whether this APZC has room to be panned (in any direction).
+   */
+  bool IsPannable() const;
+
 protected:
   // Protected destructor, to discourage deletion outside of Release():
   ~AsyncPanZoomController();
 
   /**
    * Helper method for touches beginning. Sets everything up for panning and any
    * multitouch gestures.
    */
--- a/gfx/layers/ipc/Axis.cpp
+++ b/gfx/layers/ipc/Axis.cpp
@@ -239,16 +239,22 @@ bool Axis::ScaleWillOverscrollBothSides(
   const FrameMetrics& metrics = mAsyncPanZoomController->GetFrameMetrics();
 
   CSSToParentLayerScale scale(metrics.GetZoomToParent().scale * aScale);
   CSSRect cssCompositionBounds = metrics.mCompositionBounds / scale;
 
   return GetRectLength(metrics.mScrollableRect) < GetRectLength(cssCompositionBounds);
 }
 
+bool Axis::HasRoomToPan() const {
+  return GetOrigin() > GetPageStart()
+      || GetCompositionEnd() < GetPageEnd();
+}
+
+
 AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
   : Axis(aAsyncPanZoomController)
 {
 
 }
 
 float AxisX::GetPointOffset(const CSSPoint& aPoint) const
 {
--- a/gfx/layers/ipc/Axis.h
+++ b/gfx/layers/ipc/Axis.h
@@ -165,16 +165,21 @@ public:
    * Checks if an axis will overscroll in both directions by computing the
    * content rect and checking that its height/width (depending on the axis)
    * does not overextend past the viewport.
    *
    * This gets called by ScaleWillOverscroll().
    */
   bool ScaleWillOverscrollBothSides(float aScale);
 
+  /**
+   * Returns whether there is room to pan on this axis in either direction.
+   */
+  bool HasRoomToPan() const;
+
   float GetOrigin() const;
   float GetCompositionLength() const;
   float GetPageStart() const;
   float GetPageLength() const;
   float GetCompositionEnd() const;
   float GetPageEnd() const;
 
   int32_t GetPos() const { return mPos; }
--- a/gfx/layers/ipc/GeckoContentController.h
+++ b/gfx/layers/ipc/GeckoContentController.h
@@ -117,16 +117,21 @@ public:
     /**
      * APZ started modifying the view (including panning, zooming, and fling).
      */
     TransformBegin,
     /**
      * APZ finished modifying the view.
      */
     TransformEnd,
+    /**
+     * APZ started a touch.
+     * |aArg| is 1 if touch can be a pan, 0 otherwise.
+     */
+    StartTouch,
     APZStateChangeSentinel
   MOZ_END_NESTED_ENUM_CLASS(APZStateChange)
 
   /**
    * General notices of APZ state changes for consumers.
    * |aGuid| identifies the APZC originating the state change.
    * |aChange| identifies the type of state change
    * |aArg| is used by some state changes to pass extra information (see