mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 900742 - Fix APZC hit testing problem introduced by bug 866232. r=BenWa
This commit is contained in:
parent
8309e1a839
commit
24718d2f2e
@ -67,7 +67,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Laye
|
||||
aRoot,
|
||||
// aCompositor is null in gtest scenarios
|
||||
aCompositor ? aCompositor->RootLayerTreeId() : 0,
|
||||
nullptr, nullptr,
|
||||
gfx3DMatrix(), nullptr, nullptr,
|
||||
aIsFirstPaint, aFirstPaintLayersId,
|
||||
&apzcsToDestroy);
|
||||
}
|
||||
@ -81,11 +81,15 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor, Laye
|
||||
AsyncPanZoomController*
|
||||
APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
Layer* aLayer, uint64_t aLayersId,
|
||||
gfx3DMatrix aTransform,
|
||||
AsyncPanZoomController* aParent,
|
||||
AsyncPanZoomController* aNextSibling,
|
||||
bool aIsFirstPaint, uint64_t aFirstPaintLayersId,
|
||||
nsTArray< nsRefPtr<AsyncPanZoomController> >* aApzcsToDestroy)
|
||||
{
|
||||
// Accumulate the CSS transform between layers that have an APZC
|
||||
aTransform = aTransform * aLayer->GetTransform();
|
||||
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
AsyncPanZoomController* controller = nullptr;
|
||||
if (container) {
|
||||
@ -116,12 +120,12 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
controller->NotifyLayersUpdated(container->GetFrameMetrics(),
|
||||
aIsFirstPaint && (aLayersId == aFirstPaintLayersId));
|
||||
|
||||
gfx3DMatrix transform = container->GetEffectiveTransform();
|
||||
LayerRect visible = container->GetFrameMetrics().mViewport * container->GetFrameMetrics().LayersPixelsPerCSSPixel();
|
||||
gfxRect transformed = transform.TransformBounds(gfxRect(visible.x, visible.y, visible.width, visible.height));
|
||||
controller->SetVisibleRegion(transformed);
|
||||
APZC_LOG("Setting rect(%f %f %f %f) as visible region for %p\n", transformed.x, transformed.y,
|
||||
transformed.width, transformed.height,
|
||||
controller->SetLayerHitTestData(visible, aTransform);
|
||||
// Reset the accumulated transform once we hit a layer with an APZC
|
||||
aTransform = gfx3DMatrix();
|
||||
APZC_LOG("Setting rect(%f %f %f %f) as visible region for APZC %p\n", visible.x, visible.y,
|
||||
visible.width, visible.height,
|
||||
controller);
|
||||
|
||||
// Bind the APZC instance into the tree of APZCs
|
||||
@ -144,7 +148,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
uint64_t childLayersId = (aLayer->AsRefLayer() ? aLayer->AsRefLayer()->GetReferentId() : aLayersId);
|
||||
AsyncPanZoomController* next = nullptr;
|
||||
for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
next = UpdatePanZoomControllerTree(aCompositor, child, childLayersId, aParent, next,
|
||||
next = UpdatePanZoomControllerTree(aCompositor, child, childLayersId, aTransform, aParent, next,
|
||||
aIsFirstPaint, aFirstPaintLayersId, aApzcsToDestroy);
|
||||
}
|
||||
|
||||
@ -366,17 +370,21 @@ APZCTreeManager::FindTargetAPZC(AsyncPanZoomController* aApzc, const ScrollableL
|
||||
AsyncPanZoomController*
|
||||
APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc, gfxPoint aHitTestPoint)
|
||||
{
|
||||
gfx3DMatrix transform = gfx3DMatrix(aApzc->GetCurrentAsyncTransform()) * aApzc->GetCSSTransform();
|
||||
gfx3DMatrix untransform = transform.Inverse();
|
||||
gfxPoint untransformed = untransform.ProjectPoint(aHitTestPoint);
|
||||
APZC_LOG("Untransformed %f %f to %f %f for APZC %p\n", aHitTestPoint.x, aHitTestPoint.y, untransformed.x, untransformed.y, aApzc);
|
||||
|
||||
// This walks the tree in depth-first, reverse order, so that it encounters
|
||||
// APZCs front-to-back on the screen.
|
||||
ViewTransform apzcTransform = aApzc->GetCurrentAsyncTransform();
|
||||
gfxPoint untransformed = gfx3DMatrix(apzcTransform).Inverse().ProjectPoint(aHitTestPoint);
|
||||
for (AsyncPanZoomController* child = aApzc->GetLastChild(); child; child = child->GetPrevSibling()) {
|
||||
AsyncPanZoomController* match = GetAPZCAtPoint(child, untransformed);
|
||||
if (match) {
|
||||
return match;
|
||||
}
|
||||
}
|
||||
if (aApzc->VisibleRegionContains(untransformed)) {
|
||||
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);
|
||||
return aApzc;
|
||||
}
|
||||
return nullptr;
|
||||
|
@ -253,6 +253,7 @@ private:
|
||||
*/
|
||||
AsyncPanZoomController* UpdatePanZoomControllerTree(CompositorParent* aCompositor,
|
||||
Layer* aLayer, uint64_t aLayersId,
|
||||
gfx3DMatrix aTransform,
|
||||
AsyncPanZoomController* aParent,
|
||||
AsyncPanZoomController* aNextSibling,
|
||||
bool aIsFirstPaint,
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "Axis.h"
|
||||
#include "TaskThrottler.h"
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "gfx3DMatrix.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
|
||||
@ -641,17 +642,28 @@ private:
|
||||
* hit-testing to see which APZC instance should handle touch events.
|
||||
*/
|
||||
public:
|
||||
void SetVisibleRegion(gfxRect rect) { mVisibleRegion = rect; }
|
||||
void SetLayerHitTestData(const LayerRect& aRect, const gfx3DMatrix& aTransform) {
|
||||
mVisibleRect = aRect;
|
||||
mCSSTransform = aTransform;
|
||||
}
|
||||
|
||||
bool VisibleRegionContains(const gfxPoint& aPoint) const {
|
||||
return mVisibleRegion.Contains(aPoint.x, aPoint.y);
|
||||
gfx3DMatrix GetCSSTransform() const {
|
||||
return mCSSTransform;
|
||||
}
|
||||
|
||||
bool VisibleRegionContains(const LayerPoint& aPoint) const {
|
||||
return mVisibleRect.Contains(aPoint);
|
||||
}
|
||||
|
||||
private:
|
||||
/* This is the viewport of the layer that this APZC corresponds to, but
|
||||
* post-transform. In other words, it is in the coordinate space of its
|
||||
* parent layer. */
|
||||
gfxRect mVisibleRegion;
|
||||
/* 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 cumulative layer transform from the parent APZC down to this
|
||||
* one. */
|
||||
gfx3DMatrix mCSSTransform;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -421,20 +421,20 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
gfx3DMatrix transform;
|
||||
transform.ScalePost(0.1, 0.1, 1);
|
||||
root->SetBaseTransform(transform);
|
||||
root->ComputeEffectiveTransforms(gfx3DMatrix());
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
hit = manager->GetTargetAPZC(ScreenPoint(50, 50)); // This point is now outside the root layer
|
||||
EXPECT_EQ(nullAPZC, hit.get());
|
||||
|
||||
// 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 = manager->GetTargetAPZC(ScreenPoint(2, 2));
|
||||
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
// expect hit point at LayerPoint(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)
|
||||
root->ComputeEffectiveTransforms(gfx3DMatrix());
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
hit = manager->GetTargetAPZC(ScreenPoint(2, 2));
|
||||
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
|
||||
@ -455,7 +455,6 @@ TEST(APZCTreeManager, GetAPZCAtPoint) {
|
||||
translateTransform3.ScalePost(1,15,1);
|
||||
layers[7]->SetBaseTransform(translateTransform3);
|
||||
|
||||
root->ComputeEffectiveTransforms(gfx3DMatrix());
|
||||
manager->UpdatePanZoomControllerTree(nullptr, root, 0, false);
|
||||
// layer 7 effective visible screenrect (0,16,4,60) but clipped by parent layers
|
||||
hit = manager->GetTargetAPZC(ScreenPoint(1, 45));
|
||||
|
Loading…
Reference in New Issue
Block a user