Bug 1418387 - Find the appropriate scrollbar node in GetAPZCAtPointWR. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 24 Nov 2017 16:23:06 -0500
changeset 703341 4f378c336dd70104877f4c49fd8461151d97304d
parent 703340 133b72a8ff6351182746ebf6d42a57d171ebad25
child 741740 e62ddbadd36cbdb9c4443d2f80377efb021adc5b
push id90784
push userkgupta@mozilla.com
push dateFri, 24 Nov 2017 21:25:10 +0000
reviewersbotond
bugs1418387
milestone59.0a1
Bug 1418387 - Find the appropriate scrollbar node in GetAPZCAtPointWR. r?botond MozReview-Commit-ID: Fb4465Gaj7K
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/HitTestingTreeNode.cpp
gfx/layers/apz/src/HitTestingTreeNode.h
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -2192,46 +2192,54 @@ APZCTreeManager::GetTargetAPZC(const Scr
 
   HitTestResult hitResult = HitNothing;
   HitTestingTreeNode* scrollbarNode = nullptr;
   RefPtr<AsyncPanZoomController> target;
   target = GetAPZCAtPoint(mRootNode, aPoint, &hitResult, &scrollbarNode);
 
   if (gfxPrefs::WebRenderHitTest()) {
     HitTestResult wrHitResult = HitNothing;
-    RefPtr<AsyncPanZoomController> wrTarget = GetAPZCAtPointWR(aPoint, &wrHitResult);
+    HitTestingTreeNode* wrScrollbarNode = nullptr;
+    RefPtr<AsyncPanZoomController> wrTarget = GetAPZCAtPointWR(aPoint, &wrHitResult, &wrScrollbarNode);
     // For now just compare the WR and non-WR results.
     if (wrHitResult != hitResult) {
       printf_stderr("WR hit result mismatch at %s: got %d, expected %d\n",
           Stringify(aPoint).c_str(), (int)wrHitResult, (int)hitResult);
       // MOZ_RELEASE_ASSERT(false);
     }
     if (wrTarget.get() != target.get()) {
       printf_stderr("WR hit target mismatch at %s: got %s, expected %s\n",
           Stringify(aPoint).c_str(),
           wrTarget ? Stringify(wrTarget->GetGuid()).c_str() : "null",
           target ? Stringify(target->GetGuid()).c_str() : "null");
       // MOZ_RELEASE_ASSERT(false);
     }
+    if (wrScrollbarNode != scrollbarNode) {
+      printf_stderr("WR scrollbar node mismatch at %s: got %p, expected %p\n",
+          Stringify(aPoint).c_str(), wrScrollbarNode, scrollbarNode);
+      // MOZ_RELEASE_ASSERT(false);
+    }
   }
 
   if (aOutHitResult) {
     *aOutHitResult = hitResult;
   }
   if (aOutScrollbarNode) {
     *aOutScrollbarNode = scrollbarNode;
   }
   return target.forget();
 }
 
 already_AddRefed<AsyncPanZoomController>
 APZCTreeManager::GetAPZCAtPointWR(const ScreenPoint& aHitTestPoint,
-                                  HitTestResult* aOutHitResult)
+                                  HitTestResult* aOutHitResult,
+                                  HitTestingTreeNode** aOutScrollbarNode)
 {
   MOZ_ASSERT(aOutHitResult);
+  MOZ_ASSERT(aOutScrollbarNode);
 
   RefPtr<AsyncPanZoomController> result;
   RefPtr<wr::WebRenderAPI> wr = GetWebRenderAPI();
   if (!wr) {
     return result.forget();
   }
 
   wr::WrPipelineId pipelineId;
@@ -2251,16 +2259,32 @@ APZCTreeManager::GetAPZCAtPointWR(const 
   result = node ? node->GetApzc() : nullptr;
   if (!result) {
     // It falls back to the root
     MOZ_ASSERT(scrollId == FrameMetrics::NULL_SCROLL_ID);
     result = FindRootApzcForLayersId(layersId);
     MOZ_ASSERT(result);
   }
 
+  bool isScrollbar = bool(hitInfo & gfx::CompositorHitTestInfo::eScrollbar);
+  bool isScrollbarThumb = bool(hitInfo & gfx::CompositorHitTestInfo::eScrollbarThumb);
+  ScrollDirection direction = (hitInfo & gfx::CompositorHitTestInfo::eScrollbarVertical)
+                            ? ScrollDirection::eVertical
+                            : ScrollDirection::eHorizontal;
+  if (isScrollbar || isScrollbarThumb) {
+    *aOutScrollbarNode = BreadthFirstSearch<ReverseIterator>(mRootNode.get(),
+      [&](HitTestingTreeNode* aNode) {
+        return (aNode->GetLayersId() == layersId) &&
+               (aNode->IsScrollbarNode() == isScrollbar) &&
+               (aNode->IsScrollThumbNode() == isScrollbarThumb) &&
+               (aNode->GetScrollbarDirection() == direction) &&
+               (aNode->GetScrollTargetId() == scrollId);
+      });
+  }
+
   *aOutHitResult = HitLayer;
   if (hitInfo & gfx::CompositorHitTestInfo::eDispatchToContent) {
     *aOutHitResult = HitDispatchToContentRegion;
     return result.forget();
   }
 
   auto touchFlags = hitInfo & gfx::CompositorHitTestInfo::eTouchActionMask;
   if (!touchFlags) {
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -519,17 +519,18 @@ private:
                                      const ScrollableLayerGuid& aGuid,
                                      GuidComparator aComparator);
   AsyncPanZoomController* GetTargetApzcForNode(HitTestingTreeNode* aNode);
   AsyncPanZoomController* GetAPZCAtPoint(HitTestingTreeNode* aNode,
                                          const ScreenPoint& aHitTestPoint,
                                          HitTestResult* aOutHitResult,
                                          HitTestingTreeNode** aOutScrollbarNode);
   already_AddRefed<AsyncPanZoomController> GetAPZCAtPointWR(const ScreenPoint& aHitTestPoint,
-                                                            HitTestResult* aOutHitResult);
+                                                            HitTestResult* aOutHitResult,
+                                                            HitTestingTreeNode** aOutScrollbarNode);
   AsyncPanZoomController* FindRootApzcForLayersId(uint64_t aLayersId) const;
   AsyncPanZoomController* FindRootContentApzcForLayersId(uint64_t aLayersId) const;
   AsyncPanZoomController* FindRootContentOrRootApzc() const;
   already_AddRefed<AsyncPanZoomController> GetMultitouchTarget(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
   already_AddRefed<AsyncPanZoomController> CommonAncestor(AsyncPanZoomController* aApzc1, AsyncPanZoomController* aApzc2) const;
   /**
    * Perform hit testing for a touch-start event.
    *
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -119,16 +119,26 @@ HitTestingTreeNode::IsScrollThumbNode() 
 }
 
 bool
 HitTestingTreeNode::IsScrollbarNode() const
 {
   return mScrollbarContainerDirection.isSome() || IsScrollThumbNode();
 }
 
+ScrollDirection
+HitTestingTreeNode::GetScrollbarDirection() const
+{
+  MOZ_ASSERT(IsScrollbarNode());
+  if (mScrollThumbData.mDirection.isSome()) {
+    return *(mScrollThumbData.mDirection);
+  }
+  return *mScrollbarContainerDirection;
+}
+
 FrameMetrics::ViewID
 HitTestingTreeNode::GetScrollTargetId() const
 {
   return mScrollViewId;
 }
 
 const uint64_t&
 HitTestingTreeNode::GetScrollbarAnimationId() const
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -95,16 +95,18 @@ public:
   /* Scrollbar info */
 
   void SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
                         const uint64_t& aScrollbarAnimationId,
                         const ScrollThumbData& aThumbData,
                         const Maybe<ScrollDirection>& aScrollContainerDirection);
   bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
   bool IsScrollbarNode() const;  // Scroll thumb or scrollbar container layer.
+  // This can only be called if IsScrollbarNode() is true
+  ScrollDirection GetScrollbarDirection() const;
   bool IsScrollThumbNode() const;  // Scroll thumb container layer.
   FrameMetrics::ViewID GetScrollTargetId() const;
   const ScrollThumbData& GetScrollThumbData() const;
   const uint64_t& GetScrollbarAnimationId() const;
 
   /* Fixed pos info */
 
   void SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget);