mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 932525 - Do APZC hit testing using the layer's screen coordinates rather than layer coordinates. r=kats
This commit is contained in:
parent
dd6438f71b
commit
7c0017a83e
@ -141,7 +141,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
apzc->NotifyLayersUpdated(container->GetFrameMetrics(),
|
||||
aIsFirstPaint && (aLayersId == aFirstPaintLayersId));
|
||||
|
||||
LayerRect visible = ScreenRect(container->GetFrameMetrics().mCompositionBounds) * ScreenToLayerScale(1.0);
|
||||
ScreenRect visible(container->GetFrameMetrics().mCompositionBounds);
|
||||
apzc->SetLayerHitTestData(visible, aTransform, aLayer->GetTransform());
|
||||
APZC_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
|
||||
visible.width, visible.height,
|
||||
@ -629,30 +629,42 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, const gfxPoint& a
|
||||
// comments explain what values are stored in the variables at these two levels. All the comments
|
||||
// use standard matrix notation where the leftmost matrix in a multiplication is applied first.
|
||||
|
||||
// ancestorUntransform is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L,
|
||||
// and RC.Inverse() * QC.Inverse() at recursion level for P.
|
||||
// ancestorUntransform takes points from aApzc's parent APZC's screen coordinates
|
||||
// to aApzc's screen coordinates.
|
||||
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() at recursion level for L,
|
||||
// and RC.Inverse() * QC.Inverse() at recursion level for P.
|
||||
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
|
||||
// asyncUntransform is LA.Inverse() at recursion level for L,
|
||||
// and PA.Inverse() at recursion level for P.
|
||||
gfx3DMatrix asyncUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
|
||||
// untransformSinceLastApzc is OC.Inverse() * NC.Inverse() * MC.Inverse() * LA.Inverse() * LC.Inverse() at L,
|
||||
// and RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() at P.
|
||||
gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * asyncUntransform * aApzc->GetCSSTransform().Inverse();
|
||||
// untransformed is the user input in L's layer space at L,
|
||||
// and in P's layer space at P.
|
||||
gfxPoint untransformed = untransformSinceLastApzc.ProjectPoint(aHitTestPoint);
|
||||
APZC_LOG("Untransformed %f %f to %f %f for APZC %p\n", aHitTestPoint.x, aHitTestPoint.y, untransformed.x, untransformed.y, aApzc);
|
||||
|
||||
// Hit testing for this layer is performed in aApzc's screen coordinates.
|
||||
gfxPoint hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
|
||||
APZC_LOG("Untransformed %f %f to screen coordinates %f %f for hit-testing APZC %p\n",
|
||||
aHitTestPoint.x, aHitTestPoint.y,
|
||||
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
|
||||
|
||||
// myUntransform takes points from aApzc's screen coordinates
|
||||
// to aApzc's layer coordinates (which are aApzc's children's screen coordinates).
|
||||
// It is LA.Inverse() * LC.Inverse() at L
|
||||
// and PA.Inverse() * PC.Inverse() at P.
|
||||
gfx3DMatrix myUntransform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse()
|
||||
* aApzc->GetCSSTransform().Inverse();
|
||||
|
||||
// Hit testing for child layers is performed in aApzc's layer coordinates.
|
||||
gfxPoint hitTestPointForChildLayers = myUntransform.ProjectPoint(hitTestPointForThisLayer);
|
||||
APZC_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
|
||||
aHitTestPoint.x, aHitTestPoint.y,
|
||||
hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc);
|
||||
|
||||
// This walks the tree in depth-first, reverse order, so that it encounters
|
||||
// APZCs front-to-back on the screen.
|
||||
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
AsyncPanZoomController* match = GetAPZCAtPoint(child, untransformed);
|
||||
AsyncPanZoomController* match = GetAPZCAtPoint(child, hitTestPointForChildLayers);
|
||||
if (match) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
if (aApzc->VisibleRegionContains(LayerPoint(untransformed.x, untransformed.y))) {
|
||||
APZC_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n", untransformed.x, untransformed.y, aApzc);
|
||||
if (aApzc->VisibleRegionContains(ScreenPoint(hitTestPointForThisLayer.x, hitTestPointForThisLayer.y))) {
|
||||
APZC_LOG("Successfully matched untransformed point %f %f to visible region for APZC %p\n",
|
||||
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
|
||||
return aApzc;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -655,7 +655,7 @@ private:
|
||||
* hit-testing to see which APZC instance should handle touch events.
|
||||
*/
|
||||
public:
|
||||
void SetLayerHitTestData(const LayerRect& aRect, const gfx3DMatrix& aTransformToLayer,
|
||||
void SetLayerHitTestData(const ScreenRect& aRect, const gfx3DMatrix& aTransformToLayer,
|
||||
const gfx3DMatrix& aTransformForLayer) {
|
||||
mVisibleRect = aRect;
|
||||
mAncestorTransform = aTransformToLayer;
|
||||
@ -670,16 +670,15 @@ public:
|
||||
return mCSSTransform;
|
||||
}
|
||||
|
||||
bool VisibleRegionContains(const LayerPoint& aPoint) const {
|
||||
bool VisibleRegionContains(const ScreenPoint& aPoint) const {
|
||||
return mVisibleRect.Contains(aPoint);
|
||||
}
|
||||
|
||||
private:
|
||||
/* This is the viewport of the layer that this APZC corresponds to, in
|
||||
* layer pixels. It position here does not account for any transformations
|
||||
* applied to any layers, whether they are CSS transforms or async
|
||||
* transforms. */
|
||||
LayerRect mVisibleRect;
|
||||
/* This is the visible region of the layer that this APZC corresponds to, in
|
||||
* that layer's screen pixels (the same coordinate system in which this APZC
|
||||
* receives events in ReceiveInputEvent()). */
|
||||
ScreenRect mVisibleRect;
|
||||
/* This is the cumulative CSS transform for all the layers between the parent
|
||||
* APZC and this one (not inclusive) */
|
||||
gfx3DMatrix mAncestorTransform;
|
||||
|
@ -433,19 +433,17 @@ TEST(AsyncPanZoomController, OverScrollPanning) {
|
||||
EXPECT_EQ(pointOut, ScreenPoint(0, 90));
|
||||
}
|
||||
|
||||
// Layer tree for HitTesting1
|
||||
static already_AddRefed<mozilla::layers::Layer>
|
||||
CreateTestLayerTree(nsRefPtr<LayerManager>& aLayerManager, nsTArray<nsRefPtr<Layer> >& aLayers) {
|
||||
const char* layerTreeSyntax = "c(ttccc(c(c)))";
|
||||
// LayerID 0 12345 6 7
|
||||
CreateTestLayerTree1(nsRefPtr<LayerManager>& aLayerManager, nsTArray<nsRefPtr<Layer> >& aLayers) {
|
||||
const char* layerTreeSyntax = "c(ttcc)";
|
||||
// LayerID 0 1234
|
||||
nsIntRegion layerVisibleRegion[] = {
|
||||
nsIntRegion(nsIntRect(0,0,100,100)),
|
||||
nsIntRegion(nsIntRect(0,0,100,100)),
|
||||
nsIntRegion(nsIntRect(10,10,20,20)),
|
||||
nsIntRegion(nsIntRect(10,10,20,20)),
|
||||
nsIntRegion(nsIntRect(5,5,20,20)),
|
||||
nsIntRegion(nsIntRect(10,10,40,40)),
|
||||
nsIntRegion(nsIntRect(10,10,40,40)),
|
||||
nsIntRegion(nsIntRect(10,10,40,40)),
|
||||
};
|
||||
gfx3DMatrix transforms[] = {
|
||||
gfx3DMatrix(),
|
||||
@ -453,15 +451,35 @@ CreateTestLayerTree(nsRefPtr<LayerManager>& aLayerManager, nsTArray<nsRefPtr<Lay
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
};
|
||||
return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers);
|
||||
}
|
||||
|
||||
// Layer Tree for HitTesting2
|
||||
static already_AddRefed<mozilla::layers::Layer>
|
||||
CreateTestLayerTree2(nsRefPtr<LayerManager>& aLayerManager, nsTArray<nsRefPtr<Layer> >& aLayers) {
|
||||
const char* layerTreeSyntax = "c(cc(c))";
|
||||
// LayerID 0 12 3
|
||||
nsIntRegion layerVisibleRegion[] = {
|
||||
nsIntRegion(nsIntRect(0,0,100,100)),
|
||||
nsIntRegion(nsIntRect(10,10,40,40)),
|
||||
nsIntRegion(nsIntRect(10,60,40,40)),
|
||||
nsIntRegion(nsIntRect(10,60,40,40)),
|
||||
};
|
||||
gfx3DMatrix transforms[] = {
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
gfx3DMatrix(),
|
||||
};
|
||||
return CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, aLayerManager, aLayers);
|
||||
}
|
||||
|
||||
static void
|
||||
SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, MockContentController* mcc)
|
||||
SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
|
||||
// The scrollable rect is only used in HitTesting2,
|
||||
// HitTesting1 doesn't care about it.
|
||||
CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1))
|
||||
{
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
FrameMetrics metrics;
|
||||
@ -469,8 +487,8 @@ SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId, MockCon
|
||||
nsIntRect layerBound = aLayer->GetVisibleRegion().GetBounds();
|
||||
metrics.mCompositionBounds = ScreenIntRect(layerBound.x, layerBound.y,
|
||||
layerBound.width, layerBound.height);
|
||||
metrics.mViewport = CSSRect(layerBound.x, layerBound.y,
|
||||
layerBound.width, layerBound.height);
|
||||
metrics.mScrollableRect = aScrollableRect;
|
||||
metrics.mScrollOffset = CSSPoint(0, 0);
|
||||
container->SetFrameMetrics(metrics);
|
||||
}
|
||||
|
||||
@ -499,10 +517,11 @@ GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint,
|
||||
return hit.forget();
|
||||
}
|
||||
|
||||
TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
// A simple hit testing test that doesn't involve any transforms on layers.
|
||||
TEST(APZCTreeManager, HitTesting1) {
|
||||
nsTArray<nsRefPtr<Layer> > layers;
|
||||
nsRefPtr<LayerManager> lm;
|
||||
nsRefPtr<Layer> root = CreateTestLayerTree(lm, layers);
|
||||
nsRefPtr<Layer> root = CreateTestLayerTree1(lm, layers);
|
||||
|
||||
TimeStamp testStartTime = TimeStamp::Now();
|
||||
AsyncPanZoomController::SetFrameTime(testStartTime);
|
||||
@ -521,8 +540,8 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
EXPECT_EQ(gfx3DMatrix(), transformToScreen);
|
||||
|
||||
// Now we have a root APZC that will match the page
|
||||
SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID, mcc);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerIntPoint(15, 15)
|
||||
@ -530,8 +549,8 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
EXPECT_EQ(gfxPoint(15, 15), transformToScreen.Transform(gfxPoint(15, 15)));
|
||||
|
||||
// Now we have a sub APZC with a better fit
|
||||
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID, mcc);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
|
||||
EXPECT_NE(root->AsContainerLayer()->GetAsyncPanZoomController(), layers[3]->AsContainerLayer()->GetAsyncPanZoomController());
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
@ -542,8 +561,8 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
// Now test hit testing when we have two scrollable layers
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1, mcc);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
SetScrollableFrameMetrics(layers[4], FrameMetrics::START_SCROLL_ID + 1);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerIntPoint(15, 15)
|
||||
@ -567,59 +586,115 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
|
||||
EXPECT_EQ(gfx3DMatrix(), transformToScreen);
|
||||
|
||||
// Test layer transform
|
||||
gfx3DMatrix transform;
|
||||
transform.ScalePost(0.1, 0.1, 1);
|
||||
root->SetBaseTransform(transform);
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(50, 50), transformToApzc, transformToScreen); // This point is now outside the root layer
|
||||
EXPECT_EQ(nullAPZC, hit.get());
|
||||
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
|
||||
EXPECT_EQ(gfx3DMatrix(), transformToScreen);
|
||||
|
||||
// This hit test will hit both layers[3] and layers[4]; layers[4] is later in the tree so
|
||||
// it is a better match
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(2, 2), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerPoint(20, 20)
|
||||
EXPECT_EQ(gfxPoint(20, 20), NudgeToIntegers(transformToApzc.Transform(gfxPoint(2, 2))));
|
||||
EXPECT_EQ(gfxPoint(2, 2), NudgeToIntegers(transformToScreen.Transform(gfxPoint(20, 20))));
|
||||
|
||||
// Scale layer[4] outside the range
|
||||
layers[4]->SetBaseTransform(transform);
|
||||
// layer 4 effective visible screenrect: (0.05, 0.05, 0.2, 0.2)
|
||||
// Does not contain (2, 2)
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(2, 2), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerPoint(20, 20)
|
||||
EXPECT_EQ(gfxPoint(20, 20), NudgeToIntegers(transformToApzc.Transform(gfxPoint(2, 2))));
|
||||
EXPECT_EQ(gfxPoint(2, 2), NudgeToIntegers(transformToScreen.Transform(gfxPoint(20, 20))));
|
||||
|
||||
// Transformation chain to layer 7
|
||||
SetScrollableFrameMetrics(layers[7], FrameMetrics::START_SCROLL_ID + 2, mcc);
|
||||
|
||||
gfx3DMatrix translateTransform;
|
||||
translateTransform.Translate(gfxPoint3D(10, 10, 0));
|
||||
layers[5]->SetBaseTransform(translateTransform);
|
||||
|
||||
gfx3DMatrix translateTransform2;
|
||||
translateTransform2.Translate(gfxPoint3D(-20, 0, 0));
|
||||
layers[6]->SetBaseTransform(translateTransform2);
|
||||
|
||||
gfx3DMatrix translateTransform3;
|
||||
translateTransform3.ScalePost(1,15,1);
|
||||
layers[7]->SetBaseTransform(translateTransform3);
|
||||
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
// layer 7 effective visible screenrect (0,16,4,60) but clipped by parent layers
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(1, 45), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(layers[7]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerPoint(20, 440), which is CSSPoint(20, 29)
|
||||
EXPECT_EQ(gfxPoint(20, 440), NudgeToIntegers(transformToApzc.Transform(gfxPoint(1, 45))));
|
||||
EXPECT_EQ(gfxPoint(1, 45), NudgeToIntegers(transformToScreen.Transform(gfxPoint(20, 440))));
|
||||
|
||||
manager->ClearTree();
|
||||
}
|
||||
|
||||
// A more involved hit testing test that involves css and async transforms.
|
||||
TEST(APZCTreeManager, HitTesting2) {
|
||||
nsTArray<nsRefPtr<Layer> > layers;
|
||||
nsRefPtr<LayerManager> lm;
|
||||
nsRefPtr<Layer> root = CreateTestLayerTree2(lm, layers);
|
||||
|
||||
TimeStamp testStartTime = TimeStamp::Now();
|
||||
AsyncPanZoomController::SetFrameTime(testStartTime);
|
||||
nsRefPtr<MockContentController> mcc = new MockContentController();
|
||||
ScopedLayerTreeRegistration controller(0, root, mcc);
|
||||
|
||||
nsRefPtr<APZCTreeManager> manager = new TestAPZCTreeManager();
|
||||
nsRefPtr<AsyncPanZoomController> hit;
|
||||
gfx3DMatrix transformToApzc;
|
||||
gfx3DMatrix transformToScreen;
|
||||
|
||||
// Set a CSS transform on one of the layers.
|
||||
gfx3DMatrix transform;
|
||||
transform.ScalePost(2, 1, 1);
|
||||
layers[2]->SetBaseTransform(transform);
|
||||
|
||||
// Make some other layers scrollable.
|
||||
SetScrollableFrameMetrics(root, FrameMetrics::ROOT_SCROLL_ID, CSSRect(0, 0, 200, 200));
|
||||
SetScrollableFrameMetrics(layers[1], FrameMetrics::START_SCROLL_ID, CSSRect(0, 0, 80, 80));
|
||||
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1, CSSRect(0, 0, 80, 80));
|
||||
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, false, 0);
|
||||
|
||||
// At this point, the following holds (all coordinates in screen pixels):
|
||||
// layers[0] has content from (0,0)-(200,200), clipped by composition bounds (0,0)-(100,100)
|
||||
// layers[1] has content from (10,10)-(90,90), clipped by composition bounds (10,10)-(50,50)
|
||||
// layers[2] has content from (20,60)-(100,100). no clipping as it's not a scrollable layer
|
||||
// layers[3] has content from (20,60)-(180,140), clipped by composition bounds (20,60)-(100,100)
|
||||
|
||||
AsyncPanZoomController* apzcroot = root->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc1 = layers[1]->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
AsyncPanZoomController* apzc3 = layers[3]->AsContainerLayer()->GetAsyncPanZoomController();
|
||||
|
||||
// Hit an area that's clearly on the root layer but not any of the child layers.
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzcroot, hit.get());
|
||||
EXPECT_EQ(gfxPoint(75, 25), transformToApzc.Transform(gfxPoint(75, 25)));
|
||||
EXPECT_EQ(gfxPoint(75, 25), transformToScreen.Transform(gfxPoint(75, 25)));
|
||||
|
||||
// Hit an area on the root that would be on layers[3] if layers[2]
|
||||
// weren't transformed.
|
||||
// Note that if layers[2] were scrollable, then this would hit layers[2]
|
||||
// because its composition bounds would be at (10,60)-(50,100) (and the
|
||||
// scale-only transform that we set on layers[2] would be invalid because
|
||||
// it would place the layer into overscroll, as its composition bounds
|
||||
// start at x=10 but its content at x=20).
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzcroot, hit.get());
|
||||
EXPECT_EQ(gfxPoint(15, 75), transformToApzc.Transform(gfxPoint(15, 75)));
|
||||
EXPECT_EQ(gfxPoint(15, 75), transformToScreen.Transform(gfxPoint(15, 75)));
|
||||
|
||||
// Hit an area on layers[1].
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzc1, hit.get());
|
||||
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
|
||||
EXPECT_EQ(gfxPoint(25, 25), transformToScreen.Transform(gfxPoint(25, 25)));
|
||||
|
||||
// Hit an area on layers[3].
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzc3, hit.get());
|
||||
// transformToApzc should unapply layers[2]'s transform
|
||||
EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 75)));
|
||||
// and transformToScreen should reapply it
|
||||
EXPECT_EQ(gfxPoint(25, 75), transformToScreen.Transform(gfxPoint(12.5, 75)));
|
||||
|
||||
// Hit an area on layers[3] that would be on the root if layers[2]
|
||||
// weren't transformed.
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzc3, hit.get());
|
||||
// transformToApzc should unapply layers[2]'s transform
|
||||
EXPECT_EQ(gfxPoint(37.5, 75), transformToApzc.Transform(gfxPoint(75, 75)));
|
||||
// and transformToScreen should reapply it
|
||||
EXPECT_EQ(gfxPoint(75, 75), transformToScreen.Transform(gfxPoint(37.5, 75)));
|
||||
|
||||
// Pan the root layer upward by 50 pixels.
|
||||
// This causes layers[1] to scroll out of view, and an async transform
|
||||
// of -50 to be set on the root layer.
|
||||
int time = 0;
|
||||
// Silence GMock warnings about "uninteresting mock function calls".
|
||||
EXPECT_CALL(*mcc, PostDelayedTask(_,_)).Times(1);
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(2);
|
||||
EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(1);
|
||||
ApzcPan(apzcroot, time, 100, 50);
|
||||
|
||||
// Hit where layers[3] used to be. It should now hit the root.
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzcroot, hit.get());
|
||||
// transformToApzc doesn't unapply the root's own async transform
|
||||
EXPECT_EQ(gfxPoint(75, 75), transformToApzc.Transform(gfxPoint(75, 75)));
|
||||
// but transformToScreen does
|
||||
EXPECT_EQ(gfxPoint(75, 125), transformToScreen.Transform(gfxPoint(75, 75)));
|
||||
|
||||
// Hit where layers[1] used to be and where layers[3] should now be.
|
||||
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToScreen);
|
||||
EXPECT_EQ(apzc3, hit.get());
|
||||
// transformToApzc unapplies both layers[2]'s css transform and the root's
|
||||
// async trasnform
|
||||
EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 25)));
|
||||
// transformToScreen reapplies the css transform only (since Gecko doesn't
|
||||
// know about async transforms)
|
||||
EXPECT_EQ(gfxPoint(25, 75), transformToScreen.Transform(gfxPoint(12.5, 75)));
|
||||
|
||||
manager->ClearTree();
|
||||
}
|
Loading…
Reference in New Issue
Block a user