Bug 1466611 - Render layout viewport on APZ minimap. r?botond
MozReview-Commit-ID: HrTRZpU3rAi
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -76,16 +76,17 @@ 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);
void MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer);
bool HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer);
--- 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);
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3726,16 +3726,27 @@ 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);
+ MOZ_ASSERT(mFrameMetrics.IsRootContent(),
+ "Only the root content APZC has a layout viewport");
+ 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 +3808,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();
}
@@ -3821,16 +3841,17 @@ AsyncPanZoomController::GetEffectiveZoom
}
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
@@ -4079,16 +4100,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.
@@ -4163,16 +4185,17 @@ void AsyncPanZoomController::NotifyLayer
// Send an acknowledgement with the new scroll generation so that any
// repaint requests later in this function go through.
// Because of the scroll generation update, any inflight paint requests are
// going to be ignored by layout, and so mExpectedGeckoMetrics
// becomes incorrect for the purposes of calculating the LD transform. To
// correct this we need to update mExpectedGeckoMetrics to be the
// last thing we know was painted by Gecko.
mFrameMetrics.CopyScrollInfoFrom(aLayerMetrics);
+ mCompositedLayoutViewport = mFrameMetrics.GetViewport();
mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
mExpectedGeckoMetrics = aLayerMetrics;
// Cancel the animation (which might also trigger a repaint request)
// after we update the scroll offset above. Otherwise we can be left
// in a state where things are out of sync.
CancelAnimation();
--- 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
@@ -1036,21 +1044,22 @@ private:
*
* (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
@@ -311,30 +311,36 @@ RenderMinimap(ContainerT* aContainer,
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 viewPortColor(0, 0, 1.f, 0.3f);
+ 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 viewRect = ParentLayerRect(scrollOffset, compositionBounds.Size()) / LayerToParentLayerScale(1);
+ LayerRect visualRect = ParentLayerRect(scrollOffset, compositionBounds.Size()) / LayerToParentLayerScale(1);
LayerRect dp = (fm.GetDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel();
+ Maybe<LayerRect> layoutRect;
Maybe<LayerRect> cdp;
+ if (fm.IsRootContent()) {
+ CSSRect viewport = aSampler->GetCurrentAsyncLayoutViewport(wrapper);
+ 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 (viewRect.Width() < 64 && viewRect.Height() < 64) {
+ if (visualRect.Width() < 64 && visualRect.Height() < 64) {
return;
}
// Compute a scale with an appropriate aspect ratio
// We allocate up to 100px of width and the height of this layer.
float scaleFactor;
float scaleFactorX;
float scaleFactorY;
@@ -369,19 +375,26 @@ 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 viewport.
- r = transform.TransformBounds(viewRect.ToUnknownRect());
- compositor->SlowDrawRect(r, viewPortColor, clipRect, aContainer->GetEffectiveTransform(), 2);
+ // 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,
const RenderTargetIntRect& aClipRect,
const Maybe<gfx::Polygon>& aGeometry)
{
Compositor* compositor = aManager->GetCompositor();