Bug 1076241 - Get rid of the nontransient async transform. r=kats

This commit is contained in:
Botond Ballo 2014-12-19 18:53:05 -05:00
Родитель 9f93609fd6
Коммит 755b86ca3a
9 изменённых файлов: 57 добавлений и 87 удалений

Просмотреть файл

@ -435,7 +435,7 @@ TabChildBase::HandlePossibleViewportChange(const ScreenIntSize& aOldScreenSize)
// This is the root layer, so the cumulative resolution is the same
// as the resolution.
metrics.mPresShellResolution = metrics.GetCumulativeResolution().scale;
utils->SetResolution(metrics.mPresShellResolution, metrics.mPresShellResolution);
utils->SetResolutionAndScaleTo(metrics.mPresShellResolution, metrics.mPresShellResolution);
CSSSize scrollPort = metrics.CalculateCompositedSizeInCssPixels();
utils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height);

Просмотреть файл

@ -2639,19 +2639,10 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() const {
}
}
LayerToParentLayerScale scale(mFrameMetrics.mPresShellResolution // non-transient portion
* mFrameMetrics.GetAsyncZoom().scale); // transient portion
ParentLayerPoint translation = (currentScrollOffset - lastPaintScrollOffset)
* mFrameMetrics.GetZoom();
return ViewTransform(scale, -translation);
}
Matrix4x4 AsyncPanZoomController::GetNontransientAsyncTransform() const {
ReentrantMonitorAutoEnter lock(mMonitor);
return Matrix4x4::Scaling(mLastContentPaintMetrics.mPresShellResolution,
mLastContentPaintMetrics.mPresShellResolution,
1.0f);
return ViewTransform(mFrameMetrics.GetAsyncZoom(), -translation);
}
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
@ -2660,16 +2651,7 @@ Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
LayerPoint scrollChange =
(mLastContentPaintMetrics.GetScrollOffset() - mLastDispatchedPaintMetrics.GetScrollOffset())
* mLastContentPaintMetrics.GetDevPixelsPerCSSPixel()
* mLastContentPaintMetrics.GetCumulativeResolution()
// This transform ("LD" in the terminology of the comment above
// GetScreenToApzcTransform() in APZCTreeManager.h) is applied in a
// coordinate space that includes the APZC's CSS transform ("LC").
// This CSS transform is the identity unless this APZC sets a pres-shell
// resolution, in which case the transform has a post-scale that cancels
// out the pres-shell resolution. We simulate applying the "LC" transform
// by dividing by the pres-shell resolution. This will go away once
// bug 1076192 is fixed.
/ mLastContentPaintMetrics.mPresShellResolution;
* mLastContentPaintMetrics.GetCumulativeResolution();
float zoomChange = mLastContentPaintMetrics.GetZoom().scale / mLastDispatchedPaintMetrics.GetZoom().scale;

Просмотреть файл

@ -217,13 +217,6 @@ public:
*/
ViewTransform GetCurrentAsyncTransform() const;
/**
* Returns the part of the async transform that will remain once Gecko does a
* repaint at the desired metrics. That is, in the steady state:
* Matrix4x4(GetCurrentAsyncTransform()) === GetNontransientAsyncTransform()
*/
Matrix4x4 GetNontransientAsyncTransform() const;
/**
* Returns the transform to take something from the coordinate space of the
* last thing we know gecko painted, to the coordinate space of the last thing

Просмотреть файл

@ -145,7 +145,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils,
// last paint.
float presShellResolution = aMetrics.mPresShellResolution
* aMetrics.GetAsyncZoom().scale;
aUtils->SetResolution(presShellResolution, presShellResolution);
aUtils->SetResolutionAndScaleTo(presShellResolution, presShellResolution);
// Finally, we set the displayport.
nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor(aMetrics.GetScrollId());

Просмотреть файл

@ -72,8 +72,8 @@ GetTransformToAncestorsParentLayer(Layer* aStart, const LayerMetricsWrapper& aAn
ancestorParent ? iter != ancestorParent : iter.IsValid();
iter = iter.GetParent()) {
transform = transform * iter.GetTransform();
// If the layer has a non-transient async transform then we need to apply it here
// because it will get applied by the APZ in the compositor as well
// If the layer has a pres shell resolution, the compositor will apply
// a scale to scale to this transform. Apply it here too.
const FrameMetrics& metrics = iter.Metrics();
transform.PostScale(metrics.mPresShellResolution, metrics.mPresShellResolution, 1.f);
}

Просмотреть файл

@ -151,11 +151,9 @@ ComputeViewTransform(const FrameMetrics& aContentMetrics, const FrameMetrics& aC
// but with aContentMetrics used in place of mLastContentPaintMetrics, because they
// should be equivalent, modulo race conditions while transactions are inflight.
LayerToParentLayerScale scale(aCompositorMetrics.mPresShellResolution
* aCompositorMetrics.GetAsyncZoom().scale);
ParentLayerPoint translation = (aCompositorMetrics.GetScrollOffset() - aContentMetrics.GetScrollOffset())
* aCompositorMetrics.GetZoom();
return ViewTransform(scale, -translation);
return ViewTransform(aCompositorMetrics.GetAsyncZoom(), -translation);
}
bool
@ -1318,8 +1316,7 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
* (which was generated in GetTransformToAncestorsParentLayer), and
* modifies it with the ViewTransform from the compositor side so that
* it reflects what the compositor is actually rendering. This operation
* basically replaces the nontransient async transform that was injected
* in GetTransformToAncestorsParentLayer with the complete async transform.
* basically adds in the layer's async transform.
* This function then returns the scroll ancestor's composition bounds,
* transformed into the painted layer's LayerPixel coordinates, accounting
* for the compositor state.
@ -1329,22 +1326,8 @@ GetCompositorSideCompositionBounds(const LayerMetricsWrapper& aScrollAncestor,
const Matrix4x4& aTransformToCompBounds,
const ViewTransform& aAPZTransform)
{
Matrix4x4 nonTransientAPZUntransform = Matrix4x4::Scaling(
aScrollAncestor.Metrics().mPresShellResolution,
aScrollAncestor.Metrics().mPresShellResolution,
1.f);
nonTransientAPZUntransform.Invert();
// Take off the last "term" of aTransformToCompBounds, which
// is the APZ's nontransient async transform. Replace it with
// the APZ's async transform (this includes the nontransient
// component as well).
Matrix4x4 transform = aTransformToCompBounds
* nonTransientAPZUntransform
* Matrix4x4(aAPZTransform);
transform.Invert();
return TransformTo<LayerPixel>(transform,
Matrix4x4 transform = aTransformToCompBounds * Matrix4x4(aAPZTransform);
return TransformTo<LayerPixel>(transform.Inverse(),
aScrollAncestor.Metrics().mCompositionBounds);
}

Просмотреть файл

@ -695,17 +695,15 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar,
AsyncPanZoomController* apzc = aContent.GetApzc();
Matrix4x4 asyncTransform = apzc->GetCurrentAsyncTransform();
Matrix4x4 nontransientTransform = apzc->GetNontransientAsyncTransform();
Matrix4x4 transientTransform = nontransientTransform.Inverse() * asyncTransform;
// |transientTransform| represents the amount by which we have scrolled and
// |asyncTransform| represents the amount by which we have scrolled and
// zoomed since the last paint. Because the scrollbar was sized and positioned based
// on the painted content, we need to adjust it based on transientTransform so that
// on the painted content, we need to adjust it based on asyncTransform so that
// it reflects what the user is actually seeing now.
// - The scroll thumb needs to be scaled in the direction of scrolling by the inverse
// of the transientTransform scale (representing the zoom). This is because zooming
// of the asyncTransform scale (representing the zoom). This is because zooming
// in decreases the fraction of the whole scrollable rect that is in view.
// - It needs to be translated in opposite direction of the transientTransform
// - It needs to be translated in opposite direction of the asyncTransform
// translation (representing the scroll). This is because scrolling down, which
// translates the layer content up, should result in moving the scroll thumb down.
// The amount of the translation to the scroll thumb should be such that the ratio
@ -719,41 +717,57 @@ ApplyAsyncTransformToScrollbarForContent(Layer* aScrollbar,
// scrollbar gets painted at the same resolution as the content. Since the
// coordinate space we apply this transform in includes the resolution, we
// need to adjust for it as well here. Note that in another
// aScrollbarIsDescendant hunk below we unapply the entire async
// transform, which includes the nontransientasync transform and would
// normally account for the resolution.
// aScrollbarIsDescendant hunk below we apply a resolution-cancelling
// transform which ensures the scroll thumb isn't actually rendered
// at a larger scale.
scale *= metrics.mPresShellResolution;
}
scrollbarTransform.PostScale(1.f, 1.f / transientTransform._22, 1.f);
scrollbarTransform.PostTranslate(0, -transientTransform._42 * scale, 0);
scrollbarTransform.PostScale(1.f, 1.f / asyncTransform._22, 1.f);
scrollbarTransform.PostTranslate(0, -asyncTransform._42 * scale, 0);
}
if (aScrollbar->GetScrollbarDirection() == Layer::HORIZONTAL) {
float scale = metrics.CalculateCompositedSizeInCssPixels().width / metrics.GetScrollableRect().width;
if (aScrollbarIsDescendant) {
scale *= metrics.mPresShellResolution;
}
scrollbarTransform.PostScale(1.f / transientTransform._11, 1.f, 1.f);
scrollbarTransform.PostTranslate(-transientTransform._41 * scale, 0, 0);
scrollbarTransform.PostScale(1.f / asyncTransform._11, 1.f, 1.f);
scrollbarTransform.PostTranslate(-asyncTransform._41 * scale, 0, 0);
}
Matrix4x4 transform = scrollbarTransform * aScrollbar->GetTransform();
if (aScrollbarIsDescendant) {
// If the scrollbar layer is a child of the content it is a scrollbar for, then we
// need to do an extra untransform to cancel out the async transform on
// the content. This is needed because layout positions and sizes the
// scrollbar on the assumption that there is no async transform, and without
// this code the scrollbar will end up in the wrong place.
// If the scrollbar layer is a child of the content it is a scrollbar for,
// then we need to make a couple of adjustments to the scrollbar's transform.
//
// Since the async transform is applied on top of the content's regular
// transform, we need to make sure to unapply the async transform in the
// same coordinate space. This requires applying the content transform and
// then unapplying it after unapplying the async transform.
// - First, the content's resolution applies to the scrollbar as well.
// Since we don't actually want the scroll thumb's size to vary with
// the zoom (other than its length reflecting the fraction of the
// scrollable length that's in view, which is taken care of above),
// we apply a transform to cancel out this resolution.
//
// - Second, if there is any async transform (including an overscroll
// transform) on the content, this needs to be cancelled out because
// layout positions and sizes the scrollbar on the assumption that there
// is no async transform, and without this adjustment the scrollbar will
// end up in the wrong place.
//
// Note that since the async transform is applied on top of the content's
// regular transform, we need to make sure to unapply the async transform
// in the same coordinate space. This requires applying the content
// transform and then unapplying it after unapplying the async transform.
Matrix4x4 resolutionCancellingTransform =
Matrix4x4::Scaling(metrics.mPresShellResolution,
metrics.mPresShellResolution,
1.0f).Inverse();
Matrix4x4 asyncUntransform = (asyncTransform * apzc->GetOverscrollTransform()).Inverse();
Matrix4x4 contentTransform = aContent.GetTransform();
Matrix4x4 contentUntransform = contentTransform.Inverse();
Matrix4x4 compensation = contentTransform * asyncUntransform * contentUntransform;
Matrix4x4 compensation = resolutionCancellingTransform
* contentTransform
* asyncUntransform
* contentUntransform;
transform = transform * compensation;
// We also need to make a corresponding change on the clip rect of all the
@ -894,10 +908,8 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer)
}
LayerToParentLayerScale asyncZoom = userZoom / metrics.LayersPixelsPerCSSPixel();
LayerToParentLayerScale scale(metrics.mPresShellResolution
* asyncZoom.scale);
ParentLayerPoint translation = userScroll - geckoScroll;
Matrix4x4 treeTransform = ViewTransform(scale, -translation);
Matrix4x4 treeTransform = ViewTransform(asyncZoom, -translation);
SetShadowTransform(aLayer, oldTransform * treeTransform);
NS_ASSERTION(!aLayer->AsLayerComposite()->GetShadowTransformSetByAnimation(),

Просмотреть файл

@ -841,39 +841,39 @@ TEST_F(APZCBasicTester, ComplexTransform) {
apzc->SetFrameMetrics(metrics);
apzc->NotifyLayersUpdated(metrics, true);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
childApzc->SetFrameMetrics(childMetrics);
childApzc->NotifyLayersUpdated(childMetrics, true);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint()), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(60, 60), pointOut);
// do an async scroll by 5 pixels and check the transform
metrics.ScrollBy(CSSPoint(5, 0));
apzc->SetFrameMetrics(metrics);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
childMetrics.ScrollBy(CSSPoint(5, 0));
childApzc->SetFrameMetrics(childMetrics);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(2), ParentLayerPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1), ParentLayerPoint(-30, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(90, 60), pointOut);
// do an async zoom of 1.5x and check the transform
metrics.ZoomBy(1.5f);
apzc->SetFrameMetrics(metrics);
apzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(3), ParentLayerPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
childMetrics.ZoomBy(1.5f);
childApzc->SetFrameMetrics(childMetrics);
childApzc->SampleContentTransformForFrame(testStartTime, &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(3), ParentLayerPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ViewTransform(LayerToParentLayerScale(1.5), ParentLayerPoint(-45, 0)), viewTransformOut);
EXPECT_EQ(ParentLayerPoint(135, 90), pointOut);
}

Просмотреть файл

@ -3634,7 +3634,7 @@ Tab.prototype = {
if (BrowserApp.selectedTab == this) {
if (resolution != this._drawZoom) {
this._drawZoom = resolution;
cwu.setResolution(resolution / window.devicePixelRatio, resolution / window.devicePixelRatio);
cwu.setResolutionAndScaleTo(resolution / window.devicePixelRatio, resolution / window.devicePixelRatio);
}
} else if (!fuzzyEquals(resolution, zoom)) {
dump("Warning: setDisplayPort resolution did not match zoom for background tab! (" + resolution + " != " + zoom + ")");
@ -3758,7 +3758,7 @@ Tab.prototype = {
if (BrowserApp.selectedTab == this) {
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this._drawZoom = aZoom;
cwu.setResolution(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
cwu.setResolutionAndScaleTo(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
}
}
},
@ -4523,7 +4523,7 @@ Tab.prototype = {
saveSessionZoom: function(aZoom) {
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
cwu.setResolution(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
cwu.setResolutionAndScaleTo(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
},
restoredSessionZoom: function() {