mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 1063224 - Split APZCTreeManager::GetInputTransforms() into GetScreenToApzcTransform() and GetApzcToGeckoTransform(). r=kats
--HG-- extra : source : e2c2b60db0d0865c81bfadf0100763d35011136f
This commit is contained in:
parent
482d310a1f
commit
e35b939581
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user