Bug 1109873 - Move hit-testing data into HitTestingTreeNode. r=botond

This commit is contained in:
Kartikaya Gupta 2015-01-08 09:40:01 -05:00
Родитель 6f37e44194
Коммит e0077ec0d4
5 изменённых файлов: 196 добавлений и 106 удалений

Просмотреть файл

@ -390,17 +390,13 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
// or not, depending on whether it went through the newApzc branch above.
MOZ_ASSERT(node->IsPrimaryHolder() && node->Apzc()->Matches(guid));
nsIntRegion unobscured;
if (!gfxPrefs::LayoutEventRegionsEnabled()) {
unobscured = ComputeTouchSensitiveRegion(state->mController, aMetrics, aObscured);
nsIntRegion unobscured = ComputeTouchSensitiveRegion(state->mController, aMetrics, aObscured);
node->SetHitTestData(EventRegions(), Matrix4x4(), unobscured);
APZCTM_LOG("Setting region %s as visible region for APZC %p (node %p)\n",
Stringify(unobscured).c_str(), apzc, node.get());
}
// This initializes, among other things, the APZC's hit-region.
// If event-regions are disabled, this will initialize it to the empty
// region, but UpdatePanZoomControllerTree will add the hit-region from
// the event regions later.
apzc->SetLayerHitTestData(EventRegions(unobscured), aAncestorTransform);
APZCTM_LOG("Setting region %s as visible region for APZC %p\n",
Stringify(unobscured).c_str(), apzc);
apzc->SetAncestorTransform(aAncestorTransform);
PrintAPZCInfo(aLayer, apzc);
@ -442,18 +438,6 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
// We already built an APZC earlier in this tree walk, but we have another layer
// now that will also be using that APZC. The hit-test region on the APZC needs
// to be updated to deal with the new layer's hit region.
// FIXME: Combining this hit test region to the existing hit test region has a bit
// of a problem, because it assumes the z-index of this new region is the same as
// the z-index of the old region (from the previous layer with the same scrollid)
// when in fact that may not be the case.
// Consider the case where we have three layers: A, B, and C. A is at the top in
// z-order and C is at the bottom. A and C share a scrollid and scroll together; but
// B has a different scrollid and scrolls independently. Depending on how B moves
// and the async transform on it, a larger/smaller area of C may be unobscured.
// However, when we combine the hit regions of A and C here we are ignoring the
// async transform and so we basically assume the same amount of C is always visible
// on top of B. Fixing this doesn't appear to be very easy so I'm leaving it for
// now in the hopes that we won't run into this problem a lot.
// TODO(optimization): we could recycle one of the non-primary-holder nodes
// from mNodesToDestroy instead of creating a new one since those are going
@ -469,8 +453,9 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer,
if (!gfxPrefs::LayoutEventRegionsEnabled()) {
nsIntRegion unobscured = ComputeTouchSensitiveRegion(state->mController, aMetrics, aObscured);
apzc->AddHitTestRegions(EventRegions(unobscured));
APZCTM_LOG("Adding region %s to visible region of APZC %p\n", Stringify(unobscured).c_str(), apzc);
node->SetHitTestData(EventRegions(), Matrix4x4(), unobscured);
APZCTM_LOG("Adding region %s to visible region of APZC %p (via node %p)\n",
Stringify(unobscured).c_str(), apzc, node.get());
}
}
@ -513,11 +498,13 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
uint64_t childLayersId = (aLayer.AsRefLayer() ? aLayer.AsRefLayer()->GetReferentId() : aLayersId);
nsIntRegion obscured;
nsIntRegion obscuredByUncles;
if (aLayersId == childLayersId) {
// If the child layer is in the same process, transform
// aObscured from aLayer's ParentLayerPixels to aLayer's LayerPixels,
// which are the children layers' ParentLayerPixels.
// If the child layer is in the same process, keep a copy of |aObscured|.
// This value is in ParentLayerPixels and represents the area that is
// obscured by |aLayer|'s younger uncles (i.e. any next-siblings of any
// ancestor of |aLayer|) in the same process. We will need this value later.
// If we cross a process boundary, we assume that we can start with
// an empty obscured region because nothing in the parent process will
// obscure the child process. This may be false. However, not doing this
@ -526,8 +513,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
// all child processes, even though visually they do not. We'd probably
// have to check for mask layers and so on in order to properly handle
// that case.
obscured = aObscured;
obscured.Transform(To3DMatrix(transform).Inverse());
obscuredByUncles = aObscured;
}
// If there's no APZC at this level, any APZCs for our child layers will
@ -553,6 +539,9 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
aState.mEventRegions.AppendElement(EventRegions());
}
// Convert the obscured region into this layer's LayerPixels.
nsIntRegion obscured = obscuredByUncles;
obscured.Transform(To3DMatrix(transform).Inverse());
for (LayerMetricsWrapper child = aLayer.GetLastChild(); child; child = child.GetPrevSibling()) {
gfx::TreeAutoIndent indent(mApzcTreeLog);
next = UpdatePanZoomControllerTree(aState, child, childLayersId,
@ -585,39 +574,42 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
// way we do hit-testing (where the deepest matching APZC is used) it should
// still be ok if we did propagate those regions upwards and included them
// in all the ancestor APZCs.
//
// Also at this point in the code the |obscured| region includes the hit
// regions of children of |aLayer| as well as the hit regions of |aLayer|'s
// younger uncles (i.e. the next-sibling chains of |aLayer|'s ancestors).
// When we compute the unobscured regions below, we subtract off the
// |obscured| region, but it would also be ok to do this before the above
// loop. At that point |obscured| would only have the uncles' hit regions
// and not the children. The reason this is ok is again because of the way
// we do hit-testing (where the deepest APZC is used) it doesn't matter if
// we count the children as obscuring the parent or not.
EventRegions unobscured;
unobscured.Sub(aLayer.GetEventRegions(), obscured);
APZCTM_LOG("Picking up unobscured hit region %s from layer %p\n", Stringify(unobscured).c_str(), aLayer.GetLayer());
// Take the hit region of the |aLayer|'s subtree (which has already been
// transformed into the coordinate space of |aLayer|) and...
EventRegions subtreeEventRegions = aState.mEventRegions.LastElement();
aState.mEventRegions.RemoveElementAt(aState.mEventRegions.Length() - 1);
// ... combine it with the hit region for this layer, and then ...
subtreeEventRegions.OrWith(unobscured);
// ... transform it up to the parent layer's coordinate space.
subtreeEventRegions.Transform(To3DMatrix(aLayer.GetTransform()));
if (aLayer.GetClipRect()) {
subtreeEventRegions.AndWith(*aLayer.GetClipRect());
}
APZCTM_LOG("After processing layer %p the subtree hit region is %s\n", aLayer.GetLayer(), Stringify(subtreeEventRegions).c_str());
// ... combine it with the event region for this layer.
subtreeEventRegions.OrWith(aLayer.GetEventRegions());
// If we have an APZC at this level, intersect the subtree hit region with
// the touch-sensitive region and add it to the APZ's hit test regions.
if (apzc) {
APZCTM_LOG("Adding region %s to visible region of APZC %p\n", Stringify(subtreeEventRegions).c_str(), apzc);
if (node) {
// At this point in the code we have two different "obscured" regions.
// There is |obscuredByUncles| which represents the hit regions of
// |aLayer|'s younger uncles (i.e. the next-sibling chains of |aLayer|'s
// ancestors). This obscured region does not move when aLayer is scrolled,
// and so is in the same ParentLayerPixel coordinate space as |aLayer|'s
// clip rect.
// We also have |obscured| which includes the hit regions of |aLayer|'s
// descendants. However we don't want to use this because those
// descendants (and their hit regions) move as |aLayer| scrolls.
// From |aLayer|'s point of view |obscured| is in a nonsensical coordinate
// space because it combines the uncle-obscured region and child-obscured
// regions.
// We combine the |obscuredByUncles| region with the clip rect of |aLayer|
// below, to "apply" the obscuration by the uncles.
nsIntRegion clipRegion;
if (aLayer.GetClipRect()) {
clipRegion = nsIntRegion(*aLayer.GetClipRect());
} else {
// if there is no clip on this layer (which should only happen for the
// root scrollable layer in a process) fall back to using the comp
// bounds which should be equivalent.
clipRegion = nsIntRegion(ParentLayerIntRect::ToUntyped(RoundedToInt(aLayer.Metrics().mCompositionBounds)));
}
clipRegion.SubOut(obscuredByUncles);
const CompositorParent::LayerTreeState* state = CompositorParent::GetIndirectShadowTree(aLayersId);
MOZ_ASSERT(state);
MOZ_ASSERT(state->mController.get());
@ -632,16 +624,24 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
LayoutDeviceToParentLayerScale parentCumulativeResolution =
aLayer.Metrics().GetCumulativeResolution()
/ ParentLayerToLayerScale(aLayer.Metrics().mPresShellResolution);
subtreeEventRegions.AndWith(ParentLayerIntRect::ToUntyped(
clipRegion.AndWith(ParentLayerIntRect::ToUntyped(
RoundedIn(touchSensitiveRegion
* aLayer.Metrics().GetDevPixelsPerCSSPixel()
* parentCumulativeResolution)));
}
apzc->AddHitTestRegions(subtreeEventRegions);
node->SetHitTestData(subtreeEventRegions, aLayer.GetTransform(), clipRegion);
APZCTM_LOG("After processing layer %p the event regions for %p is %s\n",
aLayer.GetLayer(), node, Stringify(subtreeEventRegions).c_str());
} else {
// If we don't have an APZC at this level, carry the subtree hit region
// up to the parent.
MOZ_ASSERT(aState.mEventRegions.Length() > 0);
// transform it up to the parent layer's coordinate space.
subtreeEventRegions.Transform(To3DMatrix(aLayer.GetTransform()));
if (aLayer.GetClipRect()) {
subtreeEventRegions.AndWith(*aLayer.GetClipRect());
}
aState.mEventRegions.LastElement().OrWith(subtreeEventRegions);
}
}
@ -1333,13 +1333,19 @@ APZCTreeManager::GetTargetAPZC(const ScreenPoint& aPoint, HitTestResult* aOutHit
HitTestResult hitResult = NoApzcHit;
for (HitTestingTreeNode* node = mRootNode; node; node = node->GetPrevSibling()) {
target = GetAPZCAtPoint(node, aPoint.ToUnknownPoint(), &hitResult);
if (target == node->Apzc() && node->GetPrevSibling() && target == node->GetPrevSibling()->Apzc()) {
// We might be able to do better if we keep looping, so let's do that.
// This happens because the hit-test data stored in "target" actually
// includes the areas of all the nodes that have "target" as their APZC.
// One of these nodes (that we haven't yet encountered) may have a child
// that is on top of this area, so we need to check for that. A future
// patch will deal with this more correctly.
if (!gfxPrefs::LayoutEventRegionsEnabled() && target == node->Apzc()
&& node->GetPrevSibling() && target == node->GetPrevSibling()->Apzc()) {
// When event-regions are disabled, we treat scrollinfo layers as
// regular scrollable layers. Unfortunately, their "hit region" (which
// we create from the composition bounds) is their full area, and they
// sit on top of their non-scrollinfo siblings. This means they will get
// a HitTestingTreeNode with a hit region that will aggressively match
// any input events that might be directed to sub-APZCs of their non-
// scrollinfo siblings. This means that we need to keep looping through
// to see if there are any other non-scrollinfo siblings that have
// children that match this event. If so, they should take priority.
// Once we turn on event-regions and ignore scrollinfo layers, this
// will become unnecessary.
continue;
}
// If we hit an overscrolled APZC, 'target' will be nullptr but it's still
@ -1485,7 +1491,7 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
// since the composition bounds (used to initialize the visible rect against
// which we hit test are in those coordinates).
Point4D hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
APZCTM_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
APZCTM_LOG("Untransformed %f %f to parentlayer coordinates %f %f for hit-testing APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, apzc);
@ -1505,13 +1511,19 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
if (hitTestPointForChildLayers.HasPositiveWCoord()) {
for (HitTestingTreeNode* child = aNode->GetLastChild(); child; child = child->GetPrevSibling()) {
AsyncPanZoomController* match = GetAPZCAtPoint(child, hitTestPointForChildLayers.As2DPoint(), aOutHitResult);
if (match == child->Apzc() && child->GetPrevSibling() && match == child->GetPrevSibling()->Apzc()) {
// We might be able to do better if we keep looping, so let's do that.
// This happens because the hit-test data stored in "target" actually
// includes the areas of all the nodes that have "target" as their APZC.
// One of these nodes (that we haven't yet encountered) may have a child
// that is on top of this area, so we need to check for that. A future
// patch will deal with this more correctly.
if (!gfxPrefs::LayoutEventRegionsEnabled() && match == aNode->Apzc()
&& aNode->GetPrevSibling() && match == aNode->GetPrevSibling()->Apzc()) {
// When event-regions are disabled, we treat scrollinfo layers as
// regular scrollable layers. Unfortunately, their "hit region" (which
// we create from the composition bounds) is their full area, and they
// sit on top of their non-scrollinfo siblings. This means they will get
// a HitTestingTreeNode with a hit region that will aggressively match
// any input events that might be directed to sub-APZCs of their non-
// scrollinfo siblings. This means that we need to keep looping through
// to see if there are any other non-scrollinfo siblings that have
// children that match this event. If so, they should take priority.
// Once we turn on event-regions and ignore scrollinfo layers, this
// will become unnecessary.
continue;
}
if (*aOutHitResult == OverscrolledApzc) {
@ -1526,12 +1538,14 @@ APZCTreeManager::GetAPZCAtPoint(HitTestingTreeNode* aNode,
}
if (!result && hitTestPointForThisLayer.HasPositiveWCoord()) {
ParentLayerPoint point = ParentLayerPoint::FromUnknownPoint(hitTestPointForThisLayer.As2DPoint());
if (apzc->HitRegionContains(point)) {
APZCTM_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n",
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, apzc);
HitTestResult hitResult = aNode->HitTest(point);
if (hitResult != HitTestResult::NoApzcHit) {
APZCTM_LOG("Successfully matched untransformed point %s to visible region for APZC %p via node %p\n",
Stringify(hitTestPointForThisLayer.As2DPoint()).c_str(), apzc, aNode);
result = apzc;
MOZ_ASSERT(hitResult == ApzcHitRegion || hitResult == ApzcContentRegion);
// If event regions are disabled, *aOutHitResult will be ApzcHitRegion
*aOutHitResult = (apzc->DispatchToContentRegionContains(point) ? ApzcContentRegion : ApzcHitRegion);
*aOutHitResult = hitResult;
}
}

Просмотреть файл

@ -970,39 +970,19 @@ private:
* hit-testing to see which APZC instance should handle touch events.
*/
public:
void SetLayerHitTestData(const EventRegions& aRegions, const Matrix4x4& aTransformToLayer) {
mEventRegions = aRegions;
void SetAncestorTransform(const Matrix4x4& aTransformToLayer) {
mAncestorTransform = aTransformToLayer;
}
void AddHitTestRegions(const EventRegions& aRegions) {
mEventRegions.OrWith(aRegions);
}
Matrix4x4 GetAncestorTransform() const {
return mAncestorTransform;
}
bool HitRegionContains(const ParentLayerPoint& aPoint) const {
ParentLayerIntPoint point = RoundedToInt(aPoint);
return mEventRegions.mHitRegion.Contains(point.x, point.y);
}
bool DispatchToContentRegionContains(const ParentLayerPoint& aPoint) const {
ParentLayerIntPoint point = RoundedToInt(aPoint);
return mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y);
}
bool IsOverscrolled() const {
return mX.IsOverscrolled() || mY.IsOverscrolled();
}
private:
/* This is the union of the hit regions of the layers that this APZC
* corresponds to, in the local screen pixels of those layers. (This is the
* same coordinate system in which this APZC receives events in
* ReceiveInputEvent()). */
EventRegions mEventRegions;
/* This is the cumulative CSS transform for all the layers from (and including)
* the parent APZC down to (but excluding) this one. */
Matrix4x4 mAncestorTransform;

Просмотреть файл

@ -6,9 +6,12 @@
#include "HitTestingTreeNode.h"
#include "AsyncPanZoomController.h"
#include "LayersLogging.h"
#include "nsPrintfCString.h"
#include "AsyncPanZoomController.h" // for AsyncPanZoomController
#include "LayersLogging.h" // for Stringify
#include "mozilla/gfx/Point.h" // for Point4D
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform::operator Matrix4x4()
#include "nsPrintfCString.h" // for nsPrintfCString
#include "UnitTransforms.h" // for ViewAs
namespace mozilla {
namespace layers {
@ -115,14 +118,63 @@ HitTestingTreeNode::IsPrimaryHolder() const
return mIsPrimaryApzcHolder;
}
void
HitTestingTreeNode::SetHitTestData(const EventRegions& aRegions,
const gfx::Matrix4x4& aTransform,
const nsIntRegion& aClipRegion)
{
mEventRegions = aRegions;
mTransform = aTransform;
mClipRegion = aClipRegion;
}
HitTestResult
HitTestingTreeNode::HitTest(const ParentLayerPoint& aPoint) const
{
// When event regions are disabled, we are actually storing the
// touch-sensitive section of the composition bounds in the clip rect, and we
// don't need to use mTransform or mEventRegions.
if (!gfxPrefs::LayoutEventRegionsEnabled()) {
MOZ_ASSERT(mEventRegions == EventRegions());
MOZ_ASSERT(mTransform == gfx::Matrix4x4());
return mClipRegion.Contains(aPoint.x, aPoint.y)
? HitTestResult::ApzcHitRegion
: HitTestResult::NoApzcHit;
}
// test against clip rect in ParentLayer coordinate space
if (!mClipRegion.Contains(aPoint.x, aPoint.y)) {
return HitTestResult::NoApzcHit;
}
// convert into Layer coordinate space
gfx::Matrix4x4 localTransform = mTransform * gfx::Matrix4x4(mApzc->GetCurrentAsyncTransform());
gfx::Point4D pointInLayerPixels = localTransform.Inverse().ProjectPoint(aPoint.ToUnknownPoint());
if (!pointInLayerPixels.HasPositiveWCoord()) {
return HitTestResult::NoApzcHit;
}
LayerIntPoint point = RoundedToInt(ViewAs<LayerPixel>(pointInLayerPixels.As2DPoint()));
// test against event regions in Layer coordinate space
if (!mEventRegions.mHitRegion.Contains(point.x, point.y)) {
return HitTestResult::NoApzcHit;
}
if (mEventRegions.mDispatchToContentHitRegion.Contains(point.x, point.y)) {
return HitTestResult::ApzcContentRegion;
}
return HitTestResult::ApzcHitRegion;
}
void
HitTestingTreeNode::Dump(const char* aPrefix) const
{
if (mPrevSibling) {
mPrevSibling->Dump(aPrefix);
}
printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) guid (%s)\n",
aPrefix, this, mApzc.get(), Stringify(mApzc->GetGuid()).c_str());
printf_stderr("%sHitTestingTreeNode (%p) APZC (%p) g=(%s) r=(%s) t=(%s) c=(%s)\n",
aPrefix, this, mApzc.get(), Stringify(mApzc->GetGuid()).c_str(),
Stringify(mEventRegions).c_str(), Stringify(mTransform).c_str(),
Stringify(mClipRegion).c_str());
if (mLastChild) {
mLastChild->Dump(nsPrintfCString("%s ", aPrefix).get());
}

Просмотреть файл

@ -7,8 +7,11 @@
#ifndef mozilla_layers_HitTestingTreeNode_h
#define mozilla_layers_HitTestingTreeNode_h
#include "FrameMetrics.h"
#include "nsRefPtr.h"
#include "APZUtils.h" // for HitTestResult
#include "FrameMetrics.h" // for ScrollableLayerGuid
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/layers/LayersTypes.h" // for EventRegions
#include "nsRefPtr.h" // for nsRefPtr
namespace mozilla {
namespace layers {
@ -67,6 +70,12 @@ public:
AsyncPanZoomController* Apzc() const;
bool IsPrimaryHolder() const;
/* Hit test related methods */
void SetHitTestData(const EventRegions& aRegions,
const gfx::Matrix4x4& aTransform,
const nsIntRegion& aClipRegion);
HitTestResult HitTest(const ParentLayerPoint& aPoint) const;
/* Debug helpers */
void Dump(const char* aPrefix = "") const;
@ -77,6 +86,32 @@ private:
nsRefPtr<AsyncPanZoomController> mApzc;
bool mIsPrimaryApzcHolder;
/* Let {L,M} be the {layer, scrollable metrics} pair that this node
* corresponds to in the layer tree. Then, mEventRegions contains the union
* of the event regions of all layers in L's subtree, excluding those layers
* which are contained in a descendant HitTestingTreeNode's mEventRegions.
* This value is stored in L's LayerPixel space.
* For example, if this HitTestingTreeNode maps to a ContainerLayer with
* scrollable metrics and which has two PaintedLayer children, the event
* regions stored here will be the union of the three event regions in the
* ContainerLayer's layer pixel space. This means the event regions from the
* PaintedLayer children will have been transformed and clipped according to
* the individual properties on those layers but the ContainerLayer's event
* regions will be used "raw". */
EventRegions mEventRegions;
/* This is the transform that the layer subtree corresponding to this node is
* subject to. In the terms of the comment on mEventRegions, it is the
* transform from the ContainerLayer. This does NOT include any async
* transforms. */
gfx::Matrix4x4 mTransform;
/* This is the clip rect that the layer subtree corresponding to this node
* is subject to. In the terms of the comment on mEventRegions, it is the clip
* rect of the ContainerLayer, and is in the ContainerLayer's ParentLayerPixel
* space. */
nsIntRegion mClipRegion;
};
}

Просмотреть файл

@ -1688,6 +1688,7 @@ protected:
metrics.SetScrollableRect(aScrollableRect);
metrics.SetScrollOffset(CSSPoint(0, 0));
aLayer->SetFrameMetrics(metrics);
aLayer->SetClipRect(&layerBound);
if (!aScrollableRect.IsEqualEdges(CSSRect(-1, -1, -1, -1))) {
// The purpose of this is to roughly mimic what layout would do in the
// case of a scrollable frame with the event regions and clip. This lets
@ -1696,7 +1697,6 @@ protected:
nsIntRect scrollRect = LayerIntRect::ToUntyped(RoundedToInt(aScrollableRect * metrics.LayersPixelsPerCSSPixel()));
er.mHitRegion = nsIntRegion(nsIntRect(layerBound.TopLeft(), scrollRect.Size()));
aLayer->SetEventRegions(er);
aLayer->SetClipRect(&layerBound);
}
}
@ -2444,7 +2444,12 @@ protected:
void CreateEventRegionsLayerTree1() {
const char* layerTreeSyntax = "c(tt)";
root = CreateLayerTree(layerTreeSyntax, nullptr, nullptr, lm, layers);
nsIntRegion layerVisibleRegions[] = {
nsIntRegion(nsIntRect(0, 0, 200, 200)), // root
nsIntRegion(nsIntRect(0, 0, 100, 200)), // left half
nsIntRegion(nsIntRect(0, 100, 200, 100)), // bottom half
};
root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID + 1);
SetScrollableFrameMetrics(layers[2], FrameMetrics::START_SCROLL_ID + 2);
@ -2472,7 +2477,11 @@ protected:
void CreateEventRegionsLayerTree2() {
const char* layerTreeSyntax = "c(t)";
root = CreateLayerTree(layerTreeSyntax, nullptr, nullptr, lm, layers);
nsIntRegion layerVisibleRegions[] = {
nsIntRegion(nsIntRect(0, 0, 100, 500)),
nsIntRegion(nsIntRect(0, 150, 100, 100)),
};
root = CreateLayerTree(layerTreeSyntax, layerVisibleRegions, nullptr, lm, layers);
SetScrollableFrameMetrics(root, FrameMetrics::START_SCROLL_ID);
// Set up the event regions so that the child thebes layer is positioned far