Bug 1030221 - Move animation Sample functions into the class definition. r=drs

This commit is contained in:
Kartikaya Gupta 2014-06-26 18:49:11 -04:00
Родитель 57b791cdc7
Коммит 9a0452ea47
1 изменённых файлов: 122 добавлений и 127 удалений

Просмотреть файл

@ -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)
{