Bug 1402498 - Rename AsyncScrollBase to ScrollAnimationPhysics and use composition instead of inheritance. r=rhunt

MozReview-Commit-ID: 7UFf0mZsrEr

--HG--
rename : layout/generic/AsyncScrollBase.cpp => layout/generic/ScrollAnimationPhysics.cpp
rename : layout/generic/AsyncScrollBase.h => layout/generic/ScrollAnimationPhysics.h
extra : rebase_source : 66cc26ef54b31d5cfe498d8f23bc678862423aa5
This commit is contained in:
Markus Stange 2017-09-22 13:42:29 -04:00
Родитель 0b21de814f
Коммит 488f43bd92
10 изменённых файлов: 91 добавлений и 90 удалений

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

@ -21,7 +21,7 @@
#include "nsPresContext.h"
#include "prtime.h"
#include "Units.h"
#include "AsyncScrollBase.h"
#include "ScrollAnimationPhysics.h"
namespace mozilla {

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

@ -15,8 +15,8 @@ namespace layers {
GenericScrollAnimation::GenericScrollAnimation(AsyncPanZoomController& aApzc,
const nsPoint& aInitialPosition)
: AsyncScrollBase(aInitialPosition)
, mApzc(aApzc)
: mApzc(aApzc)
, mAnimationPhysics(aInitialPosition)
, mFinalDestination(aInitialPosition)
, mForceVerticalOverscroll(false)
{
@ -41,8 +41,8 @@ GenericScrollAnimation::UpdateDestination(TimeStamp aTime, nsPoint aDestination,
void
GenericScrollAnimation::Update(TimeStamp aTime, const nsSize& aCurrentVelocity)
{
if (mIsFirstIteration) {
InitializeHistory(aTime);
if (mAnimationPhysics.mIsFirstIteration) {
mAnimationPhysics.InitializeHistory(aTime);
}
// Clamp the final destination to the scrollable area.
@ -51,7 +51,7 @@ GenericScrollAnimation::Update(TimeStamp aTime, const nsSize& aCurrentVelocity)
clamped.y = mApzc.mY.ClampOriginToScrollableRect(clamped.y);
mFinalDestination = CSSPoint::ToAppUnits(clamped);
AsyncScrollBase::Update(aTime, mFinalDestination, aCurrentVelocity);
mAnimationPhysics.Update(aTime, mFinalDestination, aCurrentVelocity);
}
bool
@ -63,10 +63,10 @@ GenericScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, const TimeDuration
// If the animation is finished, make sure the final position is correct by
// using one last displacement. Otherwise, compute the delta via the timing
// function as normal.
bool finished = IsFinished(now);
bool finished = mAnimationPhysics.IsFinished(now);
nsPoint sampledDest = finished
? mDestination
: PositionAt(now);
? mAnimationPhysics.mDestination
: mAnimationPhysics.PositionAt(now);
ParentLayerPoint displacement =
(CSSPoint::FromAppUnits(sampledDest) - aFrameMetrics.GetScrollOffset()) * zoom;
@ -75,7 +75,7 @@ GenericScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, const TimeDuration
mApzc.mY.SetVelocity(0);
} else if (!IsZero(displacement)) {
// Convert velocity from AppUnits/Seconds to ParentLayerCoords/Milliseconds
nsSize velocity = VelocityAt(now);
nsSize velocity = mAnimationPhysics.VelocityAt(now);
ParentLayerPoint velocityPL =
CSSPoint::FromAppUnits(nsPoint(velocity.width, velocity.height)) * zoom;
mApzc.mX.SetVelocity(velocityPL.x / 1000.0);

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

@ -8,7 +8,7 @@
#define mozilla_layers_GenericScrollAnimation_h_
#include "AsyncPanZoomAnimation.h"
#include "AsyncScrollBase.h"
#include "ScrollAnimationPhysics.h"
namespace mozilla {
namespace layers {
@ -16,8 +16,7 @@ namespace layers {
class AsyncPanZoomController;
class GenericScrollAnimation
: public AsyncPanZoomAnimation,
public AsyncScrollBase
: public AsyncPanZoomAnimation
{
public:
GenericScrollAnimation(AsyncPanZoomController& aApzc,
@ -37,6 +36,7 @@ private:
protected:
AsyncPanZoomController& mApzc;
ScrollAnimationPhysics mAnimationPhysics;
nsPoint mFinalDestination;
bool mForceVerticalOverscroll;
};

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

@ -6,7 +6,7 @@
#include "InputBlockState.h"
#include "AsyncPanZoomController.h" // for AsyncPanZoomController
#include "AsyncScrollBase.h" // for kScrollSeriesTimeoutMs
#include "ScrollAnimationPhysics.h" // for kScrollSeriesTimeoutMs
#include "gfxPrefs.h" // for gfxPrefs
#include "mozilla/MouseEvents.h"
#include "mozilla/Telemetry.h" // for Telemetry

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

@ -19,25 +19,25 @@ KeyboardScrollAnimation::KeyboardScrollAnimation(AsyncPanZoomController& aApzc,
switch (aType) {
case KeyboardScrollAction::eScrollCharacter:
case KeyboardScrollAction::eScrollLine: {
mOriginMaxMS = clamped(gfxPrefs::LineSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::LineSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(gfxPrefs::LineSmoothScrollMaxDurationMs(), 0, 10000);
mAnimationPhysics.mOriginMinMS = clamped(gfxPrefs::LineSmoothScrollMinDurationMs(), 0, mAnimationPhysics.mOriginMaxMS);
break;
}
case KeyboardScrollAction::eScrollPage: {
mOriginMaxMS = clamped(gfxPrefs::PageSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::PageSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(gfxPrefs::PageSmoothScrollMaxDurationMs(), 0, 10000);
mAnimationPhysics.mOriginMinMS = clamped(gfxPrefs::PageSmoothScrollMinDurationMs(), 0, mAnimationPhysics.mOriginMaxMS);
break;
}
case KeyboardScrollAction::eScrollComplete: {
mOriginMaxMS = clamped(gfxPrefs::OtherSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::OtherSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(gfxPrefs::OtherSmoothScrollMaxDurationMs(), 0, 10000);
mAnimationPhysics.mOriginMinMS = clamped(gfxPrefs::OtherSmoothScrollMinDurationMs(), 0, mAnimationPhysics.mOriginMaxMS);
break;
}
}
// The pref is 100-based int percentage, while mIntervalRatio is 1-based ratio
mIntervalRatio = ((double)gfxPrefs::SmoothScrollDurationToIntervalRatio()) / 100.0;
mIntervalRatio = std::max(1.0, mIntervalRatio);
mAnimationPhysics.mIntervalRatio = ((double)gfxPrefs::SmoothScrollDurationToIntervalRatio()) / 100.0;
mAnimationPhysics.mIntervalRatio = std::max(1.0, mAnimationPhysics.mIntervalRatio);
}
} // namespace layers

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

@ -22,22 +22,22 @@ WheelScrollAnimation::WheelScrollAnimation(AsyncPanZoomController& aApzc,
switch (aDeltaType) {
case ScrollWheelInput::SCROLLDELTA_PAGE:
mOriginMaxMS = clamped(gfxPrefs::PageSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::PageSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(gfxPrefs::PageSmoothScrollMaxDurationMs(), 0, 10000);
mAnimationPhysics.mOriginMinMS = clamped(gfxPrefs::PageSmoothScrollMinDurationMs(), 0, mAnimationPhysics.mOriginMaxMS);
break;
case ScrollWheelInput::SCROLLDELTA_PIXEL:
mOriginMaxMS = clamped(gfxPrefs::PixelSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::PixelSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(gfxPrefs::PixelSmoothScrollMaxDurationMs(), 0, 10000);
mAnimationPhysics.mOriginMinMS = clamped(gfxPrefs::PixelSmoothScrollMinDurationMs(), 0, mAnimationPhysics.mOriginMaxMS);
break;
case ScrollWheelInput::SCROLLDELTA_LINE:
mOriginMaxMS = clamped(gfxPrefs::WheelSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::WheelSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(gfxPrefs::WheelSmoothScrollMaxDurationMs(), 0, 10000);
mAnimationPhysics.mOriginMinMS = clamped(gfxPrefs::WheelSmoothScrollMinDurationMs(), 0, mAnimationPhysics.mOriginMaxMS);
break;
}
// The pref is 100-based int percentage, while mIntervalRatio is 1-based ratio
mIntervalRatio = ((double)gfxPrefs::SmoothScrollDurationToIntervalRatio()) / 100.0;
mIntervalRatio = std::max(1.0, mIntervalRatio);
mAnimationPhysics.mIntervalRatio = ((double)gfxPrefs::SmoothScrollDurationToIntervalRatio()) / 100.0;
mAnimationPhysics.mIntervalRatio = std::max(1.0, mAnimationPhysics.mIntervalRatio);
}
} // namespace layers

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

@ -3,21 +3,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AsyncScrollBase.h"
#include "ScrollAnimationPhysics.h"
#include "gfxPrefs.h"
using namespace mozilla;
AsyncScrollBase::AsyncScrollBase(nsPoint aStartPos)
ScrollAnimationPhysics::ScrollAnimationPhysics(nsPoint aStartPos)
: mIsFirstIteration(true)
, mStartPos(aStartPos)
{
}
void
AsyncScrollBase::Update(TimeStamp aTime,
nsPoint aDestination,
const nsSize& aCurrentVelocity)
ScrollAnimationPhysics::Update(TimeStamp aTime,
nsPoint aDestination,
const nsSize& aCurrentVelocity)
{
TimeDuration duration = ComputeDuration(aTime);
nsSize currentVelocity = aCurrentVelocity;
@ -47,7 +47,7 @@ AsyncScrollBase::Update(TimeStamp aTime,
}
TimeDuration
AsyncScrollBase::ComputeDuration(TimeStamp aTime)
ScrollAnimationPhysics::ComputeDuration(TimeStamp aTime)
{
// Average last 3 delta durations (rounding errors up to 2ms are negligible for us)
int32_t eventsDeltaMs = (aTime - mPrevEventTime[2]).ToMilliseconds() / 3;
@ -66,7 +66,7 @@ AsyncScrollBase::ComputeDuration(TimeStamp aTime)
}
void
AsyncScrollBase::InitializeHistory(TimeStamp aTime)
ScrollAnimationPhysics::InitializeHistory(TimeStamp aTime)
{
// Starting a new scroll (i.e. not when extending an existing scroll animation),
// create imaginary prev timestamps with maximum relevant intervals between them.
@ -79,10 +79,10 @@ AsyncScrollBase::InitializeHistory(TimeStamp aTime)
}
void
AsyncScrollBase::InitTimingFunction(nsSMILKeySpline& aTimingFunction,
nscoord aCurrentPos,
nscoord aCurrentVelocity,
nscoord aDestination)
ScrollAnimationPhysics::InitTimingFunction(nsSMILKeySpline& aTimingFunction,
nscoord aCurrentPos,
nscoord aCurrentVelocity,
nscoord aDestination)
{
if (aDestination == aCurrentPos || gfxPrefs::SmoothScrollCurrentVelocityWeighting() == 0) {
aTimingFunction.Init(0, 0, 1 - gfxPrefs::SmoothScrollStopDecelerationWeighting(), 1);
@ -98,7 +98,7 @@ AsyncScrollBase::InitTimingFunction(nsSMILKeySpline& aTimingFunction,
}
nsPoint
AsyncScrollBase::PositionAt(TimeStamp aTime) const
ScrollAnimationPhysics::PositionAt(TimeStamp aTime) const
{
double progressX = mTimingFunctionX.GetSplineValue(ProgressAt(aTime));
double progressY = mTimingFunctionY.GetSplineValue(ProgressAt(aTime));
@ -107,7 +107,7 @@ AsyncScrollBase::PositionAt(TimeStamp aTime) const
}
nsSize
AsyncScrollBase::VelocityAt(TimeStamp aTime) const
ScrollAnimationPhysics::VelocityAt(TimeStamp aTime) const
{
double timeProgress = ProgressAt(aTime);
return nsSize(VelocityComponent(timeProgress, mTimingFunctionX,
@ -117,10 +117,10 @@ AsyncScrollBase::VelocityAt(TimeStamp aTime) const
}
nscoord
AsyncScrollBase::VelocityComponent(double aTimeProgress,
const nsSMILKeySpline& aTimingFunction,
nscoord aStart,
nscoord aDestination) const
ScrollAnimationPhysics::VelocityComponent(double aTimeProgress,
const nsSMILKeySpline& aTimingFunction,
nscoord aStart,
nscoord aDestination) const
{
double dt, dxy;
aTimingFunction.GetSplineDerivativeValues(aTimeProgress, dt, dxy);

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

@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_layout_AsyncScrollBase_h_
#define mozilla_layout_AsyncScrollBase_h_
#ifndef mozilla_layout_ScrollAnimationPhysics_h_
#define mozilla_layout_ScrollAnimationPhysics_h_
#include "mozilla/TimeStamp.h"
#include "nsPoint.h"
@ -14,13 +14,13 @@ namespace mozilla {
// This is the base class for driving scroll wheel animation on both the
// compositor and main thread.
class AsyncScrollBase
class ScrollAnimationPhysics
{
public:
typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration;
explicit AsyncScrollBase(nsPoint aStartPos);
explicit ScrollAnimationPhysics(nsPoint aStartPos);
void Update(TimeStamp aTime,
nsPoint aDestination,
@ -37,6 +37,21 @@ public:
return aTime > mStartTime + mDuration;
}
// Initialize event history.
void InitializeHistory(TimeStamp aTime);
// Cached Preferences value.
//
// These values are minimum and maximum animation duration per event origin,
// and a global ratio which defines how longer is the animation's duration
// compared to the average recent events intervals (such that for a relatively
// consistent events rate, the next event arrives before current animation ends)
int32_t mOriginMinMS;
int32_t mOriginMaxMS;
double mIntervalRatio;
nsPoint mDestination;
bool mIsFirstIteration;
protected:
double ProgressAt(TimeStamp aTime) const {
return clamped((aTime - mStartTime) / mDuration, 0.0, 1.0);
@ -51,9 +66,6 @@ protected:
// here).
TimeDuration ComputeDuration(TimeStamp aTime);
// Initialize event history.
void InitializeHistory(TimeStamp aTime);
// Initializes the timing function in such a way that the current velocity is
// preserved.
void InitTimingFunction(nsSMILKeySpline& aTimingFunction,
@ -66,23 +78,11 @@ protected:
// initialize mPrevEventTime using imaginary previous timestamps with maximum
// relevant intervals between them.
TimeStamp mPrevEventTime[3];
bool mIsFirstIteration;
TimeStamp mStartTime;
// Cached Preferences value.
//
// These values are minimum and maximum animation duration per event origin,
// and a global ratio which defines how longer is the animation's duration
// compared to the average recent events intervals (such that for a relatively
// consistent events rate, the next event arrives before current animation ends)
int32_t mOriginMinMS;
int32_t mOriginMaxMS;
double mIntervalRatio;
nsPoint mStartPos;
TimeDuration mDuration;
nsPoint mDestination;
nsSMILKeySpline mTimingFunctionX;
nsSMILKeySpline mTimingFunctionY;
};
@ -102,4 +102,4 @@ static const uint32_t kScrollSeriesTimeoutMs = 80; // in milliseconds
} // namespace mozilla
#endif // mozilla_layout_AsyncScrollBase_h_
#endif // mozilla_layout_ScrollAnimationPhysics_h_

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

@ -68,7 +68,6 @@ with Files('nsVideoFrame.*'):
BUG_COMPONENT = ('Core', 'Audio/Video')
EXPORTS += [
'AsyncScrollBase.h',
'nsCanvasFrame.h',
'nsContainerFrame.h',
'nsDirection.h',
@ -101,6 +100,7 @@ EXPORTS += [
'nsTextFrameUtils.h',
'nsTextRunTransformations.h',
'RubyUtils.h',
'ScrollAnimationPhysics.h',
'ScrollbarActivity.h',
'ScrollSnap.h',
'TextDrawTarget.h',
@ -122,7 +122,6 @@ EXPORTS.mozilla.layout += [
]
UNIFIED_SOURCES += [
'AsyncScrollBase.cpp',
'BlockReflowInput.cpp',
'BRFrame.cpp',
'CSSAlignUtils.cpp',
@ -177,6 +176,7 @@ UNIFIED_SOURCES += [
'ReflowInput.cpp',
'ReflowOutput.cpp',
'RubyUtils.cpp',
'ScrollAnimationPhysics.cpp',
'ScrollbarActivity.cpp',
'ScrollSnap.cpp',
'ScrollVelocityQueue.cpp',

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

@ -57,7 +57,7 @@
#include "nsIFrameInlines.h"
#include "gfxPlatform.h"
#include "gfxPrefs.h"
#include "AsyncScrollBase.h"
#include "ScrollAnimationPhysics.h"
#include "ScrollSnap.h"
#include "UnitTransforms.h"
#include "nsPluginFrame.h"
@ -1799,15 +1799,14 @@ private:
// AsyncScroll has ref counting.
class ScrollFrameHelper::AsyncScroll final
: public nsARefreshObserver,
public AsyncScrollBase
: public nsARefreshObserver
{
public:
typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration;
explicit AsyncScroll(nsPoint aStartPos)
: AsyncScrollBase(aStartPos)
: mAnimationPhysics(aStartPos)
, mCallee(nullptr)
{
Telemetry::SetHistogramRecordingEnabled(
@ -1830,6 +1829,8 @@ public:
mRange = aRange;
}
ScrollAnimationPhysics mAnimationPhysics;
// Most recent scroll origin.
RefPtr<nsIAtom> mOrigin;
@ -1906,14 +1907,14 @@ ScrollFrameHelper::AsyncScroll::InitPreferences(TimeStamp aTime, nsIAtom *aOrigi
MOZ_ASSERT(aOrigin != nsGkAtoms::apz);
// Read preferences only on first iteration or for a different event origin.
if (!mIsFirstIteration && aOrigin == mOrigin) {
if (!mAnimationPhysics.mIsFirstIteration && aOrigin == mOrigin) {
return;
}
mOrigin = aOrigin;
mOriginMinMS = mOriginMaxMS = 0;
mAnimationPhysics.mOriginMinMS = mAnimationPhysics.mOriginMaxMS = 0;
bool isOriginSmoothnessEnabled = false;
mIntervalRatio = 1;
mAnimationPhysics.mIntervalRatio = 1;
// Default values for all preferences are defined in all.js
static const int32_t kDefaultMinMS = 150, kDefaultMaxMS = 150;
@ -1927,25 +1928,25 @@ ScrollFrameHelper::AsyncScroll::InitPreferences(TimeStamp aTime, nsIAtom *aOrigi
if (isOriginSmoothnessEnabled) {
nsAutoCString prefMin = prefBase + NS_LITERAL_CSTRING(".durationMinMS");
nsAutoCString prefMax = prefBase + NS_LITERAL_CSTRING(".durationMaxMS");
mOriginMinMS = Preferences::GetInt(prefMin.get(), kDefaultMinMS);
mOriginMaxMS = Preferences::GetInt(prefMax.get(), kDefaultMaxMS);
mAnimationPhysics.mOriginMinMS = Preferences::GetInt(prefMin.get(), kDefaultMinMS);
mAnimationPhysics.mOriginMaxMS = Preferences::GetInt(prefMax.get(), kDefaultMaxMS);
static const int32_t kSmoothScrollMaxAllowedAnimationDurationMS = 10000;
mOriginMaxMS = clamped(mOriginMaxMS, 0, kSmoothScrollMaxAllowedAnimationDurationMS);
mOriginMinMS = clamped(mOriginMinMS, 0, mOriginMaxMS);
mAnimationPhysics.mOriginMaxMS = clamped(mAnimationPhysics.mOriginMaxMS, 0, kSmoothScrollMaxAllowedAnimationDurationMS);
mAnimationPhysics.mOriginMinMS = clamped(mAnimationPhysics.mOriginMinMS, 0, mAnimationPhysics.mOriginMaxMS);
}
// Keep the animation duration longer than the average event intervals
// (to "connect" consecutive scroll animations before the scroll comes to a stop).
static const double kDefaultDurationToIntervalRatio = 2; // Duplicated at all.js
mIntervalRatio = Preferences::GetInt("general.smoothScroll.durationToIntervalRatio",
kDefaultDurationToIntervalRatio * 100) / 100.0;
mAnimationPhysics.mIntervalRatio = Preferences::GetInt("general.smoothScroll.durationToIntervalRatio",
kDefaultDurationToIntervalRatio * 100) / 100.0;
// Duration should be at least as long as the intervals -> ratio is at least 1
mIntervalRatio = std::max(1.0, mIntervalRatio);
mAnimationPhysics.mIntervalRatio = std::max(1.0, mAnimationPhysics.mIntervalRatio);
if (mIsFirstIteration) {
InitializeHistory(aTime);
if (mAnimationPhysics.mIsFirstIteration) {
mAnimationPhysics.InitializeHistory(aTime);
}
}
@ -1959,7 +1960,7 @@ ScrollFrameHelper::AsyncScroll::InitSmoothScroll(TimeStamp aTime,
InitPreferences(aTime, aOrigin);
mRange = aRange;
Update(aTime, aDestination, aCurrentVelocity);
mAnimationPhysics.Update(aTime, aDestination, aCurrentVelocity);
}
bool
@ -2128,8 +2129,8 @@ ScrollFrameHelper::AsyncScrollCallback(ScrollFrameHelper* aInstance,
nsRect range = aInstance->mAsyncScroll->mRange;
if (aInstance->mAsyncScroll->mIsSmoothScroll) {
if (!aInstance->mAsyncScroll->IsFinished(aTime)) {
nsPoint destination = aInstance->mAsyncScroll->PositionAt(aTime);
if (!aInstance->mAsyncScroll->mAnimationPhysics.IsFinished(aTime)) {
nsPoint destination = aInstance->mAsyncScroll->mAnimationPhysics.PositionAt(aTime);
// Allow this scroll operation to land on any pixel boundary between the
// current position and the final allowed range. (We don't want
// intermediate steps to be more constrained than the final step!)
@ -2292,7 +2293,7 @@ ScrollFrameHelper::ScrollToWithOrigin(nsPoint aScrollPosition,
currentVelocity.height = sv.y;
if (mAsyncScroll) {
if (mAsyncScroll->mIsSmoothScroll) {
currentVelocity = mAsyncScroll->VelocityAt(now);
currentVelocity = mAsyncScroll->mAnimationPhysics.VelocityAt(now);
}
mAsyncScroll = nullptr;
}