Bug 1352863 - Propagate the visible region from Layer to HitTestingTreeNode. r=kats
The propagation happens via LayerMetricsWrapper or WebRenderScrollDataWrapper.
MozReview-Commit-ID: GBZUnNn3zjN
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -329,16 +329,29 @@ public:
MOZ_ASSERT(IsValid());
if (AtBottomLayer()) {
return mLayer->GetEventRegions();
}
return EventRegions();
}
+ LayerIntRegion GetVisibleRegion() const
+ {
+ MOZ_ASSERT(IsValid());
+
+ if (AtBottomLayer()) {
+ return mLayer->GetVisibleRegion();
+ }
+
+ return ViewAs<LayerPixel>(
+ TransformBy(mLayer->GetTransformTyped(), mLayer->GetVisibleRegion()),
+ PixelCastJustification::MovingDownToChildren);
+ }
+
bool HasTransformAnimation() const
{
MOZ_ASSERT(IsValid());
if (AtBottomLayer()) {
return mLayer->HasTransformAnimation();
}
return false;
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -621,16 +621,17 @@ APZCTreeManager::PrepareNodeForLayer(con
if (!needsApzc) {
// Note: if layer properties must be propagated to nodes, RecvUpdate in
// LayerTransactionParent.cpp must ensure that APZ will be notified
// when those properties change.
node = RecycleOrCreateNode(aState, nullptr, aLayersId);
AttachNodeToTree(node, aParent, aNextSibling);
node->SetHitTestData(
GetEventRegions(aLayer),
+ aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(),
GetEventRegionsOverride(aParent, aLayer));
node->SetScrollbarData(aLayer.GetScrollbarTargetContainerId(),
aLayer.GetScrollbarAnimationId(),
aLayer.GetScrollThumbData(),
aLayer.IsScrollbarContainer());
node->SetFixedPosData(aLayer.GetFixedPositionScrollContainerId());
@@ -732,16 +733,17 @@ APZCTreeManager::PrepareNodeForLayer(con
// Since this is the first time we are encountering an APZC with this guid,
// the node holding it must be the primary holder. It may be newly-created
// or not, depending on whether it went through the newApzc branch above.
MOZ_ASSERT(node->IsPrimaryHolder() && node->GetApzc() && node->GetApzc()->Matches(guid));
ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
node->SetHitTestData(
GetEventRegions(aLayer),
+ aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
Some(clipRegion),
GetEventRegionsOverride(aParent, aLayer));
apzc->SetAncestorTransform(aAncestorTransform);
PrintAPZCInfo(aLayer, apzc);
// Bind the APZC instance into the tree of APZCs
@@ -806,16 +808,17 @@ APZCTreeManager::PrepareNodeForLayer(con
// Due to floating point inaccuracies those transforms can end up not quite
// canceling each other. That's why we're using a fuzzy comparison here
// instead of an exact one.
MOZ_ASSERT(aAncestorTransform.FuzzyEqualsMultiplicative(apzc->GetAncestorTransform()));
ParentLayerIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer);
node->SetHitTestData(
GetEventRegions(aLayer),
+ aLayer.GetVisibleRegion(),
aLayer.GetTransformTyped(),
Some(clipRegion),
GetEventRegionsOverride(aParent, aLayer));
}
// Note: if layer properties must be propagated to nodes, RecvUpdate in
// LayerTransactionParent.cpp must ensure that APZ will be notified
// when those properties change.
--- a/gfx/layers/apz/src/HitTestingTreeNode.cpp
+++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp
@@ -244,21 +244,23 @@ HitTestingTreeNode::IsPrimaryHolder() co
uint64_t
HitTestingTreeNode::GetLayersId() const
{
return mLayersId;
}
void
HitTestingTreeNode::SetHitTestData(const EventRegions& aRegions,
+ const LayerIntRegion& aVisibleRegion,
const CSSTransformMatrix& aTransform,
const Maybe<ParentLayerIntRegion>& aClipRegion,
const EventRegionsOverride& aOverride)
{
mEventRegions = aRegions;
+ mVisibleRegion = aVisibleRegion;
mTransform = aTransform;
mClipRegion = aClipRegion;
mOverride = aOverride;
}
bool
HitTestingTreeNode::IsOutsideClip(const ParentLayerPoint& aPoint) const
{
@@ -319,16 +321,22 @@ HitTestingTreeNode::GetEventRegionsOverr
}
const CSSTransformMatrix&
HitTestingTreeNode::GetTransform() const
{
return mTransform;
}
+const LayerIntRegion&
+HitTestingTreeNode::GetVisibleRegion() const
+{
+ return mVisibleRegion;
+}
+
void
HitTestingTreeNode::Dump(const char* aPrefix) const
{
if (mPrevSibling) {
mPrevSibling->Dump(aPrefix);
}
printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) %s%s%sr=(%s) t=(%s) c=(%s)\n",
aPrefix, this, mApzc.get(),
--- a/gfx/layers/apz/src/HitTestingTreeNode.h
+++ b/gfx/layers/apz/src/HitTestingTreeNode.h
@@ -81,16 +81,17 @@ public:
AsyncPanZoomController* GetApzc() const;
AsyncPanZoomController* GetNearestContainingApzc() const;
bool IsPrimaryHolder() const;
uint64_t GetLayersId() const;
/* Hit test related methods */
void SetHitTestData(const EventRegions& aRegions,
+ const LayerIntRegion& aVisibleRegion,
const CSSTransformMatrix& aTransform,
const Maybe<ParentLayerIntRegion>& aClipRegion,
const EventRegionsOverride& aOverride);
bool IsOutsideClip(const ParentLayerPoint& aPoint) const;
/* Scrollbar info */
void SetScrollbarData(FrameMetrics::ViewID aScrollViewId,
@@ -115,16 +116,17 @@ public:
Maybe<LayerPoint> Untransform(const ParentLayerPoint& aPoint,
const LayerToParentLayerMatrix4x4& aTransform) const;
/* Assuming aPoint is inside the clip region for this node, check which of the
* event region spaces it falls inside. */
HitTestResult HitTest(const LayerPoint& aPoint) const;
/* Returns the mOverride flag. */
EventRegionsOverride GetEventRegionsOverride() const;
const CSSTransformMatrix& GetTransform() const;
+ const LayerIntRegion& GetVisibleRegion() const;
/* Debug helpers */
void Dump(const char* aPrefix = "") const;
private:
void SetApzcParent(AsyncPanZoomController* aApzc);
RefPtr<HitTestingTreeNode> mLastChild;
@@ -157,16 +159,18 @@ private:
* 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;
+ LayerIntRegion mVisibleRegion;
+
/* 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
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -32,16 +32,17 @@ WebRenderLayerScrollData::Initialize(Web
for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) {
mScrollIds.AppendElement(aOwner.AddMetadata(aLayer->GetScrollMetadata(i)));
}
mIsScrollInfoLayer = aLayer->AsContainerLayer() && !aLayer->GetFirstChild();
mTransform = aLayer->GetTransform();
mTransformIsPerspective = aLayer->GetTransformIsPerspective();
mEventRegions = aLayer->GetEventRegions();
+ mVisibleRegion = aLayer->GetVisibleRegion();
mReferentId = aLayer->AsRefLayer()
? Some(aLayer->AsRefLayer()->GetReferentId())
: Nothing();
mEventRegionsOverride = aLayer->AsContainerLayer()
? aLayer->AsContainerLayer()->GetEventRegionsOverride()
: EventRegionsOverride::NoOverride;
mScrollThumbData = aLayer->GetScrollThumbData();
mScrollbarAnimationId = aLayer->GetCompositorAnimationsId();
@@ -66,16 +67,22 @@ WebRenderLayerScrollData::GetScrollMetad
const ScrollMetadata&
WebRenderLayerScrollData::GetScrollMetadata(const WebRenderScrollData& aOwner,
size_t aIndex) const
{
MOZ_ASSERT(aIndex < mScrollIds.Length());
return aOwner.GetScrollMetadata(mScrollIds[aIndex]);
}
+CSSTransformMatrix
+WebRenderLayerScrollData::GetTransformTyped() const
+{
+ return ViewAs<CSSTransformMatrix>(GetTransform());
+}
+
WebRenderScrollData::WebRenderScrollData()
: mIsFirstPaint(false)
{
}
WebRenderScrollData::~WebRenderScrollData()
{
}
--- a/gfx/layers/wr/WebRenderScrollData.h
+++ b/gfx/layers/wr/WebRenderScrollData.h
@@ -44,18 +44,20 @@ public:
// at the given index. Since we deduplicate the ScrollMetadata objects into
// the array in the owning WebRenderScrollData object, we need to be passed
// in a reference to that owner as well.
const ScrollMetadata& GetScrollMetadata(const WebRenderScrollData& aOwner,
size_t aIndex) const;
bool IsScrollInfoLayer() const { return mIsScrollInfoLayer; }
gfx::Matrix4x4 GetTransform() const { return mTransform; }
+ CSSTransformMatrix GetTransformTyped() const;
bool GetTransformIsPerspective() const { return mTransformIsPerspective; }
EventRegions GetEventRegions() const { return mEventRegions; }
+ const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
Maybe<uint64_t> GetReferentId() const { return mReferentId; }
EventRegionsOverride GetEventRegionsOverride() const { return mEventRegionsOverride; }
const ScrollThumbData& GetScrollThumbData() const { return mScrollThumbData; }
const uint64_t& GetScrollbarAnimationId() const { return mScrollbarAnimationId; }
FrameMetrics::ViewID GetScrollbarTargetContainerId() const { return mScrollbarTargetContainerId; }
bool IsScrollbarContainer() const { return mIsScrollbarContainer; }
FrameMetrics::ViewID GetFixedPositionScrollContainerId() const { return mFixedPosScrollContainerId; }
@@ -76,16 +78,17 @@ private:
// Various data that we collect from the Layer in Initialize(), serialize
// over IPC, and use on the parent side in APZ.
bool mIsScrollInfoLayer;
gfx::Matrix4x4 mTransform;
bool mTransformIsPerspective;
EventRegions mEventRegions;
+ LayerIntRegion mVisibleRegion;
Maybe<uint64_t> mReferentId;
EventRegionsOverride mEventRegionsOverride;
ScrollThumbData mScrollThumbData;
uint64_t mScrollbarAnimationId;
FrameMetrics::ViewID mScrollbarTargetContainerId;
bool mIsScrollbarContainer;
FrameMetrics::ViewID mFixedPosScrollContainerId;
};
@@ -170,16 +173,17 @@ struct ParamTraits<mozilla::layers::WebR
Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mDescendantCount);
WriteParam(aMsg, aParam.mScrollIds);
WriteParam(aMsg, aParam.mIsScrollInfoLayer);
WriteParam(aMsg, aParam.mTransform);
WriteParam(aMsg, aParam.mTransformIsPerspective);
WriteParam(aMsg, aParam.mEventRegions);
+ WriteParam(aMsg, aParam.mVisibleRegion);
WriteParam(aMsg, aParam.mReferentId);
WriteParam(aMsg, aParam.mEventRegionsOverride);
WriteParam(aMsg, aParam.mScrollThumbData);
WriteParam(aMsg, aParam.mScrollbarAnimationId);
WriteParam(aMsg, aParam.mScrollbarTargetContainerId);
WriteParam(aMsg, aParam.mIsScrollbarContainer);
WriteParam(aMsg, aParam.mFixedPosScrollContainerId);
}
@@ -188,16 +192,17 @@ struct ParamTraits<mozilla::layers::WebR
Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mDescendantCount)
&& ReadParam(aMsg, aIter, &aResult->mScrollIds)
&& ReadParam(aMsg, aIter, &aResult->mIsScrollInfoLayer)
&& ReadParam(aMsg, aIter, &aResult->mTransform)
&& ReadParam(aMsg, aIter, &aResult->mTransformIsPerspective)
&& ReadParam(aMsg, aIter, &aResult->mEventRegions)
+ && ReadParam(aMsg, aIter, &aResult->mVisibleRegion)
&& ReadParam(aMsg, aIter, &aResult->mReferentId)
&& ReadParam(aMsg, aIter, &aResult->mEventRegionsOverride)
&& ReadParam(aMsg, aIter, &aResult->mScrollThumbData)
&& ReadParam(aMsg, aIter, &aResult->mScrollbarAnimationId)
&& ReadParam(aMsg, aIter, &aResult->mScrollbarTargetContainerId)
&& ReadParam(aMsg, aIter, &aResult->mIsScrollbarContainer)
&& ReadParam(aMsg, aIter, &aResult->mFixedPosScrollContainerId);
}
--- a/gfx/layers/wr/WebRenderScrollDataWrapper.h
+++ b/gfx/layers/wr/WebRenderScrollDataWrapper.h
@@ -252,16 +252,29 @@ public:
MOZ_ASSERT(IsValid());
if (AtBottomLayer()) {
return mLayer->GetEventRegions();
}
return EventRegions();
}
+ LayerIntRegion GetVisibleRegion() const
+ {
+ MOZ_ASSERT(IsValid());
+
+ if (AtBottomLayer()) {
+ return mLayer->GetVisibleRegion();
+ }
+
+ return ViewAs<LayerPixel>(
+ TransformBy(mLayer->GetTransformTyped(), mLayer->GetVisibleRegion()),
+ PixelCastJustification::MovingDownToChildren);
+ }
+
Maybe<uint64_t> GetReferentId() const
{
MOZ_ASSERT(IsValid());
if (AtBottomLayer()) {
return mLayer->GetReferentId();
}
return Nothing();