From e06065878469934af6999c39ce380f7eedc09235 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Tue, 10 Feb 2015 16:28:07 -0500 Subject: [PATCH] Bug 1125422 - Read the force-dispatch-to-content flag from the layer tree and use it in the APZ code. r=botond --- gfx/layers/LayerMetricsWrapper.h | 9 +++++++++ gfx/layers/apz/src/APZCTreeManager.cpp | 23 ++++++++++++++++++++--- gfx/layers/apz/src/HitTestingTreeNode.cpp | 18 +++++++++++++++--- gfx/layers/apz/src/HitTestingTreeNode.h | 10 +++++++++- 4 files changed, 53 insertions(+), 7 deletions(-) diff --git a/gfx/layers/LayerMetricsWrapper.h b/gfx/layers/LayerMetricsWrapper.h index b390b5eda95f..68cd5651aff1 100644 --- a/gfx/layers/LayerMetricsWrapper.h +++ b/gfx/layers/LayerMetricsWrapper.h @@ -338,6 +338,15 @@ public: return mLayer->GetClipRect(); } + bool GetForceDispatchToContentRegion() const { + MOZ_ASSERT(IsValid()); + + if (mLayer->AsContainerLayer()) { + return mLayer->AsContainerLayer()->GetForceDispatchToContentRegion(); + } + return false; + } + // Expose an opaque pointer to the layer. Mostly used for printf // purposes. This is not intended to be a general-purpose accessor // for the underlying layer. diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index a488ecaac6a4..6e4abbaf167d 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -320,6 +320,20 @@ APZCTreeManager::RecycleOrCreateNode(TreeBuildingState& aState, return node.forget(); } +static bool +ShouldForceDispatchToContent(HitTestingTreeNode* aParent, + const LayerMetricsWrapper& aLayer) +{ + // Make it so that if the flag is set on the layer tree, it automatically + // propagates to all the nodes in the corresponding subtree rooted at that + // layer in the hit-test tree. This saves having to walk up the tree every + // we want to see if a hit-test node is affected by this flag. + if (aParent && aParent->GetForceDispatchToContent()) { + return true; + } + return aLayer.GetForceDispatchToContentRegion(); +} + HitTestingTreeNode* APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, const FrameMetrics& aMetrics, @@ -344,7 +358,8 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, node = RecycleOrCreateNode(aState, nullptr); AttachNodeToTree(node, aParent, aNextSibling); node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), - aLayer.GetClipRect() ? Some(nsIntRegion(*aLayer.GetClipRect())) : Nothing()); + aLayer.GetClipRect() ? Some(nsIntRegion(*aLayer.GetClipRect())) : Nothing(), + ShouldForceDispatchToContent(aParent, aLayer)); return node; } @@ -440,7 +455,8 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, MOZ_ASSERT(node->IsPrimaryHolder() && node->GetApzc() && node->GetApzc()->Matches(guid)); nsIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer); - node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), Some(clipRegion)); + node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), Some(clipRegion), + ShouldForceDispatchToContent(aParent, aLayer)); apzc->SetAncestorTransform(aAncestorTransform); PrintAPZCInfo(aLayer, apzc); @@ -494,7 +510,8 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, MOZ_ASSERT(aAncestorTransform == apzc->GetAncestorTransform()); nsIntRegion clipRegion = ComputeClipRegion(state->mController, aLayer); - node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), Some(clipRegion)); + node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), Some(clipRegion), + ShouldForceDispatchToContent(aParent, aLayer)); } return node; diff --git a/gfx/layers/apz/src/HitTestingTreeNode.cpp b/gfx/layers/apz/src/HitTestingTreeNode.cpp index a20343bfe727..0ec356b40cee 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.cpp +++ b/gfx/layers/apz/src/HitTestingTreeNode.cpp @@ -21,6 +21,7 @@ HitTestingTreeNode::HitTestingTreeNode(AsyncPanZoomController* aApzc, bool aIsPrimaryHolder) : mApzc(aApzc) , mIsPrimaryApzcHolder(aIsPrimaryHolder) + , mForceDispatchToContent(false) { if (mIsPrimaryApzcHolder) { MOZ_ASSERT(mApzc); @@ -155,11 +156,13 @@ HitTestingTreeNode::IsPrimaryHolder() const void HitTestingTreeNode::SetHitTestData(const EventRegions& aRegions, const gfx::Matrix4x4& aTransform, - const Maybe& aClipRegion) + const Maybe& aClipRegion, + bool aForceDispatchToContent) { mEventRegions = aRegions; mTransform = aTransform; mClipRegion = aClipRegion; + mForceDispatchToContent = aForceDispatchToContent; } bool @@ -210,20 +213,29 @@ HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) { return HitTestResult::HitNothing; } - if (mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) { + if (mForceDispatchToContent || + mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) + { return HitTestResult::HitDispatchToContentRegion; } return HitTestResult::HitLayer; } +bool +HitTestingTreeNode::GetForceDispatchToContent() const +{ + return mForceDispatchToContent; +} + void HitTestingTreeNode::Dump(const char* aPrefix) const { if (mPrevSibling) { mPrevSibling->Dump(aPrefix); } - printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) r=(%s) t=(%s) c=(%s)\n", + printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) %sr=(%s) t=(%s) c=(%s)\n", aPrefix, this, mApzc.get(), mApzc ? Stringify(mApzc->GetGuid()).c_str() : "", + mForceDispatchToContent ? "fdtc " : "", Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(), mClipRegion ? Stringify(mClipRegion.ref()).c_str() : "none"); if (mLastChild) { diff --git a/gfx/layers/apz/src/HitTestingTreeNode.h b/gfx/layers/apz/src/HitTestingTreeNode.h index 0fbc4898875c..a517d5ceb107 100644 --- a/gfx/layers/apz/src/HitTestingTreeNode.h +++ b/gfx/layers/apz/src/HitTestingTreeNode.h @@ -81,7 +81,8 @@ public: void SetHitTestData(const EventRegions& aRegions, const gfx::Matrix4x4& aTransform, - const Maybe& aClipRegion); + const Maybe& aClipRegion, + bool aForceDispatchToContent); bool IsOutsideClip(const ParentLayerPoint& aPoint) const; /* Convert aPoint into the LayerPixel space for the layer corresponding to * this node. */ @@ -89,6 +90,8 @@ public: /* 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 mForceDispatchToContent flag. */ + bool GetForceDispatchToContent() const; /* Debug helpers */ void Dump(const char* aPrefix = "") const; @@ -122,6 +125,11 @@ private: * because we may use the composition bounds of the layer if the clip is not * present. This value is in L's ParentLayerPixels. */ Maybe mClipRegion; + + /* If this flag is set, then events to this node and the entire subtree under + * should always be treated as dispatch-to-content. + */ + bool mForceDispatchToContent; }; }