Bug 1352863 - Propagate the visible region from Layer to HitTestingTreeNode. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Wed, 24 May 2017 15:47:14 -0400
changeset 583908 4c63269480154a95d5faedf1b4972f7d3373cb5a
parent 583907 d26190c57e396671f68f679aa33aa1df0bfe5bea
child 583909 8e7c2255c1cf2661489cc7fee0013bb8297c8d06
push id60596
push userbballo@mozilla.com
push dateWed, 24 May 2017 19:49:24 +0000
reviewerskats
bugs1352863
milestone55.0a1
Bug 1352863 - Propagate the visible region from Layer to HitTestingTreeNode. r=kats The propagation happens via LayerMetricsWrapper or WebRenderScrollDataWrapper. MozReview-Commit-ID: GBZUnNn3zjN
gfx/layers/LayerMetricsWrapper.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/HitTestingTreeNode.cpp
gfx/layers/apz/src/HitTestingTreeNode.h
gfx/layers/wr/WebRenderScrollData.cpp
gfx/layers/wr/WebRenderScrollData.h
gfx/layers/wr/WebRenderScrollDataWrapper.h
--- 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();