LCOV - code coverage report
Current view: top level - gfx/layers/apz/src - HitTestingTreeNode.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 121 161 75.2 %
Date: 2017-07-14 16:53:18 Functions: 27 34 79.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et tw=80 : */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "HitTestingTreeNode.h"
       8             : 
       9             : #include "AsyncPanZoomController.h"                     // for AsyncPanZoomController
      10             : #include "gfxPrefs.h"
      11             : #include "LayersLogging.h"                              // for Stringify
      12             : #include "mozilla/gfx/Point.h"                          // for Point4D
      13             : #include "mozilla/layers/APZThreadUtils.h"              // for AssertOnCompositorThread
      14             : #include "mozilla/layers/APZUtils.h"                    // for CompleteAsyncTransform
      15             : #include "mozilla/layers/AsyncCompositionManager.h"     // for ViewTransform::operator Matrix4x4()
      16             : #include "mozilla/layers/AsyncDragMetrics.h"            // for AsyncDragMetrics
      17             : #include "nsPrintfCString.h"                            // for nsPrintfCString
      18             : #include "UnitTransforms.h"                             // for ViewAs
      19             : 
      20             : namespace mozilla {
      21             : namespace layers {
      22             : 
      23          13 : HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc,
      24             :                                        bool aIsPrimaryHolder,
      25          13 :                                        uint64_t aLayersId)
      26             :   : mApzc(aApzc)
      27             :   , mIsPrimaryApzcHolder(aIsPrimaryHolder)
      28             :   , mLayersId(aLayersId)
      29             :   , mScrollViewId(FrameMetrics::NULL_SCROLL_ID)
      30             :   , mScrollbarAnimationId(0)
      31             :   , mIsScrollbarContainer(false)
      32             :   , mFixedPosTarget(FrameMetrics::NULL_SCROLL_ID)
      33          13 :   , mOverride(EventRegionsOverride::NoOverride)
      34             : {
      35          13 : if (mIsPrimaryApzcHolder) {
      36           2 :     MOZ_ASSERT(mApzc);
      37             :   }
      38          13 :   MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId);
      39          13 : }
      40             : 
      41             : void
      42         166 : HitTestingTreeNode::RecycleWith(AsyncPanZoomController* aApzc,
      43             :                                 uint64_t aLayersId)
      44             : {
      45         166 :   MOZ_ASSERT(!mIsPrimaryApzcHolder);
      46         166 :   Destroy(); // clear out tree pointers
      47         166 :   mApzc = aApzc;
      48         166 :   mLayersId = aLayersId;
      49         166 :   MOZ_ASSERT(!mApzc || mApzc->GetLayersId() == mLayersId);
      50             :   // The caller is expected to call SetHitTestData to repopulate the hit-test
      51             :   // fields.
      52         166 : }
      53             : 
      54           6 : HitTestingTreeNode::~HitTestingTreeNode()
      55             : {
      56           6 : }
      57             : 
      58             : void
      59         172 : HitTestingTreeNode::Destroy()
      60             : {
      61         172 :   APZThreadUtils::AssertOnCompositorThread();
      62             : 
      63         172 :   mPrevSibling = nullptr;
      64         172 :   mLastChild = nullptr;
      65         172 :   mParent = nullptr;
      66             : 
      67         172 :   if (mApzc) {
      68           5 :     if (mIsPrimaryApzcHolder) {
      69           0 :       mApzc->Destroy();
      70             :     }
      71           5 :     mApzc = nullptr;
      72             :   }
      73             : 
      74         172 :   mLayersId = 0;
      75         172 : }
      76             : 
      77             : void
      78         122 : HitTestingTreeNode::SetLastChild(HitTestingTreeNode* aChild)
      79             : {
      80         122 :   mLastChild = aChild;
      81         122 :   if (aChild) {
      82          90 :     aChild->mParent = this;
      83             : 
      84          90 :     if (aChild->GetApzc()) {
      85           6 :       AsyncPanZoomController* parent = GetNearestContainingApzc();
      86             :       // We assume that HitTestingTreeNodes with an ancestor/descendant
      87             :       // relationship cannot both point to the same APZC instance. This
      88             :       // assertion only covers a subset of cases in which that might occur,
      89             :       // but it's better than nothing.
      90           6 :       MOZ_ASSERT(aChild->GetApzc() != parent);
      91           6 :       aChild->SetApzcParent(parent);
      92             :     }
      93             :   }
      94         122 : }
      95             : 
      96             : void
      97         211 : HitTestingTreeNode::SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
      98             :                                      const uint64_t& aScrollbarAnimationId,
      99             :                                      const ScrollThumbData& aThumbData,
     100             :                                      bool aIsScrollContainer)
     101             : {
     102         211 :   mScrollViewId = aScrollViewId;
     103         211 :   mScrollbarAnimationId = aScrollbarAnimationId;
     104         211 :   mScrollThumbData = aThumbData;
     105         211 :   mIsScrollbarContainer = aIsScrollContainer;
     106         211 : }
     107             : 
     108             : bool
     109           0 : HitTestingTreeNode::MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const
     110             : {
     111           0 :   return IsScrollThumbNode() &&
     112           0 :          mScrollThumbData.mDirection == aDragMetrics.mDirection &&
     113           0 :          mScrollViewId == aDragMetrics.mViewId;
     114             : }
     115             : 
     116             : bool
     117          25 : HitTestingTreeNode::IsScrollThumbNode() const
     118             : {
     119          25 :   return mScrollThumbData.mDirection != ScrollDirection::NONE;
     120             : }
     121             : 
     122             : bool
     123          10 : HitTestingTreeNode::IsScrollbarNode() const
     124             : {
     125          10 :   return mIsScrollbarContainer || IsScrollThumbNode();
     126             : }
     127             : 
     128             : FrameMetrics::ViewID
     129           0 : HitTestingTreeNode::GetScrollTargetId() const
     130             : {
     131           0 :   return mScrollViewId;
     132             : }
     133             : 
     134             : const uint64_t&
     135           0 : HitTestingTreeNode::GetScrollbarAnimationId() const
     136             : {
     137           0 :   return mScrollbarAnimationId;
     138             : }
     139             : 
     140             : const ScrollThumbData&
     141           0 : HitTestingTreeNode::GetScrollThumbData() const
     142             : {
     143           0 :   return mScrollThumbData;
     144             : }
     145             : 
     146             : void
     147         211 : HitTestingTreeNode::SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget)
     148             : {
     149         211 :   mFixedPosTarget = aFixedPosTarget;
     150         211 : }
     151             : 
     152             : FrameMetrics::ViewID
     153           5 : HitTestingTreeNode::GetFixedPosTarget() const
     154             : {
     155           5 :   return mFixedPosTarget;
     156             : }
     157             : 
     158             : void
     159         125 : HitTestingTreeNode::SetPrevSibling(HitTestingTreeNode* aSibling)
     160             : {
     161         125 :   mPrevSibling = aSibling;
     162         125 :   if (aSibling) {
     163          93 :     aSibling->mParent = mParent;
     164             : 
     165          93 :     if (aSibling->GetApzc()) {
     166           5 :       AsyncPanZoomController* parent = mParent ? mParent->GetNearestContainingApzc() : nullptr;
     167           5 :       aSibling->SetApzcParent(parent);
     168             :     }
     169             :   }
     170         125 : }
     171             : 
     172             : void
     173          28 : HitTestingTreeNode::MakeRoot()
     174             : {
     175          28 :   mParent = nullptr;
     176             : 
     177          28 :   if (GetApzc()) {
     178          28 :     SetApzcParent(nullptr);
     179             :   }
     180          28 : }
     181             : 
     182             : HitTestingTreeNode*
     183         211 : HitTestingTreeNode::GetFirstChild() const
     184             : {
     185         211 :   HitTestingTreeNode* child = GetLastChild();
     186         211 :   while (child && child->GetPrevSibling()) {
     187           0 :     child = child->GetPrevSibling();
     188             :   }
     189         211 :   return child;
     190             : }
     191             : 
     192             : HitTestingTreeNode*
     193         444 : HitTestingTreeNode::GetLastChild() const
     194             : {
     195         444 :   return mLastChild;
     196             : }
     197             : 
     198             : HitTestingTreeNode*
     199         223 : HitTestingTreeNode::GetPrevSibling() const
     200             : {
     201         223 :   return mPrevSibling;
     202             : }
     203             : 
     204             : HitTestingTreeNode*
     205         248 : HitTestingTreeNode::GetParent() const
     206             : {
     207         248 :   return mParent;
     208             : }
     209             : 
     210             : bool
     211           0 : HitTestingTreeNode::IsAncestorOf(const HitTestingTreeNode* aOther) const
     212             : {
     213           0 :   for (const HitTestingTreeNode* cur = aOther; cur; cur = cur->GetParent()) {
     214           0 :     if (cur == this) {
     215           0 :       return true;
     216             :     }
     217             :   }
     218           0 :   return false;
     219             : }
     220             : 
     221             : AsyncPanZoomController*
     222         791 : HitTestingTreeNode::GetApzc() const
     223             : {
     224         791 :   return mApzc;
     225             : }
     226             : 
     227             : AsyncPanZoomController*
     228          11 : HitTestingTreeNode::GetNearestContainingApzc() const
     229             : {
     230          33 :   for (const HitTestingTreeNode* n = this; n; n = n->GetParent()) {
     231          33 :     if (n->GetApzc()) {
     232          11 :       return n->GetApzc();
     233             :     }
     234             :   }
     235           0 :   return nullptr;
     236             : }
     237             : 
     238             : bool
     239         277 : HitTestingTreeNode::IsPrimaryHolder() const
     240             : {
     241         277 :   return mIsPrimaryApzcHolder;
     242             : }
     243             : 
     244             : uint64_t
     245         231 : HitTestingTreeNode::GetLayersId() const
     246             : {
     247         231 :   return mLayersId;
     248             : }
     249             : 
     250             : void
     251         211 : HitTestingTreeNode::SetHitTestData(const EventRegions& aRegions,
     252             :                                    const LayerIntRegion& aVisibleRegion,
     253             :                                    const CSSTransformMatrix& aTransform,
     254             :                                    const Maybe<ParentLayerIntRegion>& aClipRegion,
     255             :                                    const EventRegionsOverride& aOverride)
     256             : {
     257         211 :   mEventRegions = aRegions;
     258         211 :   mVisibleRegion = aVisibleRegion;
     259         211 :   mTransform = aTransform;
     260         211 :   mClipRegion = aClipRegion;
     261         211 :   mOverride = aOverride;
     262         211 : }
     263             : 
     264             : bool
     265          21 : HitTestingTreeNode::IsOutsideClip(const ParentLayerPoint& aPoint) const
     266             : {
     267             :   // test against clip rect in ParentLayer coordinate space
     268          21 :   return (mClipRegion.isSome() && !mClipRegion->Contains(aPoint.x, aPoint.y));
     269             : }
     270             : 
     271             : Maybe<LayerPoint>
     272          20 : HitTestingTreeNode::Untransform(const ParentLayerPoint& aPoint,
     273             :                                 const LayerToParentLayerMatrix4x4& aTransform) const
     274             : {
     275          40 :   Maybe<ParentLayerToLayerMatrix4x4> inverse = aTransform.MaybeInverse();
     276          20 :   if (inverse) {
     277          20 :     return UntransformBy(inverse.ref(), aPoint);
     278             :   }
     279           0 :   return Nothing();
     280             : }
     281             : 
     282             : HitTestResult
     283          15 : HitTestingTreeNode::HitTest(const LayerPoint& aPoint) const
     284             : {
     285          15 :   if (mOverride & EventRegionsOverride::ForceEmptyHitRegion) {
     286           0 :     return HitTestResult::HitNothing;
     287             :   }
     288             : 
     289          15 :   auto point = LayerIntPoint::Round(aPoint);
     290             : 
     291             :   // test against event regions in Layer coordinate space
     292          15 :   if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) {
     293          10 :     return HitTestResult::HitNothing;
     294             :   }
     295          10 :   if ((mOverride & EventRegionsOverride::ForceDispatchToContent) ||
     296           5 :       mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y))
     297             :   {
     298           0 :     return HitTestResult::HitDispatchToContentRegion;
     299             :   }
     300           5 :   if (gfxPrefs::TouchActionEnabled()) {
     301           5 :     if (mEventRegions.mNoActionRegion.Contains(point.x, point.y)) {
     302           0 :       return HitTestResult::HitLayerTouchActionNone;
     303             :     }
     304           5 :     bool panX = mEventRegions.mHorizontalPanRegion.Contains(point.x, point.y);
     305           5 :     bool panY = mEventRegions.mVerticalPanRegion.Contains(point.x, point.y);
     306           5 :     if (panX && panY) {
     307           0 :       return HitTestResult::HitLayerTouchActionPanXY;
     308           5 :     } else if (panX) {
     309           0 :       return HitTestResult::HitLayerTouchActionPanX;
     310           5 :     } else if (panY) {
     311           0 :       return HitTestResult::HitLayerTouchActionPanY;
     312             :     }
     313             :   }
     314           5 :   return HitTestResult::HitLayer;
     315             : }
     316             : 
     317             : EventRegionsOverride
     318         183 : HitTestingTreeNode::GetEventRegionsOverride() const
     319             : {
     320         183 :   return mOverride;
     321             : }
     322             : 
     323             : const CSSTransformMatrix&
     324          20 : HitTestingTreeNode::GetTransform() const
     325             : {
     326          20 :   return mTransform;
     327             : }
     328             : 
     329             : const LayerIntRegion&
     330           0 : HitTestingTreeNode::GetVisibleRegion() const
     331             : {
     332           0 :   return mVisibleRegion;
     333             : }
     334             : 
     335             : void
     336           0 : HitTestingTreeNode::Dump(const char* aPrefix) const
     337             : {
     338           0 :   if (mPrevSibling) {
     339           0 :     mPrevSibling->Dump(aPrefix);
     340             :   }
     341           0 :   printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) %s%s%sr=(%s) t=(%s) c=(%s)\n",
     342             :     aPrefix, this, mApzc.get(),
     343           0 :     mApzc ? Stringify(mApzc->GetGuid()).c_str() : nsPrintfCString("l=%" PRIu64, mLayersId).get(),
     344           0 :     (mOverride & EventRegionsOverride::ForceDispatchToContent) ? "fdtc " : "",
     345           0 :     (mOverride & EventRegionsOverride::ForceEmptyHitRegion) ? "fehr " : "",
     346           0 :     (mFixedPosTarget != FrameMetrics::NULL_SCROLL_ID) ? nsPrintfCString("fixed=%" PRIu64 " ", mFixedPosTarget).get() : "",
     347           0 :     Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(),
     348           0 :     mClipRegion ? Stringify(mClipRegion.ref()).c_str() : "none");
     349           0 :   if (mLastChild) {
     350           0 :     mLastChild->Dump(nsPrintfCString("%s  ", aPrefix).get());
     351             :   }
     352           0 : }
     353             : 
     354             : void
     355          39 : HitTestingTreeNode::SetApzcParent(AsyncPanZoomController* aParent)
     356             : {
     357             :   // precondition: GetApzc() is non-null
     358          39 :   MOZ_ASSERT(GetApzc() != nullptr);
     359          39 :   if (IsPrimaryHolder()) {
     360          34 :     GetApzc()->SetParent(aParent);
     361             :   } else {
     362           5 :     MOZ_ASSERT(GetApzc()->GetParent() == aParent);
     363             :   }
     364          39 : }
     365             : 
     366             : } // namespace layers
     367             : } // namespace mozilla

Generated by: LCOV version 1.13