Use the main-thread key spline animation logic for Desktop APZ. (bug 1139220 part 3, r=kats,kgilbert)

--HG--
extra : rebase_source : 17514c0bcaf4ac61c53ab1729a5084fd55b8ee11
This commit is contained in:
David Anderson 2015-04-01 23:42:40 -07:00
Родитель be29505871
Коммит 13e12b0304
10 изменённых файлов: 166 добавлений и 19 удалений

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

@ -880,7 +880,7 @@ APZCTreeManager::ProcessWheelEvent(WidgetWheelEvent& aEvent,
uint64_t* aOutInputBlockId)
{
ScrollWheelInput::ScrollMode scrollMode = ScrollWheelInput::SCROLLMODE_INSTANT;
if (Preferences::GetBool("general.smoothScroll")) {
if (gfxPrefs::SmoothScrollEnabled() && gfxPrefs::WheelSmoothScrollEnabled()) {
scrollMode = ScrollWheelInput::SCROLLMODE_SMOOTH;
}

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

@ -16,6 +16,8 @@
namespace mozilla {
namespace layers {
class WheelScrollAnimation;
class AsyncPanZoomAnimation {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomAnimation)
@ -58,6 +60,11 @@ public:
*/
TimeDuration mRepaintInterval;
public:
virtual WheelScrollAnimation* AsWheelScrollAnimation() {
return nullptr;
}
protected:
// Protected destructor, to discourage deletion outside of Release():
virtual ~AsyncPanZoomAnimation()

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

@ -64,6 +64,7 @@
#include "nsTArray.h" // for nsTArray, nsTArray_Impl, etc
#include "nsThreadUtils.h" // for NS_IsMainThread
#include "SharedMemoryBasic.h" // for SharedMemoryBasic
#include "WheelScrollAnimation.h"
// #define APZC_ENABLE_RENDERTRACE
@ -393,8 +394,9 @@ static TimeStamp sFrameTime;
// Counter used to give each APZC a unique id
static uint32_t sAsyncPanZoomControllerCount = 0;
static TimeStamp
GetFrameTime() {
TimeStamp
AsyncPanZoomController::GetFrameTime()
{
if (sFrameTime.IsNull()) {
return TimeStamp::Now();
}
@ -437,7 +439,7 @@ public:
, mOverscrollHandoffChain(aOverscrollHandoffChain)
{
MOZ_ASSERT(mOverscrollHandoffChain);
TimeStamp now = GetFrameTime();
TimeStamp now = AsyncPanZoomController::GetFrameTime();
// Drop any velocity on axes where we don't have room to scroll anyways.
// This ensures that we don't take the 'overscroll' path in Sample()
@ -1076,6 +1078,7 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
case ANIMATING_ZOOM:
case SMOOTH_SCROLL:
case OVERSCROLL_ANIMATION:
case WHEEL_SCROLL:
CurrentTouchBlock()->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll);
// Fall through.
case NOTHING: {
@ -1154,10 +1157,11 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent)
NS_WARNING("Gesture listener should have handled pinching in OnTouchMove.");
return nsEventStatus_eIgnore;
case WHEEL_SCROLL:
case OVERSCROLL_ANIMATION:
// Should not receive a touch-move in the OVERSCROLL_ANIMATION state
// as touch blocks that begin in an overscrolled state cancel the
// animation.
// animation. The same is true for wheel scroll animations.
NS_WARNING("Received impossible touch in OnTouchMove");
break;
}
@ -1243,10 +1247,11 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
NS_WARNING("Gesture listener should have handled pinching in OnTouchEnd.");
return nsEventStatus_eIgnore;
case WHEEL_SCROLL:
case OVERSCROLL_ANIMATION:
// Should not receive a touch-end in the OVERSCROLL_ANIMATION state
// as touch blocks that begin in an overscrolled state cancel the
// animation.
// animation. The same is true for WHEEL_SCROLL.
NS_WARNING("Received impossible touch in OnTouchEnd");
break;
}
@ -1547,17 +1552,25 @@ nsEventStatus AsyncPanZoomController::OnScrollWheel(const ScrollWheelInput& aEve
}
case ScrollWheelInput::SCROLLMODE_SMOOTH: {
CSSPoint delta = LayoutDevicePoint(deltaX, deltaY) / mFrameMetrics.GetDevPixelsPerCSSPixel();
// If we're already in a smooth scroll animation, don't cancel it. This
// lets us preserve the existing scrolling velocity.
if (mState != SMOOTH_SCROLL) {
if (mState != WHEEL_SCROLL) {
CancelAnimation();
mFrameMetrics.SetSmoothScrollOffset(mFrameMetrics.GetScrollOffset() + delta);
} else {
mFrameMetrics.SetSmoothScrollOffset(mFrameMetrics.GetSmoothScrollOffset() + delta);
SetState(WHEEL_SCROLL);
nsPoint initialPosition = CSSPoint::ToAppUnits(mFrameMetrics.GetScrollOffset());
StartAnimation(new WheelScrollAnimation(
*this,
initialPosition));
}
StartSmoothScroll(ScrollSource::Wheel);
// Cast velocity from ParentLayerPoints/ms to CSSPoints/ms then convert to
// appunits/second
nsPoint delta =
CSSPoint::ToAppUnits(LayoutDevicePoint(deltaX, deltaY) / mFrameMetrics.GetDevPixelsPerCSSPixel());
nsPoint velocity =
CSSPoint::ToAppUnits(CSSPoint(mX.GetVelocity(), mY.GetVelocity())) * 1000.0f;
WheelScrollAnimation* animation = mAnimation->AsWheelScrollAnimation();
animation->Update(aEvent.mTimeStamp, delta, nsSize(velocity.x, velocity.y));
break;
}
}

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

@ -742,6 +742,7 @@ protected:
the finger is lifted. */
SMOOTH_SCROLL, /* Smooth scrolling to destination. Used by
CSSOM-View smooth scroll-behavior */
WHEEL_SCROLL /* Smooth scrolling to a destination for a wheel event. */
};
// This is in theory protected by |mMonitor|; that is, it should be held whenever
@ -839,6 +840,11 @@ private:
friend class FlingAnimation;
friend class OverscrollAnimation;
friend class SmoothScrollAnimation;
friend class WheelScrollAnimation;
// Returns the cached current frame time.
static TimeStamp GetFrameTime();
// The initial velocity of the most recent fling.
ParentLayerPoint mLastFlingVelocity;
// The time at which the most recent fling started.

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

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "WheelScrollAnimation.h"
namespace mozilla {
namespace layers {
WheelScrollAnimation::WheelScrollAnimation(AsyncPanZoomController& aApzc, const nsPoint& aInitialPosition)
: AsyncScrollBase(aInitialPosition)
, mApzc(aApzc)
, mFinalDestination(aInitialPosition)
{
}
void
WheelScrollAnimation::Update(TimeStamp aTime, nsPoint aDelta, const nsSize& aCurrentVelocity)
{
InitPreferences(aTime);
mFinalDestination += aDelta;
AsyncScrollBase::Update(aTime, mFinalDestination, aCurrentVelocity);
}
bool
WheelScrollAnimation::DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta)
{
TimeStamp now = AsyncPanZoomController::GetFrameTime();
if (IsFinished(now)) {
return false;
}
CSSToParentLayerScale2D zoom = aFrameMetrics.GetZoom();
nsPoint position = PositionAt(now);
ParentLayerPoint displacement =
(CSSPoint::FromAppUnits(position) - aFrameMetrics.GetScrollOffset()) * zoom;
// Note: we ignore overscroll for wheel animations.
ParentLayerPoint adjustedOffset, overscroll;
mApzc.mX.AdjustDisplacement(displacement.x, adjustedOffset.x, overscroll.x);
mApzc.mY.AdjustDisplacement(displacement.y, adjustedOffset.y, overscroll.y,
!aFrameMetrics.AllowVerticalScrollWithWheel());
aFrameMetrics.ScrollBy(adjustedOffset / zoom);
return true;
}
void
WheelScrollAnimation::InitPreferences(TimeStamp aTime)
{
if (!mIsFirstIteration) {
return;
}
mOriginMaxMS = clamped(gfxPrefs::WheelSmoothScrollMaxDurationMs(), 0, 10000);
mOriginMinMS = clamped(gfxPrefs::WheelSmoothScrollMinDurationMs(), 0, mOriginMaxMS);
mIntervalRatio = (gfxPrefs::SmoothScrollDurationToIntervalRatio() * 100) / 100.0;
mIntervalRatio = std::max(1.0, mIntervalRatio);
if (mIsFirstIteration) {
InitializeHistory(aTime);
}
}
} // namespace layers
} // namespace mozilla

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

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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_layers_WheelScrollAnimation_h_
#define mozilla_layers_WheelScrollAnimation_h_
#include "AsyncPanZoomAnimation.h"
#include "AsyncScrollBase.h"
namespace mozilla {
namespace layers {
class WheelScrollAnimation
: public AsyncPanZoomAnimation,
public AsyncScrollBase
{
public:
WheelScrollAnimation(AsyncPanZoomController& aApzc, const nsPoint& aInitialPosition);
bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) override;
void Update(TimeStamp aTime, nsPoint aDelta, const nsSize& aCurrentVelocity);
WheelScrollAnimation* AsWheelScrollAnimation() override {
return this;
}
private:
void InitPreferences(TimeStamp aTime);
private:
AsyncPanZoomController& mApzc;
nsPoint mFinalDestination;
};
} // namespace layers
} // namespace mozilla
#endif // mozilla_layers_WheelScrollAnimation_h_

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

@ -231,6 +231,7 @@ UNIFIED_SOURCES += [
'apz/src/InputQueue.cpp',
'apz/src/OverscrollHandoffState.cpp',
'apz/src/TaskThrottler.cpp',
'apz/src/WheelScrollAnimation.cpp',
'apz/testutil/APZTestData.cpp',
'apz/util/ActiveElementManager.cpp',
'apz/util/APZCCallbackHelper.cpp',

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

@ -188,6 +188,15 @@ private:
DECL_GFX_PREF(Once, "dom.vr.add-test-devices", VRAddTestDevices, int32_t, 1);
DECL_GFX_PREF(Live, "dom.w3c_pointer_events.enabled", PointerEventsEnabled, bool, false);
DECL_GFX_PREF(Live, "general.smoothScroll", SmoothScrollEnabled, bool, true);
DECL_GFX_PREF(Live, "general.smoothScroll.durationToIntervalRatio",
SmoothScrollDurationToIntervalRatio, int32_t, 200);
DECL_GFX_PREF(Live, "general.smoothScroll.mouseWheel", WheelSmoothScrollEnabled, bool, true);
DECL_GFX_PREF(Live, "general.smoothScroll.mouseWheel.durationMaxMS",
WheelSmoothScrollMaxDurationMs, int32_t, 400);
DECL_GFX_PREF(Live, "general.smoothScroll.mouseWheel.durationMinMS",
WheelSmoothScrollMinDurationMs, int32_t, 200);
DECL_GFX_PREF(Once, "gfx.android.rgb16.force", AndroidRGB16Force, bool, false);
#if defined(ANDROID)
DECL_GFX_PREF(Once, "gfx.apitrace.enabled", UseApitrace, bool, false);

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

@ -33,6 +33,10 @@ public:
// units, relative to the scroll frame.
nsPoint PositionAt(TimeStamp aTime) const;
bool IsFinished(TimeStamp aTime) {
return aTime > mStartTime + mDuration;
}
protected:
double ProgressAt(TimeStamp aTime) const {
return clamped((aTime - mStartTime) / mDuration, 0.0, 1.0);

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

@ -1606,10 +1606,6 @@ public:
mRange = aRange;
}
bool IsFinished(TimeStamp aTime) {
return aTime > mStartTime + mDuration; // XXX or if we've hit the wall
}
// Most recent scroll origin.
nsCOMPtr<nsIAtom> mOrigin;