Bug 1463184 - Use the HTTNAutoLock in FindScrollbarThumb. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 04 Jun 2018 10:01:49 -0400
changeset 475348 936a5003aa2e818a9a82a642fbe91164d97d5886
parent 475347 eb122eb10aad7702541251873ccfc74c5c405d2f
child 475349 f3de98e58e528164b45592d4d6b61cd549701c2f
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1463184
milestone62.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 1463184 - Use the HTTNAutoLock in FindScrollbarThumb. r=botond MozReview-Commit-ID: Gk1GO44A57v
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
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
@@ -2604,31 +2604,36 @@ APZCTreeManager::BuildOverscrollHandoffC
 
 void
 APZCTreeManager::SetLongTapEnabled(bool aLongTapEnabled)
 {
   APZThreadUtils::AssertOnControllerThread();
   GestureEventListener::SetLongTapEnabled(aLongTapEnabled);
 }
 
-RefPtr<HitTestingTreeNode>
-APZCTreeManager::FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics)
+void
+APZCTreeManager::FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics,
+                                     HitTestingTreeNodeAutoLock& aOutThumbNode)
 {
   if (!aDragMetrics.mDirection) {
     // The AsyncDragMetrics has not been initialized yet - there will be
     // no matching node, so don't bother searching the tree.
-    return RefPtr<HitTestingTreeNode>();
+    return;
   }
 
   RecursiveMutexAutoLock lock(mTreeLock);
 
-  return DepthFirstSearch<ReverseIterator>(mRootNode.get(),
+  RefPtr<HitTestingTreeNode> result = DepthFirstSearch<ReverseIterator>(
+      mRootNode.get(),
       [&aDragMetrics](HitTestingTreeNode* aNode) {
         return aNode->MatchesScrollDragMetrics(aDragMetrics);
       });
+  if (result) {
+    aOutThumbNode.Initialize(lock, result.forget(), mTreeLock);
+  }
 }
 
 AsyncPanZoomController*
 APZCTreeManager::GetTargetApzcForNode(HitTestingTreeNode* aNode)
 {
   for (const HitTestingTreeNode* n = aNode;
        n && n->GetLayersId() == aNode->GetLayersId();
        n = n->GetParent()) {
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -372,19 +372,20 @@ public:
 
   /**
    * Returns the current dpi value in use.
    */
   float GetDPI() const;
 
   /**
    * Find the hit testing node for the scrollbar thumb that matches these
-   * drag metrics.
+   * drag metrics. Initializes aOutThumbNode with the node, if there is one.
    */
-  RefPtr<HitTestingTreeNode> FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics);
+  void FindScrollThumbNode(const AsyncDragMetrics& aDragMetrics,
+                           HitTestingTreeNodeAutoLock& aOutThumbNode);
 
   /**
    * Sets allowed touch behavior values for current touch-session for specific
    * input block (determined by aInputBlock).
    * Should be invoked by the widget. Each value of the aValues arrays
    * corresponds to the different touch point that is currently active.
    * Must be called after receiving the TOUCH_START event that starts the
    * touch-session.
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -995,18 +995,18 @@ nsEventStatus AsyncPanZoomController::Ha
   }
 
   if (aEvent.mType == MouseInput::MouseType::MOUSE_UP) {
     SetState(NOTHING);
     ScrollSnap();
     return nsEventStatus_eConsumeNoDefault;
   }
 
-  RefPtr<HitTestingTreeNode> node =
-    GetApzcTreeManager()->FindScrollThumbNode(aDragMetrics);
+  HitTestingTreeNodeAutoLock node;
+  GetApzcTreeManager()->FindScrollThumbNode(aDragMetrics, node);
   if (!node) {
     return nsEventStatus_eConsumeNoDefault;
   }
 
   if (aEvent.mType == MouseInput::MouseType::MOUSE_DOWN) {
     SetState(SCROLLBAR_DRAG);
   }
 
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -19,17 +19,17 @@ namespace layers {
 
 using gfx::CompositorHitTestInfo;
 
 HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc,
                                        bool aIsPrimaryHolder,
                                        LayersId aLayersId)
   : mApzc(aApzc)
   , mIsPrimaryApzcHolder(aIsPrimaryHolder)
-  , mLocked(false)
+  , mLockCount(0)
   , mLayersId(aLayersId)
   , mScrollbarAnimationId(0)
   , mFixedPosTarget(FrameMetrics::NULL_SCROLL_ID)
   , mIsBackfaceHidden(false)
   , mOverride(EventRegionsOverride::NoOverride)
 {
   if (mIsPrimaryApzcHolder) {
     MOZ_ASSERT(mApzc);
@@ -69,17 +69,17 @@ HitTestingTreeNode::Destroy()
     }
     mApzc = nullptr;
   }
 }
 
 bool
 HitTestingTreeNode::IsRecyclable(const RecursiveMutexAutoLock& aProofOfTreeLock)
 {
-  return !(IsPrimaryHolder() || mLocked);
+  return !(IsPrimaryHolder() || (mLockCount > 0));
 }
 
 void
 HitTestingTreeNode::SetLastChild(HitTestingTreeNode* aChild)
 {
   mLastChild = aChild;
   if (aChild) {
     aChild->mParent = this;
@@ -405,25 +405,24 @@ HitTestingTreeNode::SetApzcParent(AsyncP
   } else {
     MOZ_ASSERT(GetApzc()->GetParent() == aParent);
   }
 }
 
 void
 HitTestingTreeNode::Lock(const RecursiveMutexAutoLock& aProofOfTreeLock)
 {
-  MOZ_ASSERT(!mLocked);
-  mLocked = true;
+  mLockCount++;
 }
 
 void
 HitTestingTreeNode::Unlock(const RecursiveMutexAutoLock& aProofOfTreeLock)
 {
-  MOZ_ASSERT(mLocked);
-  mLocked = false;
+  MOZ_ASSERT(mLockCount > 0);
+  mLockCount--;
 }
 
 HitTestingTreeNodeAutoLock::HitTestingTreeNodeAutoLock()
   : mTreeMutex(nullptr)
 {
 }
 
 HitTestingTreeNodeAutoLock::~HitTestingTreeNodeAutoLock()
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -153,17 +153,17 @@ private:
   void SetApzcParent(AsyncPanZoomController* aApzc);
 
   RefPtr<HitTestingTreeNode> mLastChild;
   RefPtr<HitTestingTreeNode> mPrevSibling;
   RefPtr<HitTestingTreeNode> mParent;
 
   RefPtr<AsyncPanZoomController> mApzc;
   bool mIsPrimaryApzcHolder;
-  bool mLocked;
+  int mLockCount;
 
   LayersId mLayersId;
 
   // This is only set to non-zero if WebRender is enabled, and only for HTTNs
   // where IsScrollThumbNode() returns true. It holds the animation id that we
   // use to move the thumb node to reflect async scrolling.
   uint64_t mScrollbarAnimationId;