зеркало из https://github.com/mozilla/gecko-dev.git
Bug 951793 - Light refactoring to the fling handoff code. r=kats
Passing FlingHandoffState around as an in-out parameter was making the next change (respecting overscroll-behavior) messy. MozReview-Commit-ID: 4wuoll20Jt7 --HG-- extra : rebase_source : c5d843254a38196547119419d1a2ad1fd0f3ef09
This commit is contained in:
Родитель
d561386618
Коммит
2f514da8d8
|
@ -2029,16 +2029,16 @@ APZCTreeManager::DispatchScroll(AsyncPanZoomController* aPrev,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ParentLayerPoint
|
||||
APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
|
||||
FlingHandoffState& aHandoffState)
|
||||
const FlingHandoffState& aHandoffState)
|
||||
{
|
||||
// If immediate handoff is disallowed, do not allow handoff beyond the
|
||||
// single APZC that's scrolled by the input block that triggered this fling.
|
||||
if (aHandoffState.mIsHandoff &&
|
||||
!gfxPrefs::APZAllowImmediateHandoff() &&
|
||||
aHandoffState.mScrolledApzc == aPrev) {
|
||||
return;
|
||||
return aHandoffState.mVelocity;
|
||||
}
|
||||
|
||||
const OverscrollHandoffChain* chain = aHandoffState.mChain;
|
||||
|
@ -2046,9 +2046,6 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
|
|||
uint32_t overscrollHandoffChainLength = chain->Length();
|
||||
uint32_t startIndex;
|
||||
|
||||
// This will store any velocity left over after the entire handoff.
|
||||
ParentLayerPoint finalResidualVelocity = aHandoffState.mVelocity;
|
||||
|
||||
// The fling's velocity needs to be transformed from the screen coordinates
|
||||
// of |aPrev| to the screen coordinates of |next|. To transform a velocity
|
||||
// correctly, we need to convert it to a displacement. For now, we do this
|
||||
|
@ -2065,64 +2062,63 @@ APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
|
|||
// IndexOf will return aOverscrollHandoffChain->Length() if
|
||||
// |aPrev| is not found.
|
||||
if (startIndex >= overscrollHandoffChainLength) {
|
||||
return;
|
||||
return aHandoffState.mVelocity;
|
||||
}
|
||||
} else {
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
// This will store any velocity left over after the entire handoff.
|
||||
ParentLayerPoint finalResidualVelocity = aHandoffState.mVelocity;
|
||||
|
||||
ParentLayerPoint currentVelocity = aHandoffState.mVelocity;
|
||||
for (; startIndex < overscrollHandoffChainLength; startIndex++) {
|
||||
current = chain->GetApzcAtIndex(startIndex);
|
||||
|
||||
// Make sure the apcz about to be handled can be handled
|
||||
// Make sure the apzc about to be handled can be handled
|
||||
if (current == nullptr || current->IsDestroyed()) {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
endPoint = startPoint + aHandoffState.mVelocity;
|
||||
endPoint = startPoint + currentVelocity;
|
||||
|
||||
// Only transform when current apcz can be transformed with previous
|
||||
// Only transform when current apzc can be transformed with previous
|
||||
if (startIndex > 0) {
|
||||
if (!TransformDisplacement(this,
|
||||
chain->GetApzcAtIndex(startIndex - 1),
|
||||
current,
|
||||
startPoint,
|
||||
endPoint)) {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ParentLayerPoint transformedVelocity = endPoint - startPoint;
|
||||
aHandoffState.mVelocity = transformedVelocity;
|
||||
FlingHandoffState transformedHandoffState = aHandoffState;
|
||||
transformedHandoffState.mVelocity = (endPoint - startPoint);
|
||||
|
||||
if (current->AttemptFling(aHandoffState)) {
|
||||
// Coming out of AttemptFling(), the handoff state's velocity is the
|
||||
// residual velocity after attempting to fling |current|.
|
||||
ParentLayerPoint residualVelocity = aHandoffState.mVelocity;
|
||||
ParentLayerPoint residualVelocity = current->AttemptFling(transformedHandoffState);
|
||||
|
||||
// If there's no residual velocity, there's nothing more to hand off.
|
||||
if (IsZero(residualVelocity)) {
|
||||
finalResidualVelocity = ParentLayerPoint();
|
||||
break;
|
||||
return ParentLayerPoint();
|
||||
}
|
||||
|
||||
// If there is residual velocity, subtract the proportion of used
|
||||
// velocity from finalResidualVelocity and continue handoff along the
|
||||
// chain.
|
||||
if (!FuzzyEqualsAdditive(transformedVelocity.x,
|
||||
// If any of the velocity available to be handed off was consumed,
|
||||
// subtract the proportion of consumed velocity from finalResidualVelocity.
|
||||
if (!FuzzyEqualsAdditive(transformedHandoffState.mVelocity.x,
|
||||
residualVelocity.x, COORDINATE_EPSILON)) {
|
||||
finalResidualVelocity.x *= (residualVelocity.x / transformedVelocity.x);
|
||||
finalResidualVelocity.x *= (residualVelocity.x / transformedHandoffState.mVelocity.x);
|
||||
}
|
||||
if (!FuzzyEqualsAdditive(transformedVelocity.y,
|
||||
if (!FuzzyEqualsAdditive(transformedHandoffState.mVelocity.y,
|
||||
residualVelocity.y, COORDINATE_EPSILON)) {
|
||||
finalResidualVelocity.y *= (residualVelocity.y / transformedVelocity.y);
|
||||
}
|
||||
}
|
||||
finalResidualVelocity.y *= (residualVelocity.y / transformedHandoffState.mVelocity.y);
|
||||
}
|
||||
|
||||
// Set the handoff state's velocity to any residual velocity left over
|
||||
// after the entire handoff process.
|
||||
aHandoffState.mVelocity = finalResidualVelocity;
|
||||
currentVelocity = residualVelocity;
|
||||
}
|
||||
|
||||
// Return any residual velocity left over after the entire handoff process.
|
||||
return finalResidualVelocity;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -422,13 +422,14 @@ public:
|
|||
* start a fling (in this case the fling is given to the
|
||||
* first APZC in the chain)
|
||||
*
|
||||
* aHandoffState.mVelocity will be modified depending on how much of that
|
||||
* velocity has been consumed by APZCs in the overscroll hand-off chain.
|
||||
* The return value is the "residual velocity", the portion of
|
||||
* |aHandoffState.mVelocity| that was not consumed by APZCs in the
|
||||
* handoff chain doing flings.
|
||||
* The caller can use this value to determine whether it should consume
|
||||
* the excess velocity by going into an overscroll fling.
|
||||
* the excess velocity by going into overscroll.
|
||||
*/
|
||||
void DispatchFling(AsyncPanZoomController* aApzc,
|
||||
FlingHandoffState& aHandoffState);
|
||||
ParentLayerPoint DispatchFling(AsyncPanZoomController* aApzc,
|
||||
const FlingHandoffState& aHandoffState);
|
||||
|
||||
void StartScrollbarDrag(
|
||||
const ScrollableLayerGuid& aGuid,
|
||||
|
|
|
@ -1592,7 +1592,7 @@ nsEventStatus AsyncPanZoomController::HandleEndOfPan()
|
|||
// null before calling DispatchFling(). This is necessary because Destroy(),
|
||||
// which nulls out mTreeManager, could be called concurrently.
|
||||
if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
|
||||
FlingHandoffState handoffState{flingVelocity,
|
||||
const FlingHandoffState handoffState{flingVelocity,
|
||||
GetCurrentTouchBlock()->GetOverscrollHandoffChain(),
|
||||
false /* not handoff */,
|
||||
GetCurrentTouchBlock()->GetScrolledApzc()};
|
||||
|
@ -2787,20 +2787,25 @@ RefPtr<const OverscrollHandoffChain> AsyncPanZoomController::BuildOverscrollHand
|
|||
return result;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::AcceptFling(FlingHandoffState& aHandoffState) {
|
||||
ParentLayerPoint AsyncPanZoomController::AttemptFling(const FlingHandoffState& aHandoffState) {
|
||||
RecursiveMutexAutoLock lock(mRecursiveMutex);
|
||||
|
||||
if (!IsPannable()) {
|
||||
return aHandoffState.mVelocity;
|
||||
}
|
||||
|
||||
// We may have a pre-existing velocity for whatever reason (for example,
|
||||
// a previously handed off fling). We don't want to clobber that.
|
||||
APZC_LOG("%p accepting fling with velocity %s\n", this,
|
||||
Stringify(aHandoffState.mVelocity).c_str());
|
||||
ParentLayerPoint residualVelocity = aHandoffState.mVelocity;
|
||||
if (mX.CanScroll()) {
|
||||
mX.SetVelocity(mX.GetVelocity() + aHandoffState.mVelocity.x);
|
||||
aHandoffState.mVelocity.x = 0;
|
||||
residualVelocity.x = 0;
|
||||
}
|
||||
if (mY.CanScroll()) {
|
||||
mY.SetVelocity(mY.GetVelocity() + aHandoffState.mVelocity.y);
|
||||
aHandoffState.mVelocity.y = 0;
|
||||
residualVelocity.y = 0;
|
||||
}
|
||||
|
||||
// If there's a scroll snap point near the predicted fling destination,
|
||||
|
@ -2816,16 +2821,8 @@ void AsyncPanZoomController::AcceptFling(FlingHandoffState& aHandoffState) {
|
|||
aHandoffState.mScrolledApzc);
|
||||
StartAnimation(fling);
|
||||
}
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::AttemptFling(FlingHandoffState& aHandoffState) {
|
||||
// If we are pannable, take over the fling ourselves.
|
||||
if (IsPannable()) {
|
||||
AcceptFling(aHandoffState);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return residualVelocity;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
|
||||
|
@ -2833,13 +2830,13 @@ void AsyncPanZoomController::HandleFlingOverscroll(const ParentLayerPoint& aVelo
|
|||
const RefPtr<const AsyncPanZoomController>& aScrolledApzc) {
|
||||
APZCTreeManager* treeManagerLocal = GetApzcTreeManager();
|
||||
if (treeManagerLocal) {
|
||||
FlingHandoffState handoffState{aVelocity,
|
||||
const FlingHandoffState handoffState{aVelocity,
|
||||
aOverscrollHandoffChain,
|
||||
true /* handoff */,
|
||||
aScrolledApzc};
|
||||
treeManagerLocal->DispatchFling(this, handoffState);
|
||||
if (!IsZero(handoffState.mVelocity) && IsPannable() && gfxPrefs::APZOverscrollEnabled()) {
|
||||
mOverscrollEffect->HandleFlingOverscroll(handoffState.mVelocity);
|
||||
ParentLayerPoint residualVelocity = treeManagerLocal->DispatchFling(this, handoffState);
|
||||
if (!IsZero(residualVelocity) && IsPannable() && gfxPrefs::APZOverscrollEnabled()) {
|
||||
mOverscrollEffect->HandleFlingOverscroll(residualVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1002,16 +1002,14 @@ private:
|
|||
public:
|
||||
/**
|
||||
* Attempt a fling with the velocity specified in |aHandoffState|.
|
||||
* If we are not pannable, the fling is handed off to the next APZC in
|
||||
* the handoff chain via mTreeManager->DispatchFling().
|
||||
* Returns true iff. the entire velocity of the fling was consumed by
|
||||
* this APZC. |aHandoffState.mVelocity| is modified to contain any
|
||||
* unused, residual velocity.
|
||||
* |aHandoffState.mIsHandoff| should be true iff. the fling was handed off
|
||||
* from a previous APZC, and determines whether acceleration is applied
|
||||
* to the fling.
|
||||
* We only accept the fling in the direction(s) in which we are pannable.
|
||||
* Returns the "residual velocity", i.e. the portion of
|
||||
* |aHandoffState.mVelocity| that this APZC did not consume.
|
||||
*/
|
||||
bool AttemptFling(FlingHandoffState& aHandoffState);
|
||||
ParentLayerPoint AttemptFling(const FlingHandoffState& aHandoffState);
|
||||
|
||||
private:
|
||||
friend class AndroidFlingAnimation;
|
||||
|
@ -1044,9 +1042,6 @@ private:
|
|||
|
||||
void HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity);
|
||||
|
||||
// Helper function used by AttemptFling().
|
||||
void AcceptFling(FlingHandoffState& aHandoffState);
|
||||
|
||||
// Start an overscroll animation with the given initial velocity.
|
||||
void StartOverscrollAnimation(const ParentLayerPoint& aVelocity);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче