mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 912806 - Store both cumulative and non-cumulative resolutions in FrameMetrics and use whichever is appropriate. r=kats
This commit is contained in:
parent
b4d4493dfd
commit
5fa50f4b24
@ -427,8 +427,11 @@ TabChild::Observe(nsISupports *aSubject,
|
||||
mLastMetrics.mZoom = mLastMetrics.CalculateIntrinsicScale();
|
||||
// We use ScreenToLayerScale(1) below in order to turn the
|
||||
// async zoom amount into the gecko zoom amount.
|
||||
mLastMetrics.mResolution =
|
||||
mLastMetrics.mCumulativeResolution =
|
||||
mLastMetrics.mZoom / mLastMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
|
||||
// This is the root layer, so the cumulative resolution is the same
|
||||
// as the resolution.
|
||||
mLastMetrics.mResolution = mLastMetrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1);
|
||||
mLastMetrics.mScrollOffset = CSSPoint(0, 0);
|
||||
|
||||
utils->SetResolution(mLastMetrics.mResolution.scale,
|
||||
@ -692,7 +695,10 @@ TabChild::HandlePossibleViewportChange()
|
||||
// new CSS viewport, so we know that there's no velocity, acceleration, and
|
||||
// we have no idea how long painting will take.
|
||||
metrics, gfx::Point(0.0f, 0.0f), gfx::Point(0.0f, 0.0f), 0.0);
|
||||
metrics.mResolution = metrics.mZoom / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
|
||||
metrics.mCumulativeResolution = metrics.mZoom / 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);
|
||||
utils->SetResolution(metrics.mResolution.scale, metrics.mResolution.scale);
|
||||
|
||||
// Force a repaint with these metrics. This, among other things, sets the
|
||||
@ -1616,8 +1622,10 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
|
||||
}
|
||||
|
||||
// set the resolution
|
||||
LayoutDeviceToLayerScale resolution = aFrameMetrics.mZoom
|
||||
/ aFrameMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
|
||||
ParentLayerToLayerScale resolution = aFrameMetrics.mZoom
|
||||
/ aFrameMetrics.mDevPixelsPerCSSPixel
|
||||
/ aFrameMetrics.GetParentResolution()
|
||||
* ScreenToLayerScale(1);
|
||||
utils->SetResolution(resolution.scale, resolution.scale);
|
||||
|
||||
// and set the display port
|
||||
|
@ -576,6 +576,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
WriteParam(aMsg, aParam.mCompositionBounds);
|
||||
WriteParam(aMsg, aParam.mScrollId);
|
||||
WriteParam(aMsg, aParam.mResolution);
|
||||
WriteParam(aMsg, aParam.mCumulativeResolution);
|
||||
WriteParam(aMsg, aParam.mZoom);
|
||||
WriteParam(aMsg, aParam.mDevPixelsPerCSSPixel);
|
||||
WriteParam(aMsg, aParam.mMayHaveTouchListeners);
|
||||
@ -592,6 +593,7 @@ struct ParamTraits<mozilla::layers::FrameMetrics>
|
||||
ReadParam(aMsg, aIter, &aResult->mCompositionBounds) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mScrollId) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mCumulativeResolution) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mZoom) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mDevPixelsPerCSSPixel) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMayHaveTouchListeners) &&
|
||||
|
@ -15,6 +15,16 @@
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// The layer coordinates of the parent layer. Like the layer coordinates
|
||||
// of the current layer (LayerPixel) but doesn't include the current layer's
|
||||
// resolution.
|
||||
struct ParentLayerPixel {};
|
||||
|
||||
typedef gfx::ScaleFactor<LayoutDevicePixel, ParentLayerPixel> LayoutDeviceToParentLayerScale;
|
||||
typedef gfx::ScaleFactor<ParentLayerPixel, LayerPixel> ParentLayerToLayerScale;
|
||||
|
||||
typedef gfx::ScaleFactor<ParentLayerPixel, ScreenPixel> ParentLayerToScreenScale;
|
||||
|
||||
/**
|
||||
* The viewport and displayport metrics for the painted frame at the
|
||||
* time of a layer-tree transaction. These metrics are especially
|
||||
@ -39,6 +49,7 @@ public:
|
||||
, mScrollId(NULL_SCROLL_ID)
|
||||
, mScrollableRect(0, 0, 0, 0)
|
||||
, mResolution(1)
|
||||
, mCumulativeResolution(1)
|
||||
, mZoom(1)
|
||||
, mDevPixelsPerCSSPixel(1)
|
||||
, mMayHaveTouchListeners(false)
|
||||
@ -57,6 +68,7 @@ public:
|
||||
mScrollId == aOther.mScrollId &&
|
||||
mScrollableRect.IsEqualEdges(aOther.mScrollableRect) &&
|
||||
mResolution == aOther.mResolution &&
|
||||
mCumulativeResolution == aOther.mCumulativeResolution &&
|
||||
mDevPixelsPerCSSPixel == aOther.mDevPixelsPerCSSPixel &&
|
||||
mMayHaveTouchListeners == aOther.mMayHaveTouchListeners &&
|
||||
mPresShellId == aOther.mPresShellId;
|
||||
@ -86,7 +98,7 @@ public:
|
||||
|
||||
CSSToLayerScale LayersPixelsPerCSSPixel() const
|
||||
{
|
||||
return mResolution * mDevPixelsPerCSSPixel;
|
||||
return mCumulativeResolution * mDevPixelsPerCSSPixel;
|
||||
}
|
||||
|
||||
LayerPoint GetScrollOffsetInLayerPixels() const
|
||||
@ -94,6 +106,11 @@ public:
|
||||
return mScrollOffset * LayersPixelsPerCSSPixel();
|
||||
}
|
||||
|
||||
LayoutDeviceToParentLayerScale GetParentResolution() const
|
||||
{
|
||||
return mCumulativeResolution / mResolution;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scale factor needed to fit the viewport
|
||||
* into its composition bounds.
|
||||
@ -211,15 +228,18 @@ public:
|
||||
// The following metrics are dimensionless.
|
||||
//
|
||||
|
||||
// The resolution, along both axes, that the current frame has been painted
|
||||
// at.
|
||||
// The resolution that the current frame has been painted at.
|
||||
//
|
||||
// Every time this frame is composited and the compositor samples its
|
||||
// transform, this metric is used to create a transform which is
|
||||
// post-multiplied into the parent's transform. Since this only happens when
|
||||
// we walk the layer tree, the resulting transform isn't stored here. Thus the
|
||||
// resolution of parent layers is opaque to this metric.
|
||||
LayoutDeviceToLayerScale mResolution;
|
||||
ParentLayerToLayerScale mResolution;
|
||||
|
||||
// The cumulative resolution that the current frame has been painted at.
|
||||
// This is the product of our mResolution and the mResolutions of our parent frames.
|
||||
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
|
||||
|
@ -497,7 +497,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
LayoutDeviceToLayerScale resolution(1.0 / rootTransform.GetXScale(),
|
||||
1.0 / rootTransform.GetYScale());
|
||||
#else
|
||||
LayoutDeviceToLayerScale resolution = metrics.mResolution;
|
||||
LayoutDeviceToLayerScale resolution = metrics.mCumulativeResolution;
|
||||
#endif
|
||||
oldTransform.Scale(resolution.scale, resolution.scale, 1);
|
||||
|
||||
@ -556,7 +556,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
|
||||
// appears to be that metrics.mZoom is poorly initialized in some scenarios. In these scenarios,
|
||||
// however, we can assume there is no async zooming in progress and so the following statement
|
||||
// works fine.
|
||||
CSSToScreenScale userZoom(metrics.mDevPixelsPerCSSPixel.scale * metrics.mResolution.scale);
|
||||
CSSToScreenScale userZoom(metrics.mDevPixelsPerCSSPixel * metrics.mCumulativeResolution * LayerToScreenScale(1));
|
||||
ScreenPoint userScroll = metrics.mScrollOffset * userZoom;
|
||||
SyncViewportInfo(displayPort, geckoZoom, mLayersUpdated,
|
||||
userScroll, userZoom, fixedLayerMargins,
|
||||
@ -580,7 +580,10 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
|
||||
}
|
||||
|
||||
LayerPoint translation = (userScroll / zoomAdjust) - geckoScroll;
|
||||
treeTransform = gfx3DMatrix(ViewTransform(-translation, userZoom / metrics.mDevPixelsPerCSSPixel));
|
||||
treeTransform = gfx3DMatrix(ViewTransform(-translation,
|
||||
userZoom
|
||||
/ metrics.mDevPixelsPerCSSPixel
|
||||
/ metrics.GetParentResolution()));
|
||||
|
||||
// The transform already takes the resolution scale into account. Since we
|
||||
// will apply the resolution scale again when computing the effective
|
||||
@ -680,7 +683,7 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
1.0 / rootTransform.GetYScale());
|
||||
#else
|
||||
LayoutDeviceToLayerScale resolution =
|
||||
scrollableLayers[i]->AsContainerLayer()->GetFrameMetrics().mResolution;
|
||||
scrollableLayers[i]->AsContainerLayer()->GetFrameMetrics().mCumulativeResolution;
|
||||
#endif
|
||||
TransformScrollableLayer(scrollableLayers[i], resolution);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ class AutoResolveRefLayers;
|
||||
// Represents (affine) transforms that are calculated from a content view.
|
||||
struct ViewTransform {
|
||||
ViewTransform(LayerPoint aTranslation = LayerPoint(),
|
||||
LayoutDeviceToScreenScale aScale = LayoutDeviceToScreenScale())
|
||||
ParentLayerToScreenScale aScale = ParentLayerToScreenScale())
|
||||
: mTranslation(aTranslation)
|
||||
, mScale(aScale)
|
||||
{}
|
||||
@ -51,7 +51,7 @@ struct ViewTransform {
|
||||
}
|
||||
|
||||
LayerPoint mTranslation;
|
||||
LayoutDeviceToScreenScale mScale;
|
||||
ParentLayerToScreenScale mScale;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -963,7 +963,7 @@ void AsyncPanZoomController::RequestContentRepaint() {
|
||||
mFrameMetrics.mScrollOffset.x) < EPSILON &&
|
||||
fabsf(mLastPaintRequestMetrics.mScrollOffset.y -
|
||||
mFrameMetrics.mScrollOffset.y) < EPSILON &&
|
||||
mFrameMetrics.mResolution == mLastPaintRequestMetrics.mResolution) {
|
||||
mFrameMetrics.mCumulativeResolution == mLastPaintRequestMetrics.mCumulativeResolution) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1110,8 +1110,11 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() {
|
||||
}
|
||||
LayerPoint translation = (mFrameMetrics.mScrollOffset - lastPaintScrollOffset)
|
||||
* mLastContentPaintMetrics.LayersPixelsPerCSSPixel();
|
||||
|
||||
return ViewTransform(-translation,
|
||||
mFrameMetrics.mZoom / mLastContentPaintMetrics.mDevPixelsPerCSSPixel);
|
||||
mFrameMetrics.mZoom
|
||||
/ mLastContentPaintMetrics.mDevPixelsPerCSSPixel
|
||||
/ mFrameMetrics.GetParentResolution());
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aLayerMetrics, bool aIsFirstPaint) {
|
||||
@ -1347,11 +1350,14 @@ void AsyncPanZoomController::TimeoutTouchListeners() {
|
||||
|
||||
void AsyncPanZoomController::SetZoomAndResolution(const CSSToScreenScale& aZoom) {
|
||||
mMonitor.AssertCurrentThreadIn();
|
||||
LayoutDeviceToParentLayerScale parentResolution = mFrameMetrics.GetParentResolution();
|
||||
mFrameMetrics.mZoom = aZoom;
|
||||
// We use ScreenToLayerScale(1) below in order to ask gecko to render
|
||||
// what's currently visible on the screen. This is effectively turning
|
||||
// the async zoom amount into the gecko zoom amount.
|
||||
mFrameMetrics.mResolution = aZoom / mFrameMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
|
||||
mFrameMetrics.mCumulativeResolution = aZoom / mFrameMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1);
|
||||
// The parent resolution will not have changed.
|
||||
mFrameMetrics.mResolution = mFrameMetrics.mCumulativeResolution / parentResolution;
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::UpdateZoomConstraints(bool aAllowZoom,
|
||||
|
@ -177,7 +177,8 @@ TEST(AsyncPanZoomController, ComplexTransform) {
|
||||
metrics.mViewport = CSSRect(0, 0, 4, 4);
|
||||
metrics.mScrollOffset = CSSPoint(10, 10);
|
||||
metrics.mScrollableRect = CSSRect(0, 0, 50, 50);
|
||||
metrics.mResolution = LayoutDeviceToLayerScale(2);
|
||||
metrics.mCumulativeResolution = LayoutDeviceToLayerScale(2);
|
||||
metrics.mResolution = ParentLayerToLayerScale(2);
|
||||
metrics.mZoom = CSSToScreenScale(6);
|
||||
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(3);
|
||||
metrics.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
|
||||
@ -198,39 +199,39 @@ TEST(AsyncPanZoomController, ComplexTransform) {
|
||||
apzc->SetFrameMetrics(metrics);
|
||||
apzc->NotifyLayersUpdated(metrics, true);
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(), ParentLayerToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
|
||||
|
||||
childApzc->SetFrameMetrics(childMetrics);
|
||||
childApzc->NotifyLayersUpdated(childMetrics, true);
|
||||
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(), ParentLayerToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
|
||||
|
||||
// do an async scroll by 5 pixels and check the transform
|
||||
metrics.mScrollOffset += CSSPoint(5, 0);
|
||||
apzc->SetFrameMetrics(metrics);
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
|
||||
|
||||
childMetrics.mScrollOffset += CSSPoint(5, 0);
|
||||
childApzc->SetFrameMetrics(childMetrics);
|
||||
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(2)), viewTransformOut);
|
||||
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
|
||||
|
||||
// do an async zoom of 1.5x and check the transform
|
||||
metrics.mZoom.scale *= 1.5f;
|
||||
apzc->SetFrameMetrics(metrics);
|
||||
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(3)), viewTransformOut);
|
||||
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
|
||||
|
||||
childMetrics.mZoom.scale *= 1.5f;
|
||||
childApzc->SetFrameMetrics(childMetrics);
|
||||
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
|
||||
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), ParentLayerToScreenScale(3)), viewTransformOut);
|
||||
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
|
||||
}
|
||||
|
||||
|
@ -663,20 +663,31 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
|
||||
nsIPresShell* presShell = presContext->GetPresShell();
|
||||
if (metrics.mScrollId == FrameMetrics::ROOT_SCROLL_ID) {
|
||||
metrics.mResolution = LayoutDeviceToLayerScale(presShell->GetXResolution(),
|
||||
presShell->GetYResolution());
|
||||
metrics.mResolution = ParentLayerToLayerScale(presShell->GetXResolution(),
|
||||
presShell->GetYResolution());
|
||||
} else {
|
||||
// Only the root scrollable frame for a given presShell should pick up
|
||||
// the presShell's resolution. All the other subframes are 1.0.
|
||||
metrics.mResolution = LayoutDeviceToLayerScale(1.0f);
|
||||
metrics.mResolution = ParentLayerToLayerScale(1.0f);
|
||||
}
|
||||
|
||||
metrics.mCumulativeResolution = LayoutDeviceToLayerScale(1.0f);
|
||||
nsIPresShell* curPresShell = presShell;
|
||||
while (curPresShell != nullptr) {
|
||||
ParentLayerToLayerScale presShellResolution(curPresShell->GetXResolution(),
|
||||
curPresShell->GetYResolution());
|
||||
metrics.mCumulativeResolution.scale *= presShellResolution.scale;
|
||||
nsPresContext* parentContext = curPresShell->GetPresContext()->GetParentPresContext();
|
||||
curPresShell = parentContext ? parentContext->GetPresShell() : nullptr;
|
||||
}
|
||||
|
||||
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(
|
||||
(float)nsPresContext::AppUnitsPerCSSPixel() / auPerDevPixel);
|
||||
|
||||
// Initially, AsyncPanZoomController should render the content to the screen
|
||||
// at the painted resolution.
|
||||
const LayerToScreenScale layerToScreenScale(1.0f);
|
||||
metrics.mZoom = metrics.mResolution * metrics.mDevPixelsPerCSSPixel
|
||||
metrics.mZoom = metrics.mCumulativeResolution * metrics.mDevPixelsPerCSSPixel
|
||||
* layerToScreenScale;
|
||||
|
||||
metrics.mMayHaveTouchListeners = aMayHaveTouchListeners;
|
||||
@ -689,7 +700,7 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
nsRect compositionBounds(frameForCompositionBoundsCalculation->GetOffsetToCrossDoc(aReferenceFrame),
|
||||
frameForCompositionBoundsCalculation->GetSize());
|
||||
metrics.mCompositionBounds = RoundedToInt(LayoutDeviceRect::FromAppUnits(compositionBounds, auPerDevPixel)
|
||||
* metrics.mResolution
|
||||
* metrics.mCumulativeResolution
|
||||
* layerToScreenScale);
|
||||
|
||||
// Adjust composition bounds for the size of scroll bars.
|
||||
|
Loading…
Reference in New Issue
Block a user