зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1375949 - Delay application of async scroll offset by one composite, to give content a chance to remain in sync. r=kats
With this in place, scroll-linked effects will remain in sync with async scrolling if they can be processed and painted within the frame budget. This change is currently behind a pref that's off by default. MozReview-Commit-ID: 6GEJTKZh6ON --HG-- extra : rebase_source : 534bf15ef1c5ca26e1dc0d7eb298063b80aa9dd3
This commit is contained in:
Родитель
8e4f219cfd
Коммит
a01f110229
|
@ -273,6 +273,13 @@ typedef GenericFlingAnimation FlingAnimation;
|
|||
* NOTE: Should not be set to anything
|
||||
* other than 0.0 for Android except for tests to disable flings.
|
||||
*
|
||||
* \li\b apz.frame_delay.enabled
|
||||
* If this is set to true, changes to the async scroll offset and async zoom
|
||||
* will not be immediately reflected in GetCurrentAsyncTransform() when called
|
||||
* with |AsyncTransformConsumer::eForCompositing|. Rather, the transform will
|
||||
* reflect the value of the async scroll offset and async zoom at the last time
|
||||
* SampleCompositedAsyncTransform() was called.
|
||||
*
|
||||
* \li\b apz.max_velocity_inches_per_ms
|
||||
* Maximum velocity. Velocity will be capped at this value if a faster fling
|
||||
* occurs. Negative values indicate unlimited velocity.\n
|
||||
|
@ -3218,6 +3225,12 @@ bool AsyncPanZoomController::UpdateAnimation(const TimeStamp& aSampleTime,
|
|||
if (mLastSampleTime == aSampleTime) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Sample the composited async transform once per composite. Note that we
|
||||
// call this after the |mLastSampleTime == aSampleTime| check, to ensure
|
||||
// it's only called once per APZC on each composite.
|
||||
SampleCompositedAsyncTransform();
|
||||
|
||||
TimeDuration sampleTimeDelta = aSampleTime - mLastSampleTime;
|
||||
mLastSampleTime = aSampleTime;
|
||||
|
||||
|
@ -3319,8 +3332,8 @@ AsyncPanZoomController::GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode
|
|||
return mLastContentPaintMetrics.GetScrollOffset() * mLastContentPaintMetrics.GetZoom();
|
||||
}
|
||||
|
||||
return (mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset)
|
||||
* mFrameMetrics.GetZoom() * mTestAsyncZoom.scale;
|
||||
return (GetEffectiveScrollOffset(aMode) + mTestAsyncScrollOffset)
|
||||
* GetEffectiveZoom(aMode) * mTestAsyncZoom.scale;
|
||||
}
|
||||
|
||||
CSSPoint
|
||||
|
@ -3331,7 +3344,7 @@ AsyncPanZoomController::GetCurrentAsyncScrollOffsetInCssPixels(AsyncTransformCon
|
|||
return mLastContentPaintMetrics.GetScrollOffset();
|
||||
}
|
||||
|
||||
return mFrameMetrics.GetScrollOffset() + mTestAsyncScrollOffset;
|
||||
return GetEffectiveScrollOffset(aMode) + mTestAsyncScrollOffset;
|
||||
}
|
||||
|
||||
AsyncTransform
|
||||
|
@ -3348,7 +3361,7 @@ AsyncPanZoomController::GetCurrentAsyncTransform(AsyncTransformConsumer aMode) c
|
|||
lastPaintScrollOffset = mLastContentPaintMetrics.GetScrollOffset();
|
||||
}
|
||||
|
||||
CSSPoint currentScrollOffset = mFrameMetrics.GetScrollOffset() +
|
||||
CSSPoint currentScrollOffset = GetEffectiveScrollOffset(aMode) +
|
||||
mTestAsyncScrollOffset;
|
||||
|
||||
// If checkerboarding has been disallowed, clamp the scroll position to stay
|
||||
|
@ -3369,14 +3382,44 @@ AsyncPanZoomController::GetCurrentAsyncTransform(AsyncTransformConsumer aMode) c
|
|||
}
|
||||
}
|
||||
|
||||
ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
|
||||
* mFrameMetrics.GetZoom() * mTestAsyncZoom.scale;
|
||||
CSSToParentLayerScale2D effectiveZoom = GetEffectiveZoom(aMode);
|
||||
|
||||
ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
|
||||
* effectiveZoom * mTestAsyncZoom.scale;
|
||||
|
||||
LayerToParentLayerScale compositedAsyncZoom =
|
||||
(effectiveZoom / mFrameMetrics.LayersPixelsPerCSSPixel()).ToScaleFactor();
|
||||
return AsyncTransform(
|
||||
LayerToParentLayerScale(mFrameMetrics.GetAsyncZoom().scale * mTestAsyncZoom.scale),
|
||||
LayerToParentLayerScale(compositedAsyncZoom.scale * mTestAsyncZoom.scale),
|
||||
-translation);
|
||||
}
|
||||
|
||||
CSSPoint
|
||||
AsyncPanZoomController::GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const
|
||||
{
|
||||
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
|
||||
return mCompositedScrollOffset;
|
||||
}
|
||||
return mFrameMetrics.GetScrollOffset();
|
||||
}
|
||||
|
||||
CSSToParentLayerScale2D
|
||||
AsyncPanZoomController::GetEffectiveZoom(AsyncTransformConsumer aMode) const
|
||||
{
|
||||
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
|
||||
return mCompositedZoom;
|
||||
}
|
||||
return mFrameMetrics.GetZoom();
|
||||
}
|
||||
|
||||
void
|
||||
AsyncPanZoomController::SampleCompositedAsyncTransform()
|
||||
{
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
mCompositedZoom = mFrameMetrics.GetZoom();
|
||||
}
|
||||
|
||||
AsyncTransformComponentMatrix
|
||||
AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const
|
||||
{
|
||||
|
@ -3628,6 +3671,9 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
|||
mExpectedGeckoMetrics = aLayerMetrics;
|
||||
ShareCompositorFrameMetrics();
|
||||
|
||||
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
mCompositedZoom = mFrameMetrics.GetZoom();
|
||||
|
||||
if (mFrameMetrics.GetDisplayPortMargins() != ScreenMargin()) {
|
||||
// A non-zero display port margin here indicates a displayport has
|
||||
// been set by a previous APZC for the content at this guid. The
|
||||
|
@ -3659,11 +3705,14 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
|||
needContentRepaint = true;
|
||||
}
|
||||
mFrameMetrics.ZoomBy(totalResolutionChange / presShellResolutionChange);
|
||||
mCompositedZoom.xScale *= (totalResolutionChange / presShellResolutionChange).width;
|
||||
mCompositedZoom.yScale *= (totalResolutionChange / presShellResolutionChange).height;
|
||||
} else {
|
||||
// Take the new zoom as either device scale or composition width or
|
||||
// viewport size got changed (e.g. due to orientation change, or content
|
||||
// changing the meta-viewport tag).
|
||||
mFrameMetrics.SetZoom(aLayerMetrics.GetZoom());
|
||||
mCompositedZoom = aLayerMetrics.GetZoom();
|
||||
mFrameMetrics.SetDevPixelsPerCSSPixel(aLayerMetrics.GetDevPixelsPerCSSPixel());
|
||||
}
|
||||
bool scrollableRectChanged = false;
|
||||
|
@ -3702,6 +3751,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe
|
|||
// correct this we need to update mExpectedGeckoMetrics to be the
|
||||
// last thing we know was painted by Gecko.
|
||||
mFrameMetrics.CopyScrollInfoFrom(aLayerMetrics);
|
||||
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
|
||||
mExpectedGeckoMetrics = aLayerMetrics;
|
||||
|
||||
// Cancel the animation (which might also trigger a repaint request)
|
||||
|
|
|
@ -731,6 +731,11 @@ private:
|
|||
// This allows us to transform events into Gecko's coordinate space.
|
||||
FrameMetrics mExpectedGeckoMetrics;
|
||||
|
||||
// These variables cache the scroll offset and zoom stored in |mFrameMetrics|
|
||||
// the last time SampleCompositedAsyncTransform() was called.
|
||||
CSSPoint mCompositedScrollOffset;
|
||||
CSSToParentLayerScale2D mCompositedZoom;
|
||||
|
||||
AxisX mX;
|
||||
AxisY mY;
|
||||
|
||||
|
@ -839,6 +844,26 @@ public:
|
|||
*/
|
||||
AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Samples the composited async transform, making the result of
|
||||
* |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
|
||||
* the async scroll offset and zoom stored in |mFrameMetrics|.
|
||||
*
|
||||
* (This is only relevant when |gfxPrefs::APZFrameDelayEnabled() == true|.
|
||||
* Otherwise, GetCurrentAsyncTransform() always reflects what's stored in
|
||||
* |mFrameMetrics| immediately, without any delay.)
|
||||
*/
|
||||
void SampleCompositedAsyncTransform();
|
||||
|
||||
/*
|
||||
* Helper functions to query the async scroll offset and zoom either
|
||||
* directly from |mFrameMetrics|, or from cached variables that store
|
||||
* the scroll offset and zoom from the last time it was sampled by
|
||||
* calling SampleCompositedAsyncTransform(), depending on who is asking.
|
||||
*/
|
||||
CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const;
|
||||
CSSToParentLayerScale2D GetEffectiveZoom(AsyncTransformConsumer aMode) const;
|
||||
|
||||
/* ===================================================================
|
||||
* The functions and members in this section are used to manage
|
||||
|
|
|
@ -311,6 +311,7 @@ private:
|
|||
DECL_GFX_PREF(Live, "apz.fling_min_velocity_threshold", APZFlingMinVelocityThreshold, float, 0.5f);
|
||||
DECL_GFX_PREF(Live, "apz.fling_stop_on_tap_threshold", APZFlingStopOnTapThreshold, float, 0.05f);
|
||||
DECL_GFX_PREF(Live, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f);
|
||||
DECL_GFX_PREF(Live, "apz.frame_delay.enabled", APZFrameDelayEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.highlight_checkerboarded_areas", APZHighlightCheckerboardedAreas, bool, false);
|
||||
DECL_GFX_PREF(Once, "apz.keyboard.enabled", APZKeyboardEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.max_velocity_inches_per_ms", APZMaxVelocity, float, -1.0f);
|
||||
|
|
|
@ -695,6 +695,7 @@ pref("apz.fling_friction", "0.002");
|
|||
pref("apz.fling_min_velocity_threshold", "0.5");
|
||||
pref("apz.fling_stop_on_tap_threshold", "0.05");
|
||||
pref("apz.fling_stopped_threshold", "0.01");
|
||||
pref("apz.frame_delay.enabled", false);
|
||||
pref("apz.highlight_checkerboarded_areas", false);
|
||||
pref("apz.keyboard.enabled", false);
|
||||
pref("apz.max_velocity_inches_per_ms", "-1.0");
|
||||
|
|
Загрузка…
Ссылка в новой задаче