Bug 952977: More gfx::Matrix cleanup in APZC r=nical

This commit is contained in:
David Zbarsky 2014-07-29 19:18:51 -04:00
parent d9caf0d0e6
commit 8aace2bf29
6 changed files with 135 additions and 116 deletions

View File

@ -8,7 +8,6 @@
#include "CompositorParent.h" // for CompositorParent, etc
#include "InputData.h" // for InputData, etc
#include "Layers.h" // for ContainerLayer, Layer, etc
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "mozilla/dom/Touch.h" // for Touch
#include "mozilla/gfx/Point.h" // for Point
#include "mozilla/layers/AsyncCompositionManager.h" // for ViewTransform
@ -32,6 +31,9 @@
namespace mozilla {
namespace layers {
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
float APZCTreeManager::sDPI = 160.0;
APZCTreeManager::APZCTreeManager()
@ -139,7 +141,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
aRoot,
// aCompositor is null in gtest scenarios
aCompositor ? aCompositor->RootLayerTreeId() : 0,
gfx3DMatrix(), nullptr, nullptr,
Matrix4x4(), nullptr, nullptr,
aIsFirstPaint, aOriginatingLayersId,
paintLogger, &apzcsToDestroy, nsIntRegion());
mApzcTreeLog << "[end]\n";
@ -154,7 +156,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
AsyncPanZoomController*
APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
Layer* aLayer, uint64_t aLayersId,
gfx3DMatrix aTransform,
Matrix4x4 aTransform,
AsyncPanZoomController* aParent,
AsyncPanZoomController* aNextSibling,
bool aIsFirstPaint,
@ -165,7 +167,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
{
mTreeLock.AssertCurrentThreadOwns();
gfx3DMatrix transform = gfx::To3DMatrix(aLayer->GetTransform());
Matrix4x4 transform = aLayer->GetTransform();
ContainerLayer* container = aLayer->AsContainerLayer();
AsyncPanZoomController* apzc = nullptr;
@ -319,7 +321,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
// Accumulate the CSS transform between layers that have an APZC, but exclude any
// any layers that do have an APZC, and reset the accumulation at those layers.
if (apzc) {
aTransform = gfx3DMatrix();
aTransform = Matrix4x4();
} else {
// Multiply child layer transforms on the left so they get applied first
aTransform = transform * aTransform;
@ -341,7 +343,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
// have to check for mask layers and so on in order to properly handle
// that case.
obscured = aObscured;
obscured.Transform(transform.Inverse());
obscured.Transform(To3DMatrix(transform).Inverse());
}
// If there's no APZC at this level, any APZCs for our child layers will
@ -378,25 +380,25 @@ APZCTreeManager::UpdatePanZoomControllerTree(CompositorParent* aCompositor,
}
/*static*/ template<class T> void
ApplyTransform(gfx::PointTyped<T>* aPoint, const gfx3DMatrix& aMatrix)
ApplyTransform(gfx::PointTyped<T>* aPoint, const Matrix4x4& aMatrix)
{
gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y));
Point result = aMatrix * aPoint->ToUnknownPoint();
aPoint->x = result.x;
aPoint->y = result.y;
}
/*static*/ template<class T> void
ApplyTransform(gfx::IntPointTyped<T>* aPoint, const gfx3DMatrix& aMatrix)
ApplyTransform(gfx::IntPointTyped<T>* aPoint, const Matrix4x4& aMatrix)
{
gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y));
aPoint->x = NS_lround(result.x);
aPoint->y = NS_lround(result.y);
Point result = aMatrix * aPoint->ToUnknownPoint();
aPoint->x = result.x;
aPoint->y = result.y;
}
/*static*/ void
ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix)
ApplyTransform(nsIntPoint* aPoint, const Matrix4x4& aMatrix)
{
gfxPoint result = aMatrix.Transform(gfxPoint(aPoint->x, aPoint->y));
Point result = aMatrix * Point(aPoint->x, aPoint->y);
aPoint->x = NS_lround(result.x);
aPoint->y = NS_lround(result.y);
}
@ -404,7 +406,7 @@ ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix)
/*static*/ template<class T> void
TransformScreenToGecko(T* aPoint, AsyncPanZoomController* aApzc, APZCTreeManager* aApzcTm)
{
gfx3DMatrix transformToApzc, transformToGecko;
Matrix4x4 transformToApzc, transformToGecko;
aApzcTm->GetInputTransforms(aApzc, transformToApzc, transformToGecko);
ApplyTransform(aPoint, transformToApzc * transformToGecko);
}
@ -414,8 +416,8 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
ScrollableLayerGuid* aOutTargetGuid)
{
nsEventStatus result = nsEventStatus_eIgnore;
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
MultiTouchInput& touchInput = aEvent.AsMultiTouchInput();
@ -559,11 +561,11 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
if (mApzcForInputBlock) {
// Cache apz transform so it can be used for future events in this block.
gfx3DMatrix transformToGecko;
Matrix4x4 transformToGecko;
GetInputTransforms(mApzcForInputBlock, mCachedTransformToApzcForInputBlock, transformToGecko);
} else {
// Reset the cached apz transform
mCachedTransformToApzcForInputBlock = gfx3DMatrix();
mCachedTransformToApzcForInputBlock = Matrix4x4();
}
} else if (mApzcForInputBlock) {
APZCTM_LOG("Re-using APZC %p as continuation of event block\n", mApzcForInputBlock.get());
@ -596,7 +598,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// For computing the input for the APZC, used the cached transform.
// This ensures that the sequence of touch points an APZC sees in an
// input block are all in the same coordinate space.
gfx3DMatrix transformToApzc = mCachedTransformToApzcForInputBlock;
Matrix4x4 transformToApzc = mCachedTransformToApzcForInputBlock;
MultiTouchInput inputForApzc(aInput);
for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) {
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
@ -606,9 +608,9 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
// For computing the event to pass back to Gecko, use the up-to-date transforms.
// This ensures that transformToApzc and transformToGecko are in sync
// (note that transformToGecko isn't cached).
gfx3DMatrix transformToGecko;
Matrix4x4 transformToGecko;
GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko);
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
Matrix4x4 outTransform = transformToApzc * transformToGecko;
for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
ApplyTransform(&(aInput.mTouches[i].mScreenPoint), outTransform);
}
@ -649,10 +651,10 @@ APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
MOZ_ASSERT(aOutTransformedPoint);
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aPoint, nullptr);
if (apzc && aOutTransformedPoint) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
GetInputTransforms(apzc, transformToApzc, transformToGecko);
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
Matrix4x4 outTransform = transformToApzc * transformToGecko;
aOutTransformedPoint->x = aPoint.x;
aOutTransformedPoint->y = aPoint.y;
ApplyTransform(aOutTransformedPoint, outTransform);
@ -672,10 +674,10 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
&inOverscrolledApzc);
if (apzc) {
apzc->GetGuid(aOutTargetGuid);
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
GetInputTransforms(apzc, transformToApzc, transformToGecko);
gfx3DMatrix outTransform = transformToApzc * transformToGecko;
Matrix4x4 outTransform = transformToApzc * transformToGecko;
ApplyTransform(&(aEvent.refPoint), outTransform);
}
return inOverscrolledApzc ? nsEventStatus_eConsumeNoDefault
@ -804,13 +806,15 @@ TransformDisplacement(APZCTreeManager* aTreeManager,
AsyncPanZoomController* aTarget,
ScreenPoint& aStartPoint,
ScreenPoint& aEndPoint) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko; // ignored
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko; // ignored
// Convert start and end points to untransformed screen coordinates.
aTreeManager->GetInputTransforms(aSource, transformToApzc, transformToGecko);
ApplyTransform(&aStartPoint, transformToApzc.Inverse());
ApplyTransform(&aEndPoint, transformToApzc.Inverse());
Matrix4x4 untransformToApzc = transformToApzc;
untransformToApzc.Invert();
ApplyTransform(&aStartPoint, untransformToApzc);
ApplyTransform(&aEndPoint, untransformToApzc);
// Convert start and end points to aTarget's transformed screen coordinates.
aTreeManager->GetInputTransforms(aTarget, transformToApzc, transformToGecko);
@ -1180,12 +1184,13 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
// to aApzc's parent layer's layer 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();
Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform();
ancestorUntransform.Invert();
// Hit testing for this layer takes place in our parent layer coordinates,
// since the composition bounds (used to initialize the visible rect against
// which we hit test are in those coordinates).
gfxPointH3D hitTestPointForThisLayer = ancestorUntransform.ProjectPoint(aHitTestPoint);
gfxPointH3D hitTestPointForThisLayer = To3DMatrix(ancestorUntransform).ProjectPoint(aHitTestPoint);
APZCTM_LOG("Untransformed %f %f to transient coordinates %f %f for hit-testing APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForThisLayer.x, hitTestPointForThisLayer.y, aApzc);
@ -1194,10 +1199,12 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
// to aApzc's layer coordinates (which are aApzc's children's ParentLayer coordinates).
// It is OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LA.Inverse() at L
// and RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() at P.
gfx3DMatrix childUntransform = ancestorUntransform
* aApzc->GetCSSTransform().Inverse()
* gfx::To3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
gfxPointH3D hitTestPointForChildLayers = childUntransform.ProjectPoint(aHitTestPoint);
Matrix4x4 cssUntransform = aApzc->GetCSSTransform();
cssUntransform.Invert();
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform();
asyncUntransform.Invert();
Matrix4x4 childUntransform = ancestorUntransform * cssUntransform * asyncUntransform;
gfxPointH3D hitTestPointForChildLayers = To3DMatrix(childUntransform).ProjectPoint(aHitTestPoint);
APZCTM_LOG("Untransformed %f %f to layer coordinates %f %f for APZC %p\n",
aHitTestPoint.x, aHitTestPoint.y,
hitTestPointForChildLayers.x, hitTestPointForChildLayers.y, aApzc);
@ -1330,8 +1337,8 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
required can be generated.
*/
void
APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
gfx3DMatrix& aTransformToGeckoOut)
APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, Matrix4x4& aTransformToApzcOut,
Matrix4x4& aTransformToGeckoOut)
{
MonitorAutoLock lock(mTreeLock);
@ -1342,26 +1349,36 @@ APZCTreeManager::GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix&
// leftmost matrix in a multiplication is applied first.
// ancestorUntransform is OC.Inverse() * NC.Inverse() * MC.Inverse()
gfx3DMatrix ancestorUntransform = aApzc->GetAncestorTransform().Inverse();
Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform();
ancestorUntransform.Invert();
// asyncUntransform is LA.Inverse()
gfx3DMatrix asyncUntransform = gfx::To3DMatrix(aApzc->GetCurrentAsyncTransform()).Inverse();
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// nontransientAsyncTransform is LN
gfx3DMatrix nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform();
Matrix4x4 nontransientAsyncTransform = aApzc->GetNontransientAsyncTransform();
// transientAsyncUntransform is LT.Inverse()
gfx3DMatrix transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform;
Matrix4x4 transientAsyncUntransform = nontransientAsyncTransform * asyncUntransform;
// aTransformToApzcOut is initialized to OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse()
aTransformToApzcOut = ancestorUntransform * aApzc->GetCSSTransform().Inverse() * nontransientAsyncTransform.Inverse();
Matrix4x4 cssUntransform = aApzc->GetCSSTransform();
cssUntransform.Invert();
Matrix4x4 nontransientAsyncUntransform = nontransientAsyncTransform;
nontransientAsyncUntransform.Invert();
aTransformToApzcOut = ancestorUntransform * cssUntransform * nontransientAsyncUntransform;
// aTransformToGeckoOut is initialized to LT.Inverse() * LD * LC * MC * NC * OC
aTransformToGeckoOut = transientAsyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetCSSTransform() * aApzc->GetAncestorTransform();
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P
ancestorUntransform = parent->GetAncestorTransform().Inverse();
ancestorUntransform = parent->GetAncestorTransform();
ancestorUntransform.Invert();
// asyncUntransform is updated to PA.Inverse() when parent == P
asyncUntransform = gfx::To3DMatrix(parent->GetCurrentAsyncTransform()).Inverse();
asyncUntransform = parent->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse()
gfx3DMatrix untransformSinceLastApzc = ancestorUntransform * parent->GetCSSTransform().Inverse() * asyncUntransform;
cssUntransform = parent->GetCSSTransform();
cssUntransform.Invert();
Matrix4x4 untransformSinceLastApzc = ancestorUntransform * cssUntransform * asyncUntransform;
// aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PC.Inverse() * PA.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse() * LC.Inverse() * LN.Inverse()
aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut;

View File

@ -10,10 +10,10 @@
#include "FrameMetrics.h" // for FrameMetrics, etc
#include "Units.h" // for CSSPoint, CSSRect, etc
#include "gfxPoint.h" // for gfxPoint
#include "gfx3DMatrix.h" // for gfx3DMatrix
#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
#include "mozilla/EventForwards.h" // for WidgetInputEvent, nsEventStatus
#include "mozilla/Monitor.h" // for Monitor
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "nsAutoPtr.h" // for nsRefPtr
#include "nsCOMPtr.h" // for already_AddRefed
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
@ -21,7 +21,6 @@
#include "nsTArrayForwardDeclare.h" // for nsTArray, nsTArray_Impl, etc
#include "mozilla/gfx/Logging.h" // for gfx::TreeLog
class gfx3DMatrix;
class nsIntRegion;
namespace mozilla {
@ -327,8 +326,8 @@ public:
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
bool* aOutInOverscrolledApzc);
void GetInputTransforms(AsyncPanZoomController *aApzc, gfx3DMatrix& aTransformToApzcOut,
gfx3DMatrix& aTransformToGeckoOut);
void GetInputTransforms(AsyncPanZoomController *aApzc, gfx::Matrix4x4& aTransformToApzcOut,
gfx::Matrix4x4& aTransformToGeckoOut);
private:
/* Helpers */
AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, FrameMetrics::ViewID aScrollId);
@ -358,7 +357,7 @@ private:
*/
AsyncPanZoomController* UpdatePanZoomControllerTree(CompositorParent* aCompositor,
Layer* aLayer, uint64_t aLayersId,
gfx3DMatrix aTransform,
gfx::Matrix4x4 aTransform,
AsyncPanZoomController* aParent,
AsyncPanZoomController* aNextSibling,
bool aIsFirstPaint,
@ -401,7 +400,7 @@ private:
* but for some operations we need to use the initial transform.
* Meaningless if mApzcForInputBlock is nullptr.
*/
gfx3DMatrix mCachedTransformToApzcForInputBlock;
gfx::Matrix4x4 mCachedTransformToApzcForInputBlock;
/* The chain of APZCs that will handle pans for the current touch input
* block, in the order in which they will be scrolled. When one APZC has
* been scrolled as far as it can, any overscroll will be handed off to

View File

@ -129,6 +129,8 @@ namespace layers {
typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
typedef GeckoContentController::APZStateChange APZStateChange;
typedef mozilla::gfx::Point Point;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
/*
* The following prefs are used to control the behaviour of the APZC.
@ -1292,10 +1294,10 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut
{
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
treeManagerLocal->GetInputTransforms(this, transformToApzc, transformToGecko);
gfxPoint result = transformToGecko.Transform(gfxPoint(aPoint.x, aPoint.y));
Point result = transformToGecko * Point(aPoint.x, aPoint.y);
// NOTE: This isn't *quite* LayoutDevicePoint, we just don't have a name
// for this coordinate space and it maps the closest to LayoutDevicePoint.
LayoutDevicePoint layoutPoint = LayoutDevicePoint(result.x, result.y);
@ -2299,20 +2301,20 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
/ mFrameMetrics.GetParentResolution());
}
gfx3DMatrix AsyncPanZoomController::GetNontransientAsyncTransform() {
Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() {
ReentrantMonitorAutoEnter lock(mMonitor);
return gfx3DMatrix::ScalingMatrix(mLastContentPaintMetrics.mResolution.scale,
mLastContentPaintMetrics.mResolution.scale,
1.0f);
return Matrix4x4().Scale(mLastContentPaintMetrics.mResolution.scale,
mLastContentPaintMetrics.mResolution.scale,
1.0f);
}
gfx3DMatrix AsyncPanZoomController::GetTransformToLastDispatchedPaint() {
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() {
ReentrantMonitorAutoEnter lock(mMonitor);
LayerPoint scrollChange = (mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
float zoomChange = mLastContentPaintMetrics.GetZoom().scale / mLastDispatchedPaintMetrics.GetZoom().scale;
return gfx3DMatrix::Translation(scrollChange.x, scrollChange.y, 0) *
gfx3DMatrix::ScalingMatrix(zoomChange, zoomChange, 1);
return Matrix4x4().Translate(scrollChange.x, scrollChange.y, 0) *
Matrix4x4().Scale(zoomChange, zoomChange, 1);
}
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
@ -2854,16 +2856,16 @@ void AsyncPanZoomController::ShareCompositorFrameMetrics() {
ParentLayerPoint AsyncPanZoomController::ToParentLayerCoords(const ScreenPoint& aPoint)
{
return TransformTo<ParentLayerPixel>(GetNontransientAsyncTransform() * GetCSSTransform(), aPoint);
return TransformTo<ParentLayerPixel>(To3DMatrix(GetNontransientAsyncTransform() * GetCSSTransform()), aPoint);
}
void AsyncPanZoomController::UpdateTransformScale()
{
gfx3DMatrix nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform();
if (!FuzzyEqualsMultiplicative(nontransientTransforms.GetXScale(), nontransientTransforms.GetYScale())) {
Matrix4x4 nontransientTransforms = GetNontransientAsyncTransform() * GetCSSTransform();
if (!FuzzyEqualsMultiplicative(nontransientTransforms._11, nontransientTransforms._22)) {
NS_WARNING("The x- and y-scales of the nontransient transforms should be equal");
}
mFrameMetrics.mTransformScale.scale = nontransientTransforms.GetXScale();
mFrameMetrics.mTransformScale.scale = nontransientTransforms._11;
}
}

View File

@ -20,7 +20,7 @@
#include "InputData.h"
#include "Axis.h"
#include "TaskThrottler.h"
#include "gfx3DMatrix.h"
#include "mozilla/gfx/Matrix.h"
#include "nsRegion.h"
#include "base/message_loop.h"
@ -69,6 +69,7 @@ class AsyncPanZoomController {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController)
typedef mozilla::MonitorAutoLock MonitorAutoLock;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef uint32_t TouchBehaviorFlags;
public:
@ -221,9 +222,9 @@ public:
/**
* Returns the part of the async transform that will remain once Gecko does a
* repaint at the desired metrics. That is, in the steady state:
* gfx3DMatrix(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
* Matrix4x4(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
*/
gfx3DMatrix GetNontransientAsyncTransform();
Matrix4x4 GetNontransientAsyncTransform();
/**
* Returns the transform to take something from the coordinate space of the
@ -232,7 +233,7 @@ public:
* processed, this is needed to transform input events properly into a space
* gecko will understand.
*/
gfx3DMatrix GetTransformToLastDispatchedPaint();
Matrix4x4 GetTransformToLastDispatchedPaint();
/**
* Recalculates the displayport. Ideally, this should paint an area bigger
@ -942,19 +943,19 @@ private:
* hit-testing to see which APZC instance should handle touch events.
*/
public:
void SetLayerHitTestData(const nsIntRegion& aRegion, const gfx3DMatrix& aTransformToLayer,
const gfx3DMatrix& aTransformForLayer) {
void SetLayerHitTestData(const nsIntRegion& aRegion, const Matrix4x4& aTransformToLayer,
const Matrix4x4& aTransformForLayer) {
mVisibleRegion = aRegion;
mAncestorTransform = aTransformToLayer;
mCSSTransform = aTransformForLayer;
UpdateTransformScale();
}
gfx3DMatrix GetAncestorTransform() const {
Matrix4x4 GetAncestorTransform() const {
return mAncestorTransform;
}
gfx3DMatrix GetCSSTransform() const {
Matrix4x4 GetCSSTransform() const {
return mCSSTransform;
}
@ -974,9 +975,9 @@ private:
nsIntRegion mVisibleRegion;
/* This is the cumulative CSS transform for all the layers between the parent
* APZC and this one (not inclusive) */
gfx3DMatrix mAncestorTransform;
Matrix4x4 mAncestorTransform;
/* This is the CSS transform for this APZC's layer. */
gfx3DMatrix mCSSTransform;
Matrix4x4 mCSSTransform;
/* ===================================================================

View File

@ -676,7 +676,7 @@ ApplyAsyncTransformToScrollbarForContent(TimeStamp aCurrentFrame, ContainerLayer
}
gfx3DMatrix asyncTransform = To3DMatrix(apzc->GetCurrentAsyncTransform());
gfx3DMatrix nontransientTransform = apzc->GetNontransientAsyncTransform();
gfx3DMatrix nontransientTransform = To3DMatrix(apzc->GetNontransientAsyncTransform());
gfx3DMatrix transientTransform = asyncTransform * nontransientTransform.Inverse();
// |transientTransform| represents the amount by which we have scrolled and

View File

@ -1499,7 +1499,7 @@ SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
static already_AddRefed<AsyncPanZoomController>
GetTargetAPZC(APZCTreeManager* manager, const ScreenPoint& aPoint,
gfx3DMatrix& aTransformToApzcOut, gfx3DMatrix& aTransformToGeckoOut)
Matrix4x4& aTransformToApzcOut, Matrix4x4& aTransformToGeckoOut)
{
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(aPoint, nullptr);
if (hit) {
@ -1520,15 +1520,15 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
ScopedLayerTreeRegistration controller(0, root, mcc);
nsRefPtr<APZCTreeManager> manager = new TestAPZCTreeManager();
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
// No APZC attached so hit testing will return no APZC at (20,20)
nsRefPtr<AsyncPanZoomController> hit = GetTargetAPZC(manager, ScreenPoint(20, 20), transformToApzc, transformToGecko);
AsyncPanZoomController* nullAPZC = nullptr;
EXPECT_EQ(nullAPZC, hit.get());
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
EXPECT_EQ(Matrix4x4(), transformToApzc);
EXPECT_EQ(Matrix4x4(), transformToGecko);
uint32_t paintSequenceNumber = 0;
@ -1538,8 +1538,8 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(15, 15)
EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15)));
EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15)));
EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
// Now we have a sub APZC with a better fit
SetScrollableFrameMetrics(layers[3], FrameMetrics::START_SCROLL_ID + 1);
@ -1548,8 +1548,8 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(layers[3]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(25, 25)
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
// At this point, layers[4] obscures layers[3] at the point (15, 15) so
// hitting there should hit the root APZC
@ -1562,25 +1562,25 @@ TEST_F(APZCTreeManagerTester, HitTesting1) {
hit = GetTargetAPZC(manager, ScreenPoint(15, 15), transformToApzc, transformToGecko);
EXPECT_EQ(layers[4]->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(15, 15)
EXPECT_EQ(gfxPoint(15, 15), transformToApzc.Transform(gfxPoint(15, 15)));
EXPECT_EQ(gfxPoint(15, 15), transformToGecko.Transform(gfxPoint(15, 15)));
EXPECT_EQ(Point(15, 15), transformToApzc * Point(15, 15));
EXPECT_EQ(Point(15, 15), transformToGecko * Point(15, 15));
// Hit test ouside the reach of layer[3,4] but inside root
hit = GetTargetAPZC(manager, ScreenPoint(90, 90), transformToApzc, transformToGecko);
EXPECT_EQ(root->AsContainerLayer()->GetAsyncPanZoomController(), hit.get());
// expect hit point at LayerIntPoint(90, 90)
EXPECT_EQ(gfxPoint(90, 90), transformToApzc.Transform(gfxPoint(90, 90)));
EXPECT_EQ(gfxPoint(90, 90), transformToGecko.Transform(gfxPoint(90, 90)));
EXPECT_EQ(Point(90, 90), transformToApzc * Point(90, 90));
EXPECT_EQ(Point(90, 90), transformToGecko * Point(90, 90));
// Hit test ouside the reach of any layer
hit = GetTargetAPZC(manager, ScreenPoint(1000, 10), transformToApzc, transformToGecko);
EXPECT_EQ(nullAPZC, hit.get());
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
EXPECT_EQ(Matrix4x4(), transformToApzc);
EXPECT_EQ(Matrix4x4(), transformToGecko);
hit = GetTargetAPZC(manager, ScreenPoint(-1000, 10), transformToApzc, transformToGecko);
EXPECT_EQ(nullAPZC, hit.get());
EXPECT_EQ(gfx3DMatrix(), transformToApzc);
EXPECT_EQ(gfx3DMatrix(), transformToGecko);
EXPECT_EQ(Matrix4x4(), transformToApzc);
EXPECT_EQ(Matrix4x4(), transformToGecko);
manager->ClearTree();
}
@ -1598,8 +1598,8 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
nsRefPtr<TestAPZCTreeManager> manager = new TestAPZCTreeManager();
nsRefPtr<AsyncPanZoomController> hit;
gfx3DMatrix transformToApzc;
gfx3DMatrix transformToGecko;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
// Set a CSS transform on one of the layers.
Matrix4x4 transform;
@ -1626,8 +1626,8 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
// Hit an area that's clearly on the root layer but not any of the child layers.
hit = GetTargetAPZC(manager, ScreenPoint(75, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
EXPECT_EQ(gfxPoint(75, 25), transformToApzc.Transform(gfxPoint(75, 25)));
EXPECT_EQ(gfxPoint(75, 25), transformToGecko.Transform(gfxPoint(75, 25)));
EXPECT_EQ(Point(75, 25), transformToApzc * Point(75, 25));
EXPECT_EQ(Point(75, 25), transformToGecko * Point(75, 25));
// Hit an area on the root that would be on layers[3] if layers[2]
// weren't transformed.
@ -1638,31 +1638,31 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
// start at x=10 but its content at x=20).
hit = GetTargetAPZC(manager, ScreenPoint(15, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
EXPECT_EQ(gfxPoint(15, 75), transformToApzc.Transform(gfxPoint(15, 75)));
EXPECT_EQ(gfxPoint(15, 75), transformToGecko.Transform(gfxPoint(15, 75)));
EXPECT_EQ(Point(15, 75), transformToApzc * Point(15, 75));
EXPECT_EQ(Point(15, 75), transformToGecko * Point(15, 75));
// Hit an area on layers[1].
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzc1, hit.get());
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
EXPECT_EQ(Point(25, 25), transformToGecko * Point(25, 25));
// Hit an area on layers[3].
hit = GetTargetAPZC(manager, ScreenPoint(25, 75), transformToApzc, transformToGecko);
EXPECT_EQ(apzc3, hit.get());
// transformToApzc should unapply layers[2]'s transform
EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 75)));
EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 75));
// and transformToGecko should reapply it
EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(12.5, 75)));
EXPECT_EQ(Point(25, 75), transformToGecko * Point(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, transformToGecko);
EXPECT_EQ(apzc3, hit.get());
// transformToApzc should unapply layers[2]'s transform
EXPECT_EQ(gfxPoint(37.5, 75), transformToApzc.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(37.5, 75), transformToApzc * Point(75, 75));
// and transformToGecko should reapply it
EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(37.5, 75)));
EXPECT_EQ(Point(75, 75), transformToGecko * Point(37.5, 75));
// Pan the root layer upward by 50 pixels.
// This causes layers[1] to scroll out of view, and an async transform
@ -1684,21 +1684,21 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko);
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)));
EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
// and transformToGecko unapplies it and then reapplies it, because by the
// time the event being transformed reaches Gecko the new paint request will
// have been handled.
EXPECT_EQ(gfxPoint(75, 75), transformToGecko.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(75, 75), transformToGecko * Point(75, 75));
// Hit where layers[1] used to be and where layers[3] should now be.
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzc3, hit.get());
// transformToApzc unapplies both layers[2]'s css transform and the root's
// async transform
EXPECT_EQ(gfxPoint(12.5, 75), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(12.5, 75), transformToApzc * Point(25, 25));
// transformToGecko reapplies both the css transform and the async transform
// because we have already issued a paint request with it.
EXPECT_EQ(gfxPoint(25, 25), transformToGecko.Transform(gfxPoint(12.5, 75)));
EXPECT_EQ(Point(25, 25), transformToGecko * Point(12.5, 75));
// This second pan will move the APZC by another 50 pixels but since the paint
// request dispatched above has not "completed", we will not dispatch another
@ -1712,19 +1712,19 @@ TEST_F(APZCTreeManagerTester, HitTesting2) {
hit = GetTargetAPZC(manager, ScreenPoint(75, 75), transformToApzc, transformToGecko);
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)));
EXPECT_EQ(Point(75, 75), transformToApzc * Point(75, 75));
// transformToGecko unapplies the full async transform of -100 pixels, and then
// reapplies the "D" transform of -50 leading to an overall adjustment of +50
EXPECT_EQ(gfxPoint(75, 125), transformToGecko.Transform(gfxPoint(75, 75)));
EXPECT_EQ(Point(75, 125), transformToGecko * Point(75, 75));
// Hit where layers[1] used to be. It should now hit the root.
hit = GetTargetAPZC(manager, ScreenPoint(25, 25), transformToApzc, transformToGecko);
EXPECT_EQ(apzcroot, hit.get());
// transformToApzc doesn't unapply the root's own async transform
EXPECT_EQ(gfxPoint(25, 25), transformToApzc.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 25), transformToApzc * Point(25, 25));
// transformToGecko unapplies the full async transform of -100 pixels, and then
// reapplies the "D" transform of -50 leading to an overall adjustment of +50
EXPECT_EQ(gfxPoint(25, 75), transformToGecko.Transform(gfxPoint(25, 25)));
EXPECT_EQ(Point(25, 75), transformToGecko * Point(25, 25));
manager->ClearTree();
}