Bug 980493 - Transition FrameMetrics::mZoom to use a getter/setter. r=kats

This commit is contained in:
Botond Ballo 2014-03-12 12:46:57 -04:00
parent c169aeed9c
commit 81f6add29a
11 changed files with 65 additions and 50 deletions

View File

@ -321,12 +321,12 @@ TabChild::InitializeRootMetrics()
mLastRootMetrics.mCompositionBounds = ParentLayerIntRect(
ParentLayerIntPoint(),
ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot));
mLastRootMetrics.mZoom = mLastRootMetrics.CalculateIntrinsicScale();
mLastRootMetrics.SetZoom(mLastRootMetrics.CalculateIntrinsicScale());
mLastRootMetrics.mDevPixelsPerCSSPixel = mWidget->GetDefaultScale();
// We use ScreenToLayerScale(1) below in order to turn the
// async zoom amount into the gecko zoom amount.
mLastRootMetrics.mCumulativeResolution =
mLastRootMetrics.mZoom / mLastRootMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
mLastRootMetrics.GetZoom() / mLastRootMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
mLastRootMetrics.mResolution = mLastRootMetrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1);
@ -609,7 +609,7 @@ TabChild::HandlePossibleViewportChange()
// within the screen width. Note that "actual content" may be different with
// respect to CSS pixels because of the CSS viewport size changing.
float oldIntrinsicScale = oldScreenWidth / oldBrowserWidth;
metrics.mZoom.scale *= metrics.CalculateIntrinsicScale().scale / oldIntrinsicScale;
metrics.ZoomBy(metrics.CalculateIntrinsicScale().scale / oldIntrinsicScale);
// Changing the zoom when we're not doing a first paint will get ignored
// by AsyncPanZoomController and causes a blurry flash.
@ -626,12 +626,12 @@ TabChild::HandlePossibleViewportChange()
CSSToScreenScale defaultZoom = viewportInfo.GetDefaultZoom();
MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom &&
defaultZoom <= viewportInfo.GetMaxZoom());
metrics.mZoom = defaultZoom;
metrics.SetZoom(defaultZoom);
metrics.mScrollId = viewId;
}
metrics.mCumulativeResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
metrics.mCumulativeResolution = metrics.GetZoom() / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
metrics.mResolution = metrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1);

View File

@ -75,7 +75,6 @@ public:
, mScrollableRect(0, 0, 0, 0)
, mResolution(1)
, mCumulativeResolution(1)
, mZoom(1)
, mTransformScale(1)
, mDevPixelsPerCSSPixel(1)
, mPresShellId(-1)
@ -83,6 +82,7 @@ public:
, mIsRoot(false)
, mHasScrollgrab(false)
, mScrollOffset(0, 0)
, mZoom(1)
, mUpdateScrollOffset(false)
, mScrollGeneration(0)
{}
@ -199,6 +199,11 @@ public:
mScrollOffset += aPoint;
}
void ZoomBy(float aFactor)
{
mZoom.scale *= aFactor;
}
// ---------------------------------------------------------------------------
// The following metrics are all in widget space/device pixels.
//
@ -293,12 +298,6 @@ public:
// This information is provided by Gecko at layout/paint time.
LayoutDeviceToLayerScale mCumulativeResolution;
// The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
// but will be drawn to the screen at mZoom. In the steady state, the
// two will be the same, but during an async zoom action the two may
// diverge. This information is initialized in Gecko but updated in the APZC.
CSSToScreenScale mZoom;
// The conversion factor between local screen pixels (the coordinate
// system in which APZCs receive input events) and our parent layer's
// layer pixels (the coordinate system of mCompositionBounds).
@ -338,6 +337,16 @@ public:
return mScrollOffset;
}
void SetZoom(const CSSToScreenScale& aZoom)
{
mZoom = aZoom;
}
CSSToScreenScale GetZoom() const
{
return mZoom;
}
void SetScrollOffsetUpdated(uint32_t aScrollGeneration)
{
mUpdateScrollOffset = true;
@ -385,6 +394,12 @@ private:
// not any parents, regardless of parent transforms.
CSSPoint mScrollOffset;
// The "user zoom". Content is painted by gecko at mResolution * mDevPixelsPerCSSPixel,
// but will be drawn to the screen at mZoom. In the steady state, the
// two will be the same, but during an async zoom action the two may
// diverge. This information is initialized in Gecko but updated in the APZC.
CSSToScreenScale mZoom;
// Whether mScrollOffset was updated by something other than the APZ code, and
// if the APZC receiving this metrics should update its local copy.
bool mUpdateScrollOffset;

View File

@ -120,7 +120,7 @@ ClientTiledThebesLayer::BeginPaint()
// Calculate the frame resolution. Because this is Gecko-side, before any
// async transforms have occurred, we can use mZoom for this.
mPaintData.mResolution = metrics.mZoom;
mPaintData.mResolution = metrics.GetZoom();
// Calculate the scroll offset since the last transaction, and the
// composition bounds.
@ -129,7 +129,7 @@ ClientTiledThebesLayer::BeginPaint()
Layer* primaryScrollable = ClientManager()->GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
mPaintData.mScrollOffset = metrics.GetScrollOffset() * metrics.mZoom;
mPaintData.mScrollOffset = metrics.GetScrollOffset() * metrics.GetZoom();
mPaintData.mCompositionBounds =
ApplyParentLayerToLayoutTransform(mPaintData.mTransformParentLayerToLayout,
ParentLayerRect(metrics.mCompositionBounds));

View File

@ -332,7 +332,7 @@ SimpleClientTiledThebesLayer::BeginPaint()
// Calculate the frame resolution. Because this is Gecko-side, before any
// async transforms have occurred, we can use mZoom for this.
mPaintData.mResolution = metrics.mZoom;
mPaintData.mResolution = metrics.GetZoom();
// Calculate the scroll offset since the last transaction, and the
// composition bounds.
@ -341,7 +341,7 @@ SimpleClientTiledThebesLayer::BeginPaint()
Layer* primaryScrollable = ClientManager()->GetPrimaryScrollableLayer();
if (primaryScrollable) {
const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
mPaintData.mScrollOffset = metrics.GetScrollOffset() * metrics.mZoom;
mPaintData.mScrollOffset = metrics.GetScrollOffset() * metrics.GetZoom();
mPaintData.mCompositionBounds =
ApplyParentLayerToLayoutTransform(mPaintData.mTransformParentLayerToLayout,
ParentLayerRect(metrics.mCompositionBounds));

View File

@ -178,7 +178,7 @@ SharedFrameMetricsHelper::UpdateFromCompositorFrameMetrics(
// Always abort updates if the resolution has changed. There's no use
// in drawing at the incorrect resolution.
if (!FuzzyEquals(compositorMetrics.mZoom.scale, contentMetrics.mZoom.scale)) {
if (!FuzzyEquals(compositorMetrics.GetZoom().scale, contentMetrics.GetZoom().scale)) {
return true;
}

View File

@ -183,7 +183,7 @@ ThebesLayerComposite::GetEffectiveResolution()
for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
const FrameMetrics& metrics = parent->GetFrameMetrics();
if (metrics.mScrollId != FrameMetrics::NULL_SCROLL_ID) {
return metrics.mZoom;
return metrics.GetZoom();
}
}

View File

@ -1154,7 +1154,7 @@ void AsyncPanZoomController::AttemptScroll(const ScreenPoint& aStartPoint,
{
ReentrantMonitorAutoEnter lock(mMonitor);
CSSToScreenScale zoom = mFrameMetrics.mZoom;
CSSToScreenScale zoom = mFrameMetrics.GetZoom();
// Inversely scale the offset by the resolution (when you're zoomed further in,
// the same swipe should move you a shorter distance).
@ -1284,7 +1284,7 @@ bool FlingAnimation::Sample(FrameMetrics& aFrameMetrics,
// Inversely scale the offset by the resolution (when you're zoomed further in,
// the same swipe should move you a shorter distance).
CSSPoint cssOffset = offset / aFrameMetrics.mZoom;
CSSPoint cssOffset = offset / aFrameMetrics.GetZoom();
CSSPoint overscroll;
aFrameMetrics.ScrollBy(CSSPoint(
mApzc.mX.AdjustDisplacement(cssOffset.x, overscroll.x),
@ -1356,7 +1356,7 @@ void AsyncPanZoomController::ScrollBy(const CSSPoint& aOffset) {
void AsyncPanZoomController::ScaleWithFocus(float aScale,
const CSSPoint& aFocus) {
mFrameMetrics.mZoom.scale *= aScale;
mFrameMetrics.ZoomBy(aScale);
// We want to adjust the scroll offset such that the CSS point represented by aFocus remains
// at the same position on the screen before and after the change in zoom. The below code
// accomplishes this; see https://bugzilla.mozilla.org/show_bug.cgi?id=923431#c6 for an
@ -1414,7 +1414,7 @@ const CSSRect AsyncPanZoomController::CalculatePendingDisplayPort(
double aEstimatedPaintDuration)
{
CSSRect compositionBounds(aFrameMetrics.CalculateCompositedRectInCssPixels());
CSSPoint velocity = aVelocity / aFrameMetrics.mZoom;
CSSPoint velocity = aVelocity / aFrameMetrics.GetZoom();
CSSPoint scrollOffset = aFrameMetrics.GetScrollOffset();
CSSRect scrollableRect = aFrameMetrics.GetExpandedScrollableRect();
@ -1484,7 +1484,7 @@ void AsyncPanZoomController::RequestContentRepaint(FrameMetrics& aFrameMetrics)
aFrameMetrics.GetScrollOffset().x) < EPSILON &&
fabsf(mLastPaintRequestMetrics.GetScrollOffset().y -
aFrameMetrics.GetScrollOffset().y) < EPSILON &&
aFrameMetrics.mZoom == mLastPaintRequestMetrics.mZoom &&
aFrameMetrics.GetZoom() == mLastPaintRequestMetrics.GetZoom() &&
fabsf(aFrameMetrics.mViewport.width - mLastPaintRequestMetrics.mViewport.width) < EPSILON &&
fabsf(aFrameMetrics.mViewport.height - mLastPaintRequestMetrics.mViewport.height) < EPSILON) {
return;
@ -1532,7 +1532,7 @@ bool ZoomAnimation::Sample(FrameMetrics& aFrameMetrics,
double animPosition = mDuration / ZOOM_TO_DURATION;
if (animPosition >= 1.0) {
aFrameMetrics.mZoom = mEndZoom;
aFrameMetrics.SetZoom(mEndZoom);
aFrameMetrics.SetScrollOffset(mEndOffset);
return false;
}
@ -1543,9 +1543,9 @@ bool ZoomAnimation::Sample(FrameMetrics& aFrameMetrics,
// We scale the scrollOffset linearly with sampledPosition, so the zoom
// needs to scale inversely to match.
aFrameMetrics.mZoom = CSSToScreenScale(1 /
aFrameMetrics.SetZoom(CSSToScreenScale(1 /
(sampledPosition / mEndZoom.scale +
(1 - sampledPosition) / mStartZoom.scale));
(1 - sampledPosition) / mStartZoom.scale)));
aFrameMetrics.SetScrollOffset(CSSPoint::FromUnknownPoint(gfx::Point(
mEndOffset.x * sampledPosition + mStartOffset.x * (1 - sampledPosition),
@ -1591,7 +1591,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
requestAnimationFrame = UpdateAnimation(aSampleTime);
aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.mZoom;
aScrollOffset = mFrameMetrics.GetScrollOffset() * mFrameMetrics.GetZoom();
*aNewTransform = GetCurrentAsyncTransform();
LogRendertraceRect(GetGuid(), "viewport", "red",
@ -1670,7 +1670,7 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
return ViewTransform(-translation,
mFrameMetrics.mZoom
mFrameMetrics.GetZoom()
/ mLastContentPaintMetrics.mDevPixelsPerCSSPixel
/ mFrameMetrics.GetParentResolution());
}
@ -1686,7 +1686,7 @@ gfx3DMatrix AsyncPanZoomController::GetTransformToLastDispatchedPaint() {
ReentrantMonitorAutoEnter lock(mMonitor);
LayerPoint scrollChange = (mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
float zoomChange = mLastContentPaintMetrics.mZoom.scale / mLastDispatchedPaintMetrics.mZoom.scale;
float zoomChange = mLastContentPaintMetrics.GetZoom().scale / mLastDispatchedPaintMetrics.GetZoom().scale;
return gfx3DMatrix::Translation(scrollChange.x, scrollChange.y, 0) *
gfx3DMatrix::ScalingMatrix(zoomChange, zoomChange, 1);
}
@ -1740,11 +1740,11 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetri
mFrameMetrics.mDevPixelsPerCSSPixel == aLayerMetrics.mDevPixelsPerCSSPixel) {
float parentResolutionChange = aLayerMetrics.GetParentResolution().scale
/ mFrameMetrics.GetParentResolution().scale;
mFrameMetrics.mZoom.scale *= parentResolutionChange;
mFrameMetrics.ZoomBy(parentResolutionChange);
} else {
// Take the new zoom as either device scale or composition width or both
// got changed (e.g. due to orientation change).
mFrameMetrics.mZoom.scale = aLayerMetrics.mZoom.scale;
mFrameMetrics.SetZoom(aLayerMetrics.GetZoom());
mFrameMetrics.mDevPixelsPerCSSPixel.scale = aLayerMetrics.mDevPixelsPerCSSPixel.scale;
}
mFrameMetrics.mScrollableRect = aLayerMetrics.mScrollableRect;
@ -1851,7 +1851,7 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
targetZoom.scale = clamped(targetZoom.scale, localMinZoom.scale, localMaxZoom.scale);
FrameMetrics endZoomToMetrics = mFrameMetrics;
endZoomToMetrics.mZoom = targetZoom / mFrameMetrics.mTransformScale;
endZoomToMetrics.SetZoom(targetZoom / mFrameMetrics.mTransformScale);
// Adjust the zoomToRect to a sensible position to prevent overscrolling.
CSSRect rectAfterZoom = CSSRect(endZoomToMetrics.CalculateCompositedRectInCssPixels());
@ -1875,9 +1875,9 @@ void AsyncPanZoomController::ZoomToRect(CSSRect aRect) {
StartAnimation(new ZoomAnimation(
mFrameMetrics.GetScrollOffset(),
mFrameMetrics.mZoom,
mFrameMetrics.GetZoom(),
endZoomToMetrics.GetScrollOffset(),
endZoomToMetrics.mZoom));
endZoomToMetrics.GetZoom()));
// Schedule a repaint now, so the new displayport will be painted before the
// animation finishes.

View File

@ -350,7 +350,7 @@ TEST(AsyncPanZoomController, Pinch) {
fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
fm.SetScrollOffset(CSSPoint(300, 300));
fm.mZoom = CSSToScreenScale(2.0);
fm.SetZoom(CSSToScreenScale(2.0));
apzc->SetFrameMetrics(fm);
apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
// the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
@ -362,13 +362,13 @@ TEST(AsyncPanZoomController, Pinch) {
// the visible area of the document in CSS pixels is now x=305 y=310 w=40 h=80
fm = apzc->GetFrameMetrics();
EXPECT_EQ(fm.mZoom.scale, 2.5f);
EXPECT_EQ(fm.GetZoom().scale, 2.5f);
EXPECT_EQ(fm.GetScrollOffset().x, 305);
EXPECT_EQ(fm.GetScrollOffset().y, 310);
// part 2 of the test, move to the top-right corner of the page and pinch and
// make sure we stay in the correct spot
fm.mZoom = CSSToScreenScale(2.0);
fm.SetZoom(CSSToScreenScale(2.0));
fm.SetScrollOffset(CSSPoint(930, 5));
apzc->SetFrameMetrics(fm);
// the visible area of the document in CSS pixels is x=930 y=5 w=50 h=100
@ -377,7 +377,7 @@ TEST(AsyncPanZoomController, Pinch) {
// the visible area of the document in CSS pixels is now x=880 y=0 w=100 h=200
fm = apzc->GetFrameMetrics();
EXPECT_EQ(fm.mZoom.scale, 1.0f);
EXPECT_EQ(fm.GetZoom().scale, 1.0f);
EXPECT_EQ(fm.GetScrollOffset().x, 880);
EXPECT_EQ(fm.GetScrollOffset().y, 0);
@ -393,7 +393,7 @@ TEST(AsyncPanZoomController, PinchWithTouchActionNone) {
fm.mCompositionBounds = ParentLayerIntRect(200, 200, 100, 200);
fm.mScrollableRect = CSSRect(0, 0, 980, 1000);
fm.SetScrollOffset(CSSPoint(300, 300));
fm.mZoom = CSSToScreenScale(2.0);
fm.SetZoom(CSSToScreenScale(2.0));
apzc->SetFrameMetrics(fm);
// the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
@ -413,7 +413,7 @@ TEST(AsyncPanZoomController, PinchWithTouchActionNone) {
// The frame metrics should stay the same since touch-action:none makes
// apzc ignore pinch gestures.
fm = apzc->GetFrameMetrics();
EXPECT_EQ(fm.mZoom.scale, 2.0f);
EXPECT_EQ(fm.GetZoom().scale, 2.0f);
EXPECT_EQ(fm.GetScrollOffset().x, 300);
EXPECT_EQ(fm.GetScrollOffset().y, 300);
}
@ -427,7 +427,7 @@ TEST(AsyncPanZoomController, Overzoom) {
fm.mCompositionBounds = ParentLayerIntRect(0, 0, 100, 100);
fm.mScrollableRect = CSSRect(0, 0, 125, 150);
fm.SetScrollOffset(CSSPoint(10, 0));
fm.mZoom = CSSToScreenScale(1.0);
fm.SetZoom(CSSToScreenScale(1.0));
apzc->SetFrameMetrics(fm);
apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
// the visible area of the document in CSS pixels is x=10 y=0 w=100 h=100
@ -438,7 +438,7 @@ TEST(AsyncPanZoomController, Overzoom) {
ApzcPinch(apzc, 50, 50, 0.5);
fm = apzc->GetFrameMetrics();
EXPECT_EQ(fm.mZoom.scale, 0.8f);
EXPECT_EQ(fm.GetZoom().scale, 0.8f);
// bug 936721 - PGO builds introduce rounding error so
// use a fuzzy match instead
EXPECT_LT(abs(fm.GetScrollOffset().x), 1e-5);
@ -509,7 +509,7 @@ TEST(AsyncPanZoomController, ComplexTransform) {
metrics.mScrollableRect = CSSRect(0, 0, 50, 50);
metrics.mCumulativeResolution = LayoutDeviceToLayerScale(2);
metrics.mResolution = ParentLayerToLayerScale(2);
metrics.mZoom = CSSToScreenScale(6);
metrics.SetZoom(CSSToScreenScale(6));
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(3);
metrics.mScrollId = FrameMetrics::START_SCROLL_ID;
@ -552,13 +552,13 @@ TEST(AsyncPanZoomController, ComplexTransform) {
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
// do an async zoom of 1.5x and check the transform
metrics.mZoom.scale *= 1.5f;
metrics.ZoomBy(1.5f);
apzc->SetFrameMetrics(metrics);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(3)), viewTransformOut);
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
childMetrics.mZoom.scale *= 1.5f;
childMetrics.ZoomBy(1.5f);
childApzc->SetFrameMetrics(childMetrics);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(3)), viewTransformOut);

View File

@ -728,8 +728,8 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
// Initially, AsyncPanZoomController should render the content to the screen
// at the painted resolution.
const LayerToScreenScale layerToScreenScale(1.0f);
metrics.mZoom = metrics.mCumulativeResolution * metrics.mDevPixelsPerCSSPixel
* layerToScreenScale;
metrics.SetZoom(metrics.mCumulativeResolution * metrics.mDevPixelsPerCSSPixel
* layerToScreenScale);
if (presShell) {
nsIDocument* document = nullptr;

View File

@ -1880,7 +1880,7 @@ AndroidBridge::RequestContentRepaint(const mozilla::layers::FrameMetrics& aFrame
{
ALOG_BRIDGE("AndroidBridge::RequestContentRepaint");
CSSToScreenScale resolution = aFrameMetrics.mZoom;
CSSToScreenScale resolution = aFrameMetrics.GetZoom();
ScreenRect dp = (aFrameMetrics.mDisplayPort + aFrameMetrics.GetScrollOffset()) * resolution;
mNativePanZoomController->RequestContentRepaintWrapper(dp.x, dp.y, dp.width, dp.height, resolution.scale);

View File

@ -77,7 +77,7 @@ MaybeAlignAndClampDisplayPort(mozilla::layers::FrameMetrics& aFrameMetrics,
// this FrameMetrics may be incorrect (and is about to be reset by mZoom).
displayPort =
ExpandDisplayPortToTileBoundaries(displayPort + aActualScrollOffset,
aFrameMetrics.mZoom *
aFrameMetrics.GetZoom() *
ScreenToLayerScale(1.0))
- aActualScrollOffset;
}
@ -190,7 +190,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
// take the async zoom calculated by the APZC and tell gecko about it (turning it into
// a "sync" zoom) which will update the resolution at which the layer is painted.
ParentLayerToLayerScale presShellResolution =
aMetrics.mZoom
aMetrics.GetZoom()
/ aMetrics.mDevPixelsPerCSSPixel
/ aMetrics.GetParentResolution()
* ScreenToLayerScale(1.0f);