Bug 1063224 - Split APZCTreeManager::GetInputTransforms() into GetScreenToApzcTransform() and GetApzcToGeckoTransform(). r=kats

--HG--
extra : source : e2c2b60db0d0865c81bfadf0100763d35011136f
This commit is contained in:
Botond Ballo 2014-09-08 18:04:01 -04:00
parent 482d310a1f
commit e35b939581
4 changed files with 79 additions and 52 deletions

View File

@ -406,7 +406,7 @@ APZCTreeManager::UpdatePanZoomControllerTree(TreeBuildingState& aState,
mApzcTreeLog << '\n';
// Accumulate the CSS transform between layers that have an APZC.
// In the terminology of the big comment above APZCTreeManager::GetInputTransforms, if
// In the terminology of the big comment above APZCTreeManager::GetScreenToApzcTransform, if
// we are at layer M, then aAncestorTransform is NC * OC * PC, and we left-multiply MC and
// compute ancestorTransform to be MC * NC * OC * PC. This gets passed down as the ancestor
// transform to layer L when we recurse into the children below. If we are at a layer
@ -495,8 +495,8 @@ ApplyTransform(nsIntPoint* aPoint, const Matrix4x4& aMatrix)
/*static*/ template<class T> void
TransformScreenToGecko(T* aPoint, AsyncPanZoomController* aApzc, APZCTreeManager* aApzcTm)
{
Matrix4x4 transformToApzc, transformToGecko;
aApzcTm->GetInputTransforms(aApzc, transformToApzc, transformToGecko);
Matrix4x4 transformToApzc = aApzcTm->GetScreenToApzcTransform(aApzc);
Matrix4x4 transformToGecko = aApzcTm->GetApzcToGeckoTransform(aApzc);
ApplyTransform(aPoint, transformToApzc * transformToGecko);
}
@ -506,7 +506,6 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
{
nsEventStatus result = nsEventStatus_eIgnore;
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
bool inOverscrolledApzc = false;
switch (aEvent.mInputType) {
case MULTITOUCH_INPUT: {
@ -522,7 +521,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
// transform than the one in TransformScreenToGecko, so we need to
// make a copy of the event.
PanGestureInput inputForApzc(panInput);
GetInputTransforms(apzc, transformToApzc, transformToGecko);
transformToApzc = GetScreenToApzcTransform(apzc);
ApplyTransform(&(inputForApzc.mPanStartPoint), transformToApzc);
result = apzc->ReceiveInputEvent(inputForApzc);
@ -540,7 +539,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
// transform than the one in TransformScreenToGecko, so we need to
// make a copy of the event.
PinchGestureInput inputForApzc(pinchInput);
GetInputTransforms(apzc, transformToApzc, transformToGecko);
transformToApzc = GetScreenToApzcTransform(apzc);
ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc);
result = apzc->ReceiveInputEvent(inputForApzc);
@ -558,7 +557,7 @@ APZCTreeManager::ReceiveInputEvent(InputData& aEvent,
// transform than the one in TransformScreenToGecko, so we need to
// make a copy of the event.
TapGestureInput inputForApzc(tapInput);
GetInputTransforms(apzc, transformToApzc, transformToGecko);
transformToApzc = GetScreenToApzcTransform(apzc);
ApplyTransform(&(inputForApzc.mPoint), transformToApzc);
result = apzc->ReceiveInputEvent(inputForApzc);
@ -632,8 +631,7 @@ APZCTreeManager::ProcessTouchInput(MultiTouchInput& aInput,
if (mApzcForInputBlock) {
// Cache apz transform so it can be used for future events in this block.
Matrix4x4 transformToGecko;
GetInputTransforms(mApzcForInputBlock, mCachedTransformToApzcForInputBlock, transformToGecko);
mCachedTransformToApzcForInputBlock = GetScreenToApzcTransform(mApzcForInputBlock);
} else {
// Reset the cached apz transform
mCachedTransformToApzcForInputBlock = Matrix4x4();
@ -680,8 +678,8 @@ 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).
Matrix4x4 transformToGecko;
GetInputTransforms(mApzcForInputBlock, transformToApzc, transformToGecko);
transformToApzc = GetScreenToApzcTransform(mApzcForInputBlock);
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(mApzcForInputBlock);
Matrix4x4 outTransform = transformToApzc * transformToGecko;
for (size_t i = 0; i < aInput.mTouches.Length(); i++) {
ApplyTransform(&(aInput.mTouches[i].mScreenPoint), outTransform);
@ -721,9 +719,8 @@ APZCTreeManager::TransformCoordinateToGecko(const ScreenIntPoint& aPoint,
MOZ_ASSERT(aOutTransformedPoint);
nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aPoint, nullptr);
if (apzc && aOutTransformedPoint) {
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
GetInputTransforms(apzc, transformToApzc, transformToGecko);
Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
Matrix4x4 outTransform = transformToApzc * transformToGecko;
*aOutTransformedPoint = TransformTo<LayoutDevicePixel>(outTransform, aPoint);
}
@ -743,9 +740,8 @@ APZCTreeManager::ProcessEvent(WidgetInputEvent& aEvent,
&inOverscrolledApzc);
if (apzc) {
apzc->GetGuid(aOutTargetGuid);
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
GetInputTransforms(apzc, transformToApzc, transformToGecko);
Matrix4x4 transformToApzc = GetScreenToApzcTransform(apzc);
Matrix4x4 transformToGecko = GetApzcToGeckoTransform(apzc);
Matrix4x4 outTransform = transformToApzc * transformToGecko;
ApplyTransform(&(aEvent.refPoint), outTransform);
}
@ -877,17 +873,16 @@ TransformDisplacement(APZCTreeManager* aTreeManager,
ScreenPoint& aStartPoint,
ScreenPoint& aEndPoint) {
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko; // ignored
// Convert start and end points to untransformed screen coordinates.
aTreeManager->GetInputTransforms(aSource, transformToApzc, transformToGecko);
transformToApzc = aTreeManager->GetScreenToApzcTransform(aSource);
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);
transformToApzc = aTreeManager->GetScreenToApzcTransform(aTarget);
ApplyTransform(&aStartPoint, transformToApzc);
ApplyTransform(&aEndPoint, transformToApzc);
}
@ -1159,7 +1154,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
mTreeLock.AssertCurrentThreadOwns();
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment on GetInputTransforms. This function will recurse with aApzc at L and P, and the
// explained in the comment above GetScreenToApzcTransform. This function will recurse with aApzc at L and P, and the
// 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.
@ -1224,8 +1219,8 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
return result;
}
/* This function sets the aTransformToApzcOut and aTransformToGeckoOut out-parameters
to some useful transformations that input events may need applied. This is best
/* The methods GetScreenToApzcTransform() and GetApzcToGeckoTransform() return
some useful transformations that input events may need applied. This is best
illustrated with an example. Consider a chain of layers, L, M, N, O, P, Q, R. Layer L
is the layer that corresponds to the argument |aApzc|, and layer R is the root
of the layer tree. Layer M is the parent of L, N is the parent of M, and so on.
@ -1258,7 +1253,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
MT.Inverse()
MN.Inverse()
MC.Inverse()
This combined transformation is returned in the aTransformToApzcOut out-parameter.
This combined transformation is returned by GetScreenToApzcTransform().
Next, if we want user inputs sent to gecko for event-dispatching, we will need to strip
out all of the async transforms that are involved in this chain. This is because async
@ -1290,7 +1285,7 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
RC
RD
This sequence can be simplified and refactored to the following:
aTransformToApzcOut
GetScreenToApzcTransform()
LA.Inverse()
LD
MC
@ -1298,9 +1293,9 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
...
RC
RD
Since aTransformToApzcOut is already one of the out-parameters, we set aTransformToGeckoOut
to the remaining transforms (LA.Inverse() * LD * ... * RD), so that the caller code can
combine it with aTransformToApzcOut to get the final transform required in this case.
Since GetScreenToApzcTransform() can be obtained by calling that function, GetApzcToGeckoTransform()
returns the remaining transforms (LA.Inverse() * LD * ... * RD), so that the caller code can
combine it with GetScreenToApzcTransform() to get the final transform required in this case.
Note that for many of these layers, there will be no AsyncPanZoomController attached, and
so the async transform will be the identity transform. So, in the example above, if layers
@ -1314,10 +1309,14 @@ APZCTreeManager::GetAPZCAtPoint(AsyncPanZoomController* aApzc,
The APZCs also obviously have LT, LN, PT, and PN, so all of the above transformation combinations
required can be generated.
*/
void
APZCTreeManager::GetInputTransforms(const AsyncPanZoomController *aApzc, Matrix4x4& aTransformToApzcOut,
Matrix4x4& aTransformToGeckoOut) const
/*
* See the long comment above for a detailed explanation of this function.
*/
Matrix4x4
APZCTreeManager::GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const
{
Matrix4x4 result;
MonitorAutoLock lock(mTreeLock);
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
@ -1329,34 +1328,64 @@ APZCTreeManager::GetInputTransforms(const AsyncPanZoomController *aApzc, Matrix4
// ancestorUntransform is PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
Matrix4x4 ancestorUntransform = aApzc->GetAncestorTransform();
ancestorUntransform.Invert();
// asyncUntransform is LA.Inverse()
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// aTransformToApzcOut is initialized to PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
aTransformToApzcOut = ancestorUntransform;
// aTransformToGeckoOut is initialized to LA.Inverse() * LD * MC * NC * OC * PC
aTransformToGeckoOut = asyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetAncestorTransform();
// result is initialized to PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
result = ancestorUntransform;
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P
ancestorUntransform = parent->GetAncestorTransform();
ancestorUntransform.Invert();
// asyncUntransform is updated to PA.Inverse() when parent == P
asyncUntransform = parent->GetCurrentAsyncTransform();
Matrix4x4 asyncUntransform = parent->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PA.Inverse()
Matrix4x4 untransformSinceLastApzc = ancestorUntransform * asyncUntransform;
// aTransformToApzcOut is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
aTransformToApzcOut = untransformSinceLastApzc * aTransformToApzcOut;
// aTransformToGeckoOut is LA.Inverse() * LD * MC * NC * OC * PC * PD * QC * RC
aTransformToGeckoOut = aTransformToGeckoOut * parent->GetTransformToLastDispatchedPaint() * parent->GetAncestorTransform();
// result is RC.Inverse() * QC.Inverse() * PA.Inverse() * PC.Inverse() * OC.Inverse() * NC.Inverse() * MC.Inverse()
result = untransformSinceLastApzc * result;
// The above values for aTransformToApzcOut and aTransformToGeckoOut when parent == P match
// the required output as explained in the comment above this method. Note that any missing
// The above value for result when parent == P matches the required output
// as explained in the comment above this method. Note that any missing
// terms are guaranteed to be identity transforms.
}
return result;
}
/*
* See the long comment above GetScreenToApzcTransform() for a detailed
* explanation of this function.
*/
Matrix4x4
APZCTreeManager::GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const
{
Matrix4x4 result;
MonitorAutoLock lock(mTreeLock);
// The comments below assume there is a chain of layers L..R with L and P having APZC instances as
// explained in the comment above. This function is called with aApzc at L, and the loop
// below performs one iteration, where parent is at P. The 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.
// asyncUntransform is LA.Inverse()
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransform();
asyncUntransform.Invert();
// aTransformToGeckoOut is initialized to LA.Inverse() * LD * MC * NC * OC * PC
result = asyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetAncestorTransform();
for (AsyncPanZoomController* parent = aApzc->GetParent(); parent; parent = parent->GetParent()) {
// aTransformToGeckoOut is LA.Inverse() * LD * MC * NC * OC * PC * PD * QC * RC
result = result * parent->GetTransformToLastDispatchedPaint() * parent->GetAncestorTransform();
// The above value for result when parent == P matches the required output
// as explained in the comment above this method. Note that any missing
// terms are guaranteed to be identity transforms.
}
return result;
}
already_AddRefed<AsyncPanZoomController>

View File

@ -361,9 +361,8 @@ public:
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScrollableLayerGuid& aGuid);
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint,
bool* aOutInOverscrolledApzc);
void GetInputTransforms(const AsyncPanZoomController *aApzc,
gfx::Matrix4x4& aTransformToApzcOut,
gfx::Matrix4x4& aTransformToGeckoOut) const;
gfx::Matrix4x4 GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) const;
gfx::Matrix4x4 GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) const;
private:
/* Helpers */
AsyncPanZoomController* FindTargetAPZC(AsyncPanZoomController* aApzc, FrameMetrics::ViewID aScrollId);

View File

@ -1453,9 +1453,7 @@ AsyncPanZoomController::ConvertToGecko(const ScreenPoint& aPoint, CSSPoint* aOut
{
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
Matrix4x4 transformToApzc;
Matrix4x4 transformToGecko;
treeManagerLocal->GetInputTransforms(this, transformToApzc, transformToGecko);
Matrix4x4 transformToGecko = treeManagerLocal->GetApzcToGeckoTransform(this);
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.

View File

@ -1505,7 +1505,8 @@ protected:
already_AddRefed<AsyncPanZoomController> GetTargetAPZC(const ScreenPoint& aPoint) {
nsRefPtr<AsyncPanZoomController> hit = manager->GetTargetAPZC(aPoint, nullptr);
if (hit) {
manager->GetInputTransforms(hit.get(), transformToApzc, transformToGecko);
transformToApzc = manager->GetScreenToApzcTransform(hit.get());
transformToGecko = manager->GetApzcToGeckoTransform(hit.get());
}
return hit.forget();
}