summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/src/HitTestingTreeNode.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/apz/src/HitTestingTreeNode.h')
-rw-r--r--gfx/layers/apz/src/HitTestingTreeNode.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h
new file mode 100644
index 000000000..442751a8d
--- /dev/null
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_layers_HitTestingTreeNode_h
+#define mozilla_layers_HitTestingTreeNode_h
+
+#include "APZUtils.h" // for HitTestResult
+#include "FrameMetrics.h" // for ScrollableLayerGuid
+#include "Layers.h"
+#include "mozilla/gfx/Matrix.h" // for Matrix4x4
+#include "mozilla/layers/LayersTypes.h" // for EventRegions
+#include "mozilla/Maybe.h" // for Maybe
+#include "mozilla/RefPtr.h" // for nsRefPtr
+
+namespace mozilla {
+namespace layers {
+
+class AsyncDragMetrics;
+class AsyncPanZoomController;
+
+/**
+ * This class represents a node in a tree that is used by the APZCTreeManager
+ * to do hit testing. The tree is roughly a copy of the layer tree, but will
+ * contain multiple nodes in cases where the layer has multiple FrameMetrics.
+ * In other words, the structure of this tree should be identical to the
+ * LayerMetrics tree (see documentation in LayerMetricsWrapper.h).
+ *
+ * Not all HitTestingTreeNode instances will have an APZC associated with them;
+ * only HitTestingTreeNodes that correspond to layers with scrollable metrics
+ * have APZCs.
+ * Multiple HitTestingTreeNode instances may share the same underlying APZC
+ * instance if the layers they represent share the same scrollable metrics (i.e.
+ * are part of the same animated geometry root). If this happens, exactly one of
+ * the HitTestingTreeNode instances will be designated as the "primary holder"
+ * of the APZC. When this primary holder is destroyed, it will destroy the APZC
+ * along with it; in contrast, destroying non-primary-holder nodes will not
+ * destroy the APZC.
+ * Code should not make assumptions about which of the nodes will be the
+ * primary holder, only that that there will be exactly one for each APZC in
+ * the tree.
+ *
+ * The reason this tree exists at all is so that we can do hit-testing on the
+ * thread that we receive input on (referred to the as the controller thread in
+ * APZ terminology), which may be different from the compositor thread.
+ * Accessing the compositor layer tree can only be done on the compositor
+ * thread, and so it is simpler to make a copy of the hit-testing related
+ * properties into a separate tree.
+ */
+class HitTestingTreeNode {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(HitTestingTreeNode);
+
+private:
+ ~HitTestingTreeNode();
+public:
+ HitTestingTreeNode(AsyncPanZoomController* aApzc, bool aIsPrimaryHolder,
+ uint64_t aLayersId);
+ void RecycleWith(AsyncPanZoomController* aApzc, uint64_t aLayersId);
+ void Destroy();
+
+ /* Tree construction methods */
+
+ void SetLastChild(HitTestingTreeNode* aChild);
+ void SetPrevSibling(HitTestingTreeNode* aSibling);
+ void MakeRoot();
+
+ /* Tree walking methods. GetFirstChild is O(n) in the number of children. The
+ * other tree walking methods are all O(1). */
+
+ HitTestingTreeNode* GetFirstChild() const;
+ HitTestingTreeNode* GetLastChild() const;
+ HitTestingTreeNode* GetPrevSibling() const;
+ HitTestingTreeNode* GetParent() const;
+
+ /* APZC related methods */
+
+ AsyncPanZoomController* GetApzc() const;
+ AsyncPanZoomController* GetNearestContainingApzc() const;
+ bool IsPrimaryHolder() const;
+ uint64_t GetLayersId() const;
+
+ /* Hit test related methods */
+
+ void SetHitTestData(const EventRegions& aRegions,
+ const CSSTransformMatrix& aTransform,
+ const Maybe<ParentLayerIntRegion>& aClipRegion,
+ const EventRegionsOverride& aOverride);
+ bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
+
+ /* Scrollbar info */
+
+ void SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
+ Layer::ScrollDirection aDir,
+ int32_t aScrollSize,
+ bool aIsScrollContainer);
+ bool MatchesScrollDragMetrics(const AsyncDragMetrics& aDragMetrics) const;
+ int32_t GetScrollSize() const;
+ bool IsScrollbarNode() const;
+
+ /* Fixed pos info */
+
+ void SetFixedPosData(FrameMetrics::ViewID aFixedPosTarget);
+ FrameMetrics::ViewID GetFixedPosTarget() const;
+
+ /* Convert aPoint into the LayerPixel space for the layer corresponding to
+ * this node. */
+ Maybe<LayerPoint> Untransform(const ParentLayerPoint& aPoint) const;
+ /* Assuming aPoint is inside the clip region for this node, check which of the
+ * event region spaces it falls inside. */
+ HitTestResult HitTest(const ParentLayerPoint& aPoint) const;
+ /* Returns the mOverride flag. */
+ EventRegionsOverride GetEventRegionsOverride() const;
+
+ /* Debug helpers */
+ void Dump(const char* aPrefix = "") const;
+
+private:
+ void SetApzcParent(AsyncPanZoomController* aApzc);
+
+ RefPtr<HitTestingTreeNode> mLastChild;
+ RefPtr<HitTestingTreeNode> mPrevSibling;
+ RefPtr<HitTestingTreeNode> mParent;
+
+ RefPtr<AsyncPanZoomController> mApzc;
+ bool mIsPrimaryApzcHolder;
+
+ uint64_t mLayersId;
+
+ FrameMetrics::ViewID mScrollViewId;
+ Layer::ScrollDirection mScrollDir;
+ int32_t mScrollSize;
+ bool mIsScrollbarContainer;
+
+ FrameMetrics::ViewID mFixedPosTarget;
+
+ /* Let {L,M} be the {layer, scrollable metrics} pair that this node
+ * corresponds to in the layer tree. mEventRegions contains the event regions
+ * from L, in the case where event-regions are enabled. If event-regions are
+ * disabled, it will contain the visible region of L, which we use as an
+ * approximation to the hit region for the purposes of obscuring other layers.
+ * This value is in L's LayerPixels.
+ */
+ EventRegions mEventRegions;
+
+ /* This is the transform from layer L. This does NOT include any async
+ * transforms. */
+ CSSTransformMatrix mTransform;
+
+ /* This is clip rect for L that we wish to use for hit-testing purposes. Note
+ * that this may not be exactly the same as the clip rect on layer L because
+ * of the touch-sensitive region provided by the GeckoContentController, or
+ * because we may use the composition bounds of the layer if the clip is not
+ * present. This value is in L's ParentLayerPixels. */
+ Maybe<ParentLayerIntRegion> mClipRegion;
+
+ /* Indicates whether or not the event regions on this node need to be
+ * overridden in a certain way. */
+ EventRegionsOverride mOverride;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_HitTestingTreeNode_h