зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
be29505871
Коммит
13e12b0304
|
@ -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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче