Bug 1466611 - Use cached layout viewport when appropriate, only draw for RCD-RSF. r?botond
Adds GetEffectiveLayoutViewport to use the cached layout viewport when APZ
frame delay is enabled, similar to GetEffectiveScrollOffset / GetEffectiveZoom.
MozReview-Commit-ID: 3CyLqJ3AyrH
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -76,21 +76,21 @@ public:
*/
LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb(
const LayerToParentLayerMatrix4x4& aCurrentTransform,
const LayerMetricsWrapper& aContent,
const ScrollbarData& aThumbData,
bool aScrollbarIsDescendant,
AsyncTransformComponentMatrix* aOutClipTransform);
+ CSSRect GetCurrentAsyncLayoutViewport(const LayerMetricsWrapper& aLayer);
ParentLayerPoint GetCurrentAsyncScrollOffset(const LayerMetricsWrapper& aLayer);
AsyncTransform GetCurrentAsyncTransform(const LayerMetricsWrapper& aLayer);
AsyncTransformComponentMatrix GetOverscrollTransform(const LayerMetricsWrapper& aLayer);
AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(const LayerMetricsWrapper& aLayer);
- CSSRect GetCurrentAsyncViewport(const LayerMetricsWrapper& aLayer);
void MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer);
bool HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer);
/**
* This can be used to assert that the current thread is the
* sampler thread (which samples the async transform).
* This does nothing if thread assertions are disabled.
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -145,16 +145,26 @@ APZSampler::ComputeTransformForScrollThu
aContent.GetTransform(),
aContent.GetApzc(),
aContent.Metrics(),
aThumbData,
aScrollbarIsDescendant,
aOutClipTransform);
}
+CSSRect
+APZSampler::GetCurrentAsyncLayoutViewport(const LayerMetricsWrapper& aLayer)
+{
+ MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+ AssertOnSamplerThread();
+
+ MOZ_ASSERT(aLayer.GetApzc());
+ return aLayer.GetApzc()->GetCurrentAsyncLayoutViewport(AsyncPanZoomController::eForCompositing);
+}
+
ParentLayerPoint
APZSampler::GetCurrentAsyncScrollOffset(const LayerMetricsWrapper& aLayer)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AssertOnSamplerThread();
MOZ_ASSERT(aLayer.GetApzc());
return aLayer.GetApzc()->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForCompositing);
@@ -185,26 +195,16 @@ APZSampler::GetCurrentAsyncTransformWith
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AssertOnSamplerThread();
MOZ_ASSERT(aLayer.GetApzc());
return aLayer.GetApzc()->GetCurrentAsyncTransformWithOverscroll(AsyncPanZoomController::eForCompositing);
}
-CSSRect
-APZSampler::GetCurrentAsyncViewport(const LayerMetricsWrapper& aLayer)
-{
- MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
- AssertOnSamplerThread();
-
- MOZ_ASSERT(aLayer.GetApzc());
- return aLayer.GetApzc()->GetCurrentAsyncViewport(AsyncPanZoomController::eForCompositing);
-}
-
void
APZSampler::MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer)
{
MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
AssertOnSamplerThread();
MOZ_ASSERT(aLayer.GetApzc());
aLayer.GetApzc()->MarkAsyncTransformAppliedToContent();
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3726,16 +3726,28 @@ bool AsyncPanZoomController::AdvanceAnim
APZThreadUtils::RunOnControllerThread(deferredTasks[i].forget());
}
// If any of the deferred tasks starts a new animation, it will request a
// new composite directly, so we can just return requestAnimationFrame here.
return requestAnimationFrame;
}
+CSSRect
+AsyncPanZoomController::GetCurrentAsyncLayoutViewport(AsyncTransformConsumer aMode) const {
+ RecursiveMutexAutoLock lock(mRecursiveMutex);
+ if (!mFrameMetrics.IsRootContent()) {
+ return CSSRect();
+ }
+ if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
+ return mLastContentPaintMetrics.GetViewport();
+ }
+ return GetEffectiveLayoutViewport(aMode);
+}
+
ParentLayerPoint
AsyncPanZoomController::GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode) const
{
RecursiveMutexAutoLock lock(mRecursiveMutex);
if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
return mLastContentPaintMetrics.GetScrollOffset() * mLastContentPaintMetrics.GetZoom();
}
@@ -3797,16 +3809,25 @@ AsyncPanZoomController::GetCurrentAsyncT
LayerToParentLayerScale compositedAsyncZoom =
(effectiveZoom / mFrameMetrics.LayersPixelsPerCSSPixel()).ToScaleFactor();
return AsyncTransform(
LayerToParentLayerScale(compositedAsyncZoom.scale * mTestAsyncZoom.scale),
-translation);
}
+CSSRect
+AsyncPanZoomController::GetEffectiveLayoutViewport(AsyncTransformConsumer aMode) const
+{
+ if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
+ return mCompositedLayoutViewport;
+ }
+ return mFrameMetrics.GetViewport();
+}
+
CSSPoint
AsyncPanZoomController::GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const
{
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
return mCompositedScrollOffset;
}
return mFrameMetrics.GetScrollOffset();
}
@@ -3815,31 +3836,23 @@ CSSToParentLayerScale2D
AsyncPanZoomController::GetEffectiveZoom(AsyncTransformConsumer aMode) const
{
if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
return mCompositedZoom;
}
return mFrameMetrics.GetZoom();
}
-CSSRect
-AsyncPanZoomController::GetCurrentAsyncViewport(AsyncTransformConsumer aMode) const {
- RecursiveMutexAutoLock lock(mRecursiveMutex);
- if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
- return mLastContentPaintMetrics.GetViewport();
- }
- return mFrameMetrics.GetViewport();
-}
-
bool
AsyncPanZoomController::SampleCompositedAsyncTransform()
{
RecursiveMutexAutoLock lock(mRecursiveMutex);
if (mCompositedScrollOffset != mFrameMetrics.GetScrollOffset() ||
mCompositedZoom != mFrameMetrics.GetZoom()) {
+ mCompositedLayoutViewport = mFrameMetrics.GetViewport();
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
mCompositedZoom = mFrameMetrics.GetZoom();
return true;
}
return false;
}
AsyncTransformComponentMatrix
@@ -4088,16 +4101,17 @@ void AsyncPanZoomController::NotifyLayer
// Initialize our internal state to something sane when the content
// that was just painted is something we knew nothing about previously
CancelAnimation();
mScrollMetadata = aScrollMetadata;
mExpectedGeckoMetrics = aLayerMetrics;
ShareCompositorFrameMetrics();
+ mCompositedLayoutViewport = mFrameMetrics.GetViewport();
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
// scrollable rect may have changed since then, making the margins
// wrong, so we need to calculate a new display port.
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -903,18 +903,20 @@ private:
FrameMetrics& mLastContentPaintMetrics; // for convenience, refers to mLastContentPaintMetadata.mMetrics
// The last metrics used for a content repaint request.
FrameMetrics mLastPaintRequestMetrics;
// The metrics that we expect content to have. This is updated when we
// request a content repaint, and when we receive a shadow layers update.
// 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.
+ // These variables cache the layout viewport, scroll offset, and zoom stored
+ // in |mFrameMetrics| the last time SampleCompositedAsyncTransform() was
+ // called.
+ CSSRect mCompositedLayoutViewport;
CSSPoint mCompositedScrollOffset;
CSSToParentLayerScale2D mCompositedZoom;
AxisX mX;
AxisY mY;
// This flag is set to true when we are in a axis-locked pan as a result of
// the touch-action CSS property.
@@ -987,16 +989,22 @@ public:
* regardless of mForceDisableApz.
*/
enum AsyncTransformConsumer {
eForHitTesting,
eForCompositing,
};
/**
+ * Get the current layout viewport of the scrollable frame corresponding to
+ * this APZC.
+ */
+ CSSRect GetCurrentAsyncLayoutViewport(AsyncTransformConsumer aMode) const;
+
+ /**
* Get the current scroll offset of the scrollable frame corresponding
* to this APZC, including the effects of any asynchronous panning and
* zooming, in ParentLayer pixels.
*/
ParentLayerPoint GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode) const;
/**
* Get the current scroll offset of the scrollable frame corresponding
@@ -1020,43 +1028,38 @@ public:
AsyncTransform GetCurrentAsyncTransform(AsyncTransformConsumer aMode) const;
/**
* Returns the same transform as GetCurrentAsyncTransform(), but includes
* any transform due to axis over-scroll.
*/
AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(AsyncTransformConsumer aMode) const;
- /**
- * Get the current viewport of the scrollable frame corresponding to this
- * APZC.
- */
- CSSRect GetCurrentAsyncViewport(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|.
*
* Returns true if the newly sampled value is different from the previously
* sampled value.
*
* (This is only relevant when |gfxPrefs::APZFrameDelayEnabled() == true|.
* Otherwise, GetCurrentAsyncTransform() always reflects what's stored in
* |mFrameMetrics| immediately, without any delay.)
*/
bool 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.
+ * Helper functions to query the async layout viewport, scroll offset, and
+ * zoom either directly from |mFrameMetrics|, or from cached variables that
+ * store the required value from the last time it was sampled by calling
+ * SampleCompositedAsyncTransform(), depending on who is asking.
*/
+ CSSRect GetEffectiveLayoutViewport(AsyncTransformConsumer aMode) const;
CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const;
CSSToParentLayerScale2D GetEffectiveZoom(AsyncTransformConsumer aMode) const;
/* ===================================================================
* The functions and members in this section are used to manage
* the state that tracks what this APZC is doing with the input events.
*/
protected:
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -301,37 +301,40 @@ RenderMinimap(ContainerT* aContainer,
LayerMetricsWrapper wrapper(aLayer, 0);
if (!wrapper.GetApzc()) {
return;
}
const FrameMetrics& fm = wrapper.Metrics();
MOZ_ASSERT(fm.IsScrollable());
ParentLayerPoint scrollOffset = aSampler->GetCurrentAsyncScrollOffset(wrapper);
- CSSRect viewport = aSampler->GetCurrentAsyncViewport(wrapper);
+ CSSRect viewport = aSampler->GetCurrentAsyncLayoutViewport(wrapper);
// Options
const int verticalPadding = 10;
const int horizontalPadding = 5;
gfx::Color backgroundColor(0.3f, 0.3f, 0.3f, 0.3f);
gfx::Color tileActiveColor(1, 1, 1, 0.4f);
gfx::Color tileBorderColor(0, 0, 0, 0.1f);
gfx::Color pageBorderColor(0, 0, 0);
gfx::Color criticalDisplayPortColor(1.f, 1.f, 0);
gfx::Color displayPortColor(0, 1.f, 0);
gfx::Color layoutPortColor(1.f, 0, 0);
gfx::Color visualPortColor(0, 0, 1.f, 0.3f);
// Rects
ParentLayerRect compositionBounds = fm.GetCompositionBounds();
LayerRect scrollRect = fm.GetScrollableRect() * fm.LayersPixelsPerCSSPixel();
- LayerRect layoutRect = viewport * fm.LayersPixelsPerCSSPixel();
LayerRect visualRect = ParentLayerRect(scrollOffset, compositionBounds.Size()) / LayerToParentLayerScale(1);
LayerRect dp = (fm.GetDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel();
+ Maybe<LayerRect> layoutRect;
Maybe<LayerRect> cdp;
+ if (!viewport.IsEmpty()) {
+ layoutRect = Some(viewport * fm.LayersPixelsPerCSSPixel());
+ }
if (!fm.GetCriticalDisplayPort().IsEmpty()) {
cdp = Some((fm.GetCriticalDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel());
}
// Don't render trivial minimap. They can show up from textboxes and other tiny frames.
if (visualRect.Width() < 64 && visualRect.Height() < 64) {
return;
}
@@ -372,19 +375,22 @@ RenderMinimap(ContainerT* aContainer,
compositor->SlowDrawRect(r, displayPortColor, clipRect, aContainer->GetEffectiveTransform());
// Render the critical displayport if there is one
if (cdp) {
r = transform.TransformBounds(cdp->ToUnknownRect());
compositor->SlowDrawRect(r, criticalDisplayPortColor, clipRect, aContainer->GetEffectiveTransform());
}
- // Render the layout viewport.
- r = transform.TransformBounds(layoutRect.ToUnknownRect());
- compositor->SlowDrawRect(r, layoutPortColor, clipRect, aContainer->GetEffectiveTransform());
+ // Render the layout viewport if it exists (which is only in the root
+ // content APZC).
+ if (layoutRect) {
+ r = transform.TransformBounds(layoutRect->ToUnknownRect());
+ compositor->SlowDrawRect(r, layoutPortColor, clipRect, aContainer->GetEffectiveTransform());
+ }
// Render the visual viewport.
r = transform.TransformBounds(visualRect.ToUnknownRect());
compositor->SlowDrawRect(r, visualPortColor, clipRect, aContainer->GetEffectiveTransform(), 2);
}
template<class ContainerT> void
RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager,