зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1030221 - Move animation Sample functions into the class definition. r=drs
This commit is contained in:
Родитель
57b791cdc7
Коммит
9a0452ea47
|
@ -461,7 +461,100 @@ public:
|
|||
* or false if there is no fling or the fling has ended.
|
||||
*/
|
||||
virtual bool Sample(FrameMetrics& aFrameMetrics,
|
||||
const TimeDuration& aDelta) MOZ_OVERRIDE;
|
||||
const TimeDuration& aDelta) MOZ_OVERRIDE
|
||||
{
|
||||
// If the fling is handed off to our APZC from a child, on the first call to
|
||||
// Sample() aDelta might be negative because it's computed as the sample time
|
||||
// from SampleContentTransformForFrame() minus our APZC's mLastSampleTime
|
||||
// which is the time the child handed off the fling from its call to
|
||||
// SampleContentTransformForFrame() with the same sample time. If we allow
|
||||
// the negative aDelta to be processed, it will yield a displacement in the
|
||||
// direction opposite to the fling, which can cause us to overscroll and
|
||||
// hand off the fling to _our_ parent, which effectively kills the fling.
|
||||
if (aDelta.ToMilliseconds() <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool overscrolled = mApzc.IsOverscrolled();
|
||||
float friction = overscrolled ? gfxPrefs::APZOverscrollFlingFriction()
|
||||
: gfxPrefs::APZFlingFriction();
|
||||
float threshold = overscrolled ? gfxPrefs::APZOverscrollFlingStoppedThreshold()
|
||||
: gfxPrefs::APZFlingStoppedThreshold();
|
||||
|
||||
bool shouldContinueFlingX = mApzc.mX.FlingApplyFrictionOrCancel(aDelta, friction, threshold),
|
||||
shouldContinueFlingY = mApzc.mY.FlingApplyFrictionOrCancel(aDelta, friction, threshold);
|
||||
// If we shouldn't continue the fling, let's just stop and repaint.
|
||||
if (!shouldContinueFlingX && !shouldContinueFlingY) {
|
||||
APZC_LOG("%p ending fling animation. overscrolled=%d\n", &mApzc, mApzc.IsOverscrolled());
|
||||
// If we are in overscroll, schedule the snap-back animation that relieves it.
|
||||
if (mApzc.IsOverscrolled()) {
|
||||
mDeferredTasks.append(NewRunnableMethod(&mApzc, &AsyncPanZoomController::StartSnapBack));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// AdjustDisplacement() zeroes out the Axis velocity if we're in overscroll.
|
||||
// Since we need to hand off the velocity to the tree manager in such a case,
|
||||
// we save it here. Would be ScreenVector instead of ScreenPoint if we had
|
||||
// vector classes.
|
||||
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
|
||||
|
||||
ScreenPoint offset = velocity * aDelta.ToMilliseconds();
|
||||
|
||||
// Inversely scale the offset by the resolution (when you're zoomed further in,
|
||||
// the same swipe should move you a shorter distance).
|
||||
CSSPoint cssOffset = offset / aFrameMetrics.GetZoom();
|
||||
CSSPoint overscroll;
|
||||
aFrameMetrics.ScrollBy(CSSPoint(
|
||||
mApzc.mX.AdjustDisplacement(cssOffset.x, overscroll.x),
|
||||
mApzc.mY.AdjustDisplacement(cssOffset.y, overscroll.y)
|
||||
));
|
||||
|
||||
// The fling may have caused us to reach the end of our scroll range.
|
||||
if (!IsZero(overscroll)) {
|
||||
if (mAllowOverscroll) {
|
||||
// If this is a fling that allows overscroll, then go into overscroll.
|
||||
|
||||
mApzc.OverscrollBy(overscroll);
|
||||
|
||||
// Restore the velocity of the fling, which was zeroed out by
|
||||
// AdjustDisplacement().
|
||||
mApzc.mX.SetVelocity(velocity.x);
|
||||
mApzc.mY.SetVelocity(velocity.y);
|
||||
|
||||
} else {
|
||||
// Otherwise, hand off the fling to the next APZC in the overscroll
|
||||
// handoff chain.
|
||||
|
||||
// We may have reached the end of the scroll range along one axis but
|
||||
// not the other. In such a case we only want to hand off the relevant
|
||||
// component of the fling.
|
||||
if (FuzzyEqualsAdditive(overscroll.x, 0.0f, COORDINATE_EPSILON)) {
|
||||
velocity.x = 0;
|
||||
} else if (FuzzyEqualsAdditive(overscroll.y, 0.0f, COORDINATE_EPSILON)) {
|
||||
velocity.y = 0;
|
||||
}
|
||||
|
||||
// To hand off the fling, we attempt to find a target APZC and start a new
|
||||
// fling with the same velocity on that APZC. For simplicity, the actual
|
||||
// overscroll of the current sample is discarded rather than being handed
|
||||
// off. The compositor should sample animations sufficiently frequently
|
||||
// that this is not noticeable. The target APZC is chosen by seeing if
|
||||
// there is an APZC further in the handoff chain which is pannable; if
|
||||
// there isn't, we take the new fling ourselves, entering an overscrolled
|
||||
// state.
|
||||
// Note: APZC is holding mMonitor, so directly calling
|
||||
// HandleFlingOverscroll() (which acquires the tree lock) would violate
|
||||
// the lock ordering. Instead we schedule HandleFlingOverscroll() to be
|
||||
// called after mMonitor is released.
|
||||
mDeferredTasks.append(NewRunnableMethod(&mApzc,
|
||||
&AsyncPanZoomController::HandleFlingOverscroll,
|
||||
velocity));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool SameDirection(float aVelocity1, float aVelocity2)
|
||||
|
@ -493,7 +586,34 @@ public:
|
|||
{}
|
||||
|
||||
virtual bool Sample(FrameMetrics& aFrameMetrics,
|
||||
const TimeDuration& aDelta) MOZ_OVERRIDE;
|
||||
const TimeDuration& aDelta) MOZ_OVERRIDE
|
||||
{
|
||||
mDuration += aDelta;
|
||||
double animPosition = mDuration / mTotalDuration;
|
||||
|
||||
if (animPosition >= 1.0) {
|
||||
aFrameMetrics.SetZoom(mEndZoom);
|
||||
aFrameMetrics.SetScrollOffset(mEndOffset);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sample the zoom at the current time point. The sampled zoom
|
||||
// will affect the final computed resolution.
|
||||
double sampledPosition = gComputedTimingFunction->GetValue(animPosition);
|
||||
|
||||
// We scale the scrollOffset linearly with sampledPosition, so the zoom
|
||||
// needs to scale inversely to match.
|
||||
aFrameMetrics.SetZoom(CSSToScreenScale(1 /
|
||||
(sampledPosition / mEndZoom.scale +
|
||||
(1 - sampledPosition) / mStartZoom.scale)));
|
||||
|
||||
aFrameMetrics.SetScrollOffset(CSSPoint::FromUnknownPoint(gfx::Point(
|
||||
mEndOffset.x * sampledPosition + mStartOffset.x * (1 - sampledPosition),
|
||||
mEndOffset.y * sampledPosition + mStartOffset.y * (1 - sampledPosition)
|
||||
)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
TimeDuration mDuration;
|
||||
|
@ -1616,102 +1736,6 @@ ScreenIntPoint& AsyncPanZoomController::GetFirstTouchScreenPoint(const MultiTouc
|
|||
return ((SingleTouchData&)aEvent.mTouches[0]).mScreenPoint;
|
||||
}
|
||||
|
||||
bool FlingAnimation::Sample(FrameMetrics& aFrameMetrics,
|
||||
const TimeDuration& aDelta) {
|
||||
|
||||
// If the fling is handed off to our APZC from a child, on the first call to
|
||||
// Sample() aDelta might be negative because it's computed as the sample time
|
||||
// from SampleContentTransformForFrame() minus our APZC's mLastSampleTime
|
||||
// which is the time the child handed off the fling from its call to
|
||||
// SampleContentTransformForFrame() with the same sample time. If we allow
|
||||
// the negative aDelta to be processed, it will yield a displacement in the
|
||||
// direction opposite to the fling, which can cause us to overscroll and
|
||||
// hand off the fling to _our_ parent, which effectively kills the fling.
|
||||
if (aDelta.ToMilliseconds() <= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool overscrolled = mApzc.IsOverscrolled();
|
||||
float friction = overscrolled ? gfxPrefs::APZOverscrollFlingFriction()
|
||||
: gfxPrefs::APZFlingFriction();
|
||||
float threshold = overscrolled ? gfxPrefs::APZOverscrollFlingStoppedThreshold()
|
||||
: gfxPrefs::APZFlingStoppedThreshold();
|
||||
|
||||
bool shouldContinueFlingX = mApzc.mX.FlingApplyFrictionOrCancel(aDelta, friction, threshold),
|
||||
shouldContinueFlingY = mApzc.mY.FlingApplyFrictionOrCancel(aDelta, friction, threshold);
|
||||
// If we shouldn't continue the fling, let's just stop and repaint.
|
||||
if (!shouldContinueFlingX && !shouldContinueFlingY) {
|
||||
APZC_LOG("%p ending fling animation. overscrolled=%d\n", &mApzc, mApzc.IsOverscrolled());
|
||||
// If we are in overscroll, schedule the snap-back animation that relieves it.
|
||||
if (mApzc.IsOverscrolled()) {
|
||||
mDeferredTasks.append(NewRunnableMethod(&mApzc, &AsyncPanZoomController::StartSnapBack));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// AdjustDisplacement() zeroes out the Axis velocity if we're in overscroll.
|
||||
// Since we need to hand off the velocity to the tree manager in such a case,
|
||||
// we save it here. Would be ScreenVector instead of ScreenPoint if we had
|
||||
// vector classes.
|
||||
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
|
||||
|
||||
ScreenPoint offset = velocity * aDelta.ToMilliseconds();
|
||||
|
||||
// Inversely scale the offset by the resolution (when you're zoomed further in,
|
||||
// the same swipe should move you a shorter distance).
|
||||
CSSPoint cssOffset = offset / aFrameMetrics.GetZoom();
|
||||
CSSPoint overscroll;
|
||||
aFrameMetrics.ScrollBy(CSSPoint(
|
||||
mApzc.mX.AdjustDisplacement(cssOffset.x, overscroll.x),
|
||||
mApzc.mY.AdjustDisplacement(cssOffset.y, overscroll.y)
|
||||
));
|
||||
|
||||
// The fling may have caused us to reach the end of our scroll range.
|
||||
if (!IsZero(overscroll)) {
|
||||
if (mAllowOverscroll) {
|
||||
// If this is a fling that allows overscroll, then go into overscroll.
|
||||
|
||||
mApzc.OverscrollBy(overscroll);
|
||||
|
||||
// Restore the velocity of the fling, which was zeroed out by
|
||||
// AdjustDisplacement().
|
||||
mApzc.mX.SetVelocity(velocity.x);
|
||||
mApzc.mY.SetVelocity(velocity.y);
|
||||
|
||||
} else {
|
||||
// Otherwise, hand off the fling to the next APZC in the overscroll
|
||||
// handoff chain.
|
||||
|
||||
// We may have reached the end of the scroll range along one axis but
|
||||
// not the other. In such a case we only want to hand off the relevant
|
||||
// component of the fling.
|
||||
if (FuzzyEqualsAdditive(overscroll.x, 0.0f, COORDINATE_EPSILON)) {
|
||||
velocity.x = 0;
|
||||
} else if (FuzzyEqualsAdditive(overscroll.y, 0.0f, COORDINATE_EPSILON)) {
|
||||
velocity.y = 0;
|
||||
}
|
||||
|
||||
// To hand off the fling, we attempt to find a target APZC and start a new
|
||||
// fling with the same velocity on that APZC. For simplicity, the actual
|
||||
// overscroll of the current sample is discarded rather than being handed
|
||||
// off. The compositor should sample animations sufficiently frequently
|
||||
// that this is not noticeable. The target APZC is chosen by seeing if
|
||||
// there is an APZC further in the handoff chain which is pannable; if
|
||||
// there isn't, we take the new fling ourselves, entering an overscrolled
|
||||
// state.
|
||||
// Note: APZC is holding mMonitor, so directly calling
|
||||
// HandleFlingOverscroll() (which acquires the tree lock) would violate
|
||||
// the lock ordering. Instead we schedule HandleFlingOverscroll() to be
|
||||
// called after mMonitor is released.
|
||||
mDeferredTasks.append(NewRunnableMethod(&mApzc,
|
||||
&AsyncPanZoomController::HandleFlingOverscroll,
|
||||
velocity));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::StartAnimation(AsyncPanZoomAnimation* aAnimation)
|
||||
{
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
|
@ -1950,35 +1974,6 @@ AsyncPanZoomController::FireAsyncScrollOnTimeout()
|
|||
mAsyncScrollTimeoutTask = nullptr;
|
||||
}
|
||||
|
||||
bool ZoomAnimation::Sample(FrameMetrics& aFrameMetrics,
|
||||
const TimeDuration& aDelta) {
|
||||
mDuration += aDelta;
|
||||
double animPosition = mDuration / mTotalDuration;
|
||||
|
||||
if (animPosition >= 1.0) {
|
||||
aFrameMetrics.SetZoom(mEndZoom);
|
||||
aFrameMetrics.SetScrollOffset(mEndOffset);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sample the zoom at the current time point. The sampled zoom
|
||||
// will affect the final computed resolution.
|
||||
double sampledPosition = gComputedTimingFunction->GetValue(animPosition);
|
||||
|
||||
// We scale the scrollOffset linearly with sampledPosition, so the zoom
|
||||
// needs to scale inversely to match.
|
||||
aFrameMetrics.SetZoom(CSSToScreenScale(1 /
|
||||
(sampledPosition / mEndZoom.scale +
|
||||
(1 - sampledPosition) / mStartZoom.scale)));
|
||||
|
||||
aFrameMetrics.SetScrollOffset(CSSPoint::FromUnknownPoint(gfx::Point(
|
||||
mEndOffset.x * sampledPosition + mStartOffset.x * (1 - sampledPosition),
|
||||
mEndOffset.y * sampledPosition + mStartOffset.y * (1 - sampledPosition)
|
||||
)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
||||
Vector<Task*>* aOutDeferredTasks)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче