Bug 918288 - Modify the SetTargetAPZC API to take an array of targets for multiple touch points. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 21 Nov 2014 21:36:25 -0500
changeset 241302 35dfe1a7ed6a3ad4036cf36f1f16172f73428826
parent 241301 f440594be934055df8c919fda84f06643d1664e6
child 241303 e3c088f81361d4c67e54ae06cb86ef22999fe9ff
push id4311
push userraliiev@mozilla.com
push dateMon, 12 Jan 2015 19:37:41 +0000
treeherdermozilla-beta@150c9fed433b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs918288
milestone36.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 918288 - Modify the SetTargetAPZC API to take an array of targets for multiple touch points. r=botond
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/tests/gtest/TestAsyncPanZoomController.cpp
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -716,21 +716,17 @@ APZCTreeManager::GetTouchInputBlockAPZC(
     for (AsyncPanZoomController* apzc = mRootApzc; apzc; apzc = apzc->GetPrevSibling()) {
       FlushRepaintsRecursively(apzc);
     }
   }
 
   apzc = GetTargetAPZC(aEvent.mTouches[0].mScreenPoint, aOutHitResult);
   for (size_t i = 1; i < aEvent.mTouches.Length(); i++) {
     nsRefPtr<AsyncPanZoomController> apzc2 = GetTargetAPZC(aEvent.mTouches[i].mScreenPoint, aOutHitResult);
-    apzc = CommonAncestor(apzc.get(), apzc2.get());
-    APZCTM_LOG("Using APZC %p as the common ancestor\n", apzc.get());
-    // For now, we only ever want to do pinching on the root APZC for a given layers id. So
-    // when we find the common ancestor of multiple points, also walk up to the root APZC.
-    apzc = RootAPZCForLayersId(apzc);
+    apzc = GetMultitouchTarget(apzc, apzc2);
     APZCTM_LOG("Using APZC %p as the root APZC for multi-touch\n", apzc.get());
   }
 
   return apzc.forget();
 }
 
 nsEventStatus
 APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
@@ -955,19 +951,26 @@ void
 APZCTreeManager::ContentReceivedTouch(uint64_t aInputBlockId,
                                       bool aPreventDefault)
 {
   mInputQueue->ContentReceivedTouch(aInputBlockId, aPreventDefault);
 }
 
 void
 APZCTreeManager::SetTargetAPZC(uint64_t aInputBlockId,
-                               const ScrollableLayerGuid& aGuid)
+                               const nsTArray<ScrollableLayerGuid>& aTargets)
 {
-  nsRefPtr<AsyncPanZoomController> target = GetTargetAPZC(aGuid);
+  nsRefPtr<AsyncPanZoomController> target = nullptr;
+  if (aTargets.Length() > 0) {
+    target = GetTargetAPZC(aTargets[0]);
+  }
+  for (size_t i = 1; i < aTargets.Length(); i++) {
+    nsRefPtr<AsyncPanZoomController> apzc2 = GetTargetAPZC(aTargets[i]);
+    target = GetMultitouchTarget(target, apzc2);
+  }
   mInputQueue->SetConfirmedTargetApzc(aInputBlockId, target);
 }
 
 void
 APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
                                        const ZoomConstraints& aConstraints)
 {
   nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
@@ -1551,17 +1554,27 @@ APZCTreeManager::GetApzcToGeckoTransform
     // as explained in the comment above this method. Note that any missing
     // terms are guaranteed to be identity transforms.
   }
 
   return result;
 }
 
 already_AddRefed<AsyncPanZoomController>
-APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2)
+APZCTreeManager::GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const
+{
+  nsRefPtr<AsyncPanZoomController> apzc = CommonAncestor(aApzc1, aApzc2);
+  // For now, we only ever want to do pinching on the root APZC for a given layers id. So
+  // when we find the common ancestor of multiple points, also walk up to the root APZC.
+  apzc = RootAPZCForLayersId(apzc);
+  return apzc.forget();
+}
+
+already_AddRefed<AsyncPanZoomController>
+APZCTreeManager::CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const
 {
   MonitorAutoLock lock(mTreeLock);
   nsRefPtr<AsyncPanZoomController> ancestor;
 
   // If either aApzc1 or aApzc2 is null, min(depth1, depth2) will be 0 and this function
   // will return null.
 
   // Calculate depth of the APZCs in the tree
@@ -1597,17 +1610,17 @@ APZCTreeManager::CommonAncestor(AsyncPan
     }
     aApzc1 = aApzc1->GetParent();
     aApzc2 = aApzc2->GetParent();
   }
   return ancestor.forget();
 }
 
 already_AddRefed<AsyncPanZoomController>
-APZCTreeManager::RootAPZCForLayersId(AsyncPanZoomController* aApzc)
+APZCTreeManager::RootAPZCForLayersId(AsyncPanZoomController* aApzc) const
 {
   MonitorAutoLock lock(mTreeLock);
   nsRefPtr<AsyncPanZoomController> apzc = aApzc;
   while (apzc && !apzc->IsRootForLayersId()) {
     apzc = apzc->GetParent();
   }
   return apzc.forget();
 }
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -214,21 +214,23 @@ public:
                             bool aPreventDefault);
 
   /**
    * When the event regions code is enabled, this function should be invoked to
    * to confirm the target of the input block. This is only needed in cases
    * where the initial input event of the block hit a dispatch-to-content region
    * but is safe to call for all input blocks. This function should always be
    * invoked on the controller thread.
-   * In the case where the input block has no target, or the target is not a
-   * scrollable frame, |aGuid.mScrollId| should be set to FrameMetrics::
-   * NULL_SCROLL_ID.
+   * The different elements in the array of targets correspond to the targets
+   * for the different touch points. In the case where the touch point has no
+   * target, or the target is not a scrollable frame, the target's |mScrollId|
+   * should be set to FrameMetrics::NULL_SCROLL_ID.
    */
-  void SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aGuid);
+  void SetTargetAPZC(uint64_t aInputBlockId,
+                     const nsTArray<ScrollableLayerGuid>& aTargets);
 
   /**
    * Updates any zoom constraints contained in the <meta name="viewport"> tag.
    */
   void UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
                              const ZoomConstraints& aConstraints);
 
   /**
@@ -399,18 +401,19 @@ public:
   gfx::Matrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
 private:
   /* Helpers */
   AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, FrameMetrics::ViewID aScrollId);
   AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableLayerGuid& aGuid);
   AsyncPanZoomController* GetAPZCAtPoint(AsyncPanZoomController* aApzc,
                                          const gfx::Point& aHitTestPoint,
                                          HitTestResult* aOutHitResult);
-  already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2);
-  already_AddRefed<AsyncPanZoomController> RootAPZCForLayersId(AsyncPanZoomController* aApzc);
+  already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
+  already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
+  already_AddRefed<AsyncPanZoomController> RootAPZCForLayersId(AsyncPanZoomController* aApzc) const;
   already_AddRefed<AsyncPanZoomController> GetTouchInputBlockAPZC(const MultiTouchInput& aEvent,
                                                                   HitTestResult* aOutHitResult);
   nsEventStatus ProcessTouchInput(MultiTouchInput& aInput,
                                   ScrollableLayerGuid* aOutTargetGuid,
                                   uint64_t* aOutInputBlockId);
   nsEventStatus ProcessEvent(WidgetInputEvent& inputEvent,
                              ScrollableLayerGuid* aOutTargetGuid,
                              uint64_t* aOutInputBlockId);
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp
@@ -2480,17 +2480,19 @@ TEST_F(APZEventRegionsTester, HitRegionI
   mcc->RunThroughDelayedTasks();    // this runs the main-thread timeout
   check.Call("Tap pending on d-t-c region");
   mcc->RunThroughDelayedTasks();    // this runs the tap event
   check.Call("Tapped on bottom again");
 
   // Now let's do that again, but simulate a main-thread response
   uint64_t inputBlockId = 0;
   Tap(manager, 10, 110, time, 100, nullptr, &inputBlockId);
-  manager->SetTargetAPZC(inputBlockId, left->GetGuid());
+  nsTArray<ScrollableLayerGuid> targets;
+  targets.AppendElement(left->GetGuid());
+  manager->SetTargetAPZC(inputBlockId, targets);
   while (mcc->RunThroughDelayedTasks());    // this runs the tap event
   check.Call("Tapped on left this time");
 }
 
 TEST_F(APZEventRegionsTester, HitRegionAccumulatesChildren) {
   SCOPED_GFX_PREF(LayoutEventRegionsEnabled, bool, true);
 
   CreateEventRegionsLayerTree2();