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 : #ifndef mozilla_layers_HitTestingTreeNode_h
8 : #define mozilla_layers_HitTestingTreeNode_h
9 :
10 : #include "APZUtils.h" // for HitTestResult
11 : #include "FrameMetrics.h" // for ScrollableLayerGuid
12 : #include "Layers.h"
13 : #include "mozilla/gfx/Matrix.h" // for Matrix4x4
14 : #include "mozilla/layers/LayersTypes.h" // for EventRegions
15 : #include "mozilla/Maybe.h" // for Maybe
16 : #include "mozilla/RefPtr.h" // for nsRefPtr
17 :
18 : namespace mozilla {
19 : namespace layers {
20 :
21 : class AsyncDragMetrics;
22 : class AsyncPanZoomController;
23 :
24 : /**
25 : * This class represents a node in a tree that is used by the APZCTreeManager
26 : * to do hit testing. The tree is roughly a copy of the layer tree, but will
27 : * contain multiple nodes in cases where the layer has multiple FrameMetrics.
28 : * In other words, the structure of this tree should be identical to the
29 : * LayerMetrics tree (see documentation in LayerMetricsWrapper.h).
30 : *
31 : * Not all HitTestingTreeNode instances will have an APZC associated with them;
32 : * only HitTestingTreeNodes that correspond to layers with scrollable metrics
33 : * have APZCs.
34 : * Multiple HitTestingTreeNode instances may share the same underlying APZC
35 : * instance if the layers they represent share the same scrollable metrics (i.e.
36 : * are part of the same animated geometry root). If this happens, exactly one of
37 : * the HitTestingTreeNode instances will be designated as the "primary holder"
38 : * of the APZC. When this primary holder is destroyed, it will destroy the APZC
39 : * along with it; in contrast, destroying non-primary-holder nodes will not
40 : * destroy the APZC.
41 : * Code should not make assumptions about which of the nodes will be the
42 : * primary holder, only that that there will be exactly one for each APZC in
43 : * the tree.
44 : *
45 : * The reason this tree exists at all is so that we can do hit-testing on the
46 : * thread that we receive input on (referred to the as the controller thread in
47 : * APZ terminology), which may be different from the compositor thread.
48 : * Accessing the compositor layer tree can only be done on the compositor
49 : * thread, and so it is simpler to make a copy of the hit-testing related
50 : * properties into a separate tree.
51 : */
52 : class HitTestingTreeNode {
53 1687 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HitTestingTreeNode);
54 :
55 : private:
56 : ~HitTestingTreeNode();
57 : public:
58 : HitTestingTreeNode(AsyncPanZoomController* aApzc, bool aIsPrimaryHolder,
59 : uint64_t aLayersId);
60 : void RecycleWith(AsyncPanZoomController* aApzc, uint64_t aLayersId);
61 : void Destroy();
62 :
63 : /* Tree construction methods */
64 :
65 : void SetLastChild(HitTestingTreeNode* aChild);
66 : void SetPrevSibling(HitTestingTreeNode* aSibling);
67 : void MakeRoot();
68 :
69 : /* Tree walking methods. GetFirstChild is O(n) in the number of children. The
70 : * other tree walking methods are all O(1). */
71 :
72 : HitTestingTreeNode* GetFirstChild() const;
73 : HitTestingTreeNode* GetLastChild() const;
74 : HitTestingTreeNode* GetPrevSibling() const;
75 : HitTestingTreeNode* GetParent() const;
76 :
77 : bool IsAncestorOf(const HitTestingTreeNode* aOther) const;
78 :
79 : /* APZC related methods */
80 :
81 : AsyncPanZoomController* GetApzc() const;
82 : AsyncPanZoomController* GetNearestContainingApzc() const;
83 : bool IsPrimaryHolder() const;
84 : uint64_t GetLayersId() const;
85 :
86 : /* Hit test related methods */
87 :
88 : void SetHitTestData(const EventRegions& aRegions,
89 : const LayerIntRegion& aVisibleRegion,
90 : const CSSTransformMatrix& aTransform,
91 : const Maybe<ParentLayerIntRegion>& aClipRegion,
92 : const EventRegionsOverride& aOverride);
93 : bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
94 :
95 : /* Scrollbar info */
96 :
97 : void SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
98 : const uint64_t& aScrollbarAnimationId,
99 : const ScrollThumbData& aThumbData,
100 : bool aIsScrollContainer);
101 : bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
102 : bool IsScrollbarNode() const; // Scroll thumb or scrollbar container layer.
103 : bool IsScrollThumbNode() const; // Scroll thumb container layer.
104 : FrameMetrics::ViewID GetScrollTargetId() const;
105 : const ScrollThumbData& GetScrollThumbData() const;
106 : const uint64_t& GetScrollbarAnimationId() const;
107 :
108 : /* Fixed pos info */
109 :
110 : void SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget);
111 : FrameMetrics::ViewID GetFixedPosTarget() const;
112 :
113 : /* Convert |aPoint| into the LayerPixel space for the layer corresponding to
114 : * this node. |aTransform| is the complete (content + async) transform for
115 : * this node. */
116 : Maybe<LayerPoint> Untransform(const ParentLayerPoint& aPoint,
117 : const LayerToParentLayerMatrix4x4& aTransform) const;
118 : /* Assuming aPoint is inside the clip region for this node, check which of the
119 : * event region spaces it falls inside. */
120 : HitTestResult HitTest(const LayerPoint& aPoint) const;
121 : /* Returns the mOverride flag. */
122 : EventRegionsOverride GetEventRegionsOverride() const;
123 : const CSSTransformMatrix& GetTransform() const;
124 : const LayerIntRegion& GetVisibleRegion() const;
125 :
126 : /* Debug helpers */
127 : void Dump(const char* aPrefix = "") const;
128 :
129 : private:
130 : void SetApzcParent(AsyncPanZoomController* aApzc);
131 :
132 : RefPtr<HitTestingTreeNode> mLastChild;
133 : RefPtr<HitTestingTreeNode> mPrevSibling;
134 : RefPtr<HitTestingTreeNode> mParent;
135 :
136 : RefPtr<AsyncPanZoomController> mApzc;
137 : bool mIsPrimaryApzcHolder;
138 :
139 : uint64_t mLayersId;
140 :
141 : // This is set for both scroll track and scroll thumb Container layers, and
142 : // represents the scroll id of the scroll frame scrolled by the scrollbar.
143 : FrameMetrics::ViewID mScrollViewId;
144 :
145 : // This is only set to non-zero if WebRender is enabled, and only for HTTNs
146 : // where IsScrollThumbNode() returns true. It holds the animation id that we
147 : // use to move the thumb node to reflect async scrolling.
148 : uint64_t mScrollbarAnimationId;
149 :
150 : // This is set for scroll thumb Container layers only.
151 : ScrollThumbData mScrollThumbData;
152 :
153 : // This is set for scroll track Container layers only.
154 : bool mIsScrollbarContainer;
155 :
156 : FrameMetrics::ViewID mFixedPosTarget;
157 :
158 : /* Let {L,M} be the {layer, scrollable metrics} pair that this node
159 : * corresponds to in the layer tree. mEventRegions contains the event regions
160 : * from L, in the case where event-regions are enabled. If event-regions are
161 : * disabled, it will contain the visible region of L, which we use as an
162 : * approximation to the hit region for the purposes of obscuring other layers.
163 : * This value is in L's LayerPixels.
164 : */
165 : EventRegions mEventRegions;
166 :
167 : LayerIntRegion mVisibleRegion;
168 :
169 : /* This is the transform from layer L. This does NOT include any async
170 : * transforms. */
171 : CSSTransformMatrix mTransform;
172 :
173 : /* This is clip rect for L that we wish to use for hit-testing purposes. Note
174 : * that this may not be exactly the same as the clip rect on layer L because
175 : * of the touch-sensitive region provided by the GeckoContentController, or
176 : * because we may use the composition bounds of the layer if the clip is not
177 : * present. This value is in L's ParentLayerPixels. */
178 : Maybe<ParentLayerIntRegion> mClipRegion;
179 :
180 : /* Indicates whether or not the event regions on this node need to be
181 : * overridden in a certain way. */
182 : EventRegionsOverride mOverride;
183 : };
184 :
185 : } // namespace layers
186 : } // namespace mozilla
187 :
188 : #endif // mozilla_layers_HitTestingTreeNode_h
|