author | Chris Lord <chrislord.net@gmail.com> |
Tue, 26 Jun 2012 14:43:18 +0100 | |
changeset 97693 | ddd519d0767ed613df103591e62d5412aee02aa0 |
parent 97692 | 9b952d9249536576a90b41b95bc60ab367607b97 |
child 97694 | de70e79ced32b414eca99e219430c20d73b16500 |
push id | 22993 |
push user | emorley@mozilla.com |
push date | Wed, 27 Jun 2012 10:31:27 +0000 |
treeherder | mozilla-central@1a56f1f011c9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | ajuma |
bugs | 758620 |
milestone | 16.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/layers/ipc/CompositorParent.cpp | file | annotate | diff | comparison | revisions | |
gfx/layers/ipc/CompositorParent.h | file | annotate | diff | comparison | revisions |
--- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -308,37 +308,45 @@ CompositorParent::GetPrimaryScrollableLa static void Translate2D(gfx3DMatrix& aTransform, const gfxPoint& aOffset) { aTransform._41 += aOffset.x; aTransform._42 += aOffset.y; } void -CompositorParent::TranslateFixedLayers(Layer* aLayer, - const gfxPoint& aTranslation) +CompositorParent::TransformFixedLayers(Layer* aLayer, + const gfxPoint& aTranslation, + const gfxPoint& aScaleDiff) { if (aLayer->GetIsFixedPosition() && !aLayer->GetParent()->GetIsFixedPosition()) { + // When a scale has been applied to a layer, it focuses around (0,0). + // The anchor position is used here as a scale focus point (assuming that + // aScaleDiff has already been applied) to re-focus the scale. + const gfxPoint& anchor = aLayer->GetFixedPositionAnchor(); + gfxPoint translation(aTranslation.x - (anchor.x - anchor.x / aScaleDiff.x), + aTranslation.y - (anchor.y - anchor.y / aScaleDiff.y)); + gfx3DMatrix layerTransform = aLayer->GetTransform(); - Translate2D(layerTransform, aTranslation); + Translate2D(layerTransform, translation); ShadowLayer* shadow = aLayer->AsShadowLayer(); shadow->SetShadowTransform(layerTransform); const nsIntRect* clipRect = aLayer->GetClipRect(); if (clipRect) { nsIntRect transformedClipRect(*clipRect); - transformedClipRect.MoveBy(aTranslation.x, aTranslation.y); + transformedClipRect.MoveBy(translation.x, translation.y); shadow->SetShadowClipRect(&transformedClipRect); } } for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { - TranslateFixedLayers(child, aTranslation); + TransformFixedLayers(child, aTranslation, aScaleDiff); } } // Go down shadow layer tree, setting properties to match their non-shadow // counterparts. static void SetShadowProperties(Layer* aLayer) { @@ -406,26 +414,40 @@ CompositorParent::TransformShadowTree() metricsScrollOffset = metrics.mViewportScrollOffset; nsIntPoint scrollCompensation( (mScrollOffset.x / tempScaleDiffX - metricsScrollOffset.x) * mXScale, (mScrollOffset.y / tempScaleDiffY - metricsScrollOffset.y) * mYScale); ViewTransform treeTransform(-scrollCompensation, mXScale, mYScale); shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform); - // Alter the scroll offset so that fixed position layers remain within - // the page area. - float offsetX = mScrollOffset.x / tempScaleDiffX; - float offsetY = mScrollOffset.y / tempScaleDiffY; - offsetX = NS_MAX((float)mContentRect.x, NS_MIN(offsetX, (float)(mContentRect.XMost() - mWidgetSize.width))); - offsetY = NS_MAX((float)mContentRect.y, NS_MIN(offsetY, (float)(mContentRect.YMost() - mWidgetSize.height))); - gfxPoint reverseViewTranslation(offsetX - metricsScrollOffset.x, - offsetY - metricsScrollOffset.y); + // Translate fixed position layers so that they stay in the correct position + // when mScrollOffset and metricsScrollOffset differ. + gfxPoint scaleDiff(tempScaleDiffX, tempScaleDiffY); + gfxPoint offset(clamped(mScrollOffset.x / tempScaleDiffX, mContentRect.x / tempScaleDiffX, + (mContentRect.XMost() - mWidgetSize.width / tempScaleDiffX)) - + metricsScrollOffset.x, + clamped(mScrollOffset.y / tempScaleDiffY, mContentRect.y / tempScaleDiffY, + (mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY)) - + metricsScrollOffset.y); - TranslateFixedLayers(layer, reverseViewTranslation); + // If the contents can fit entirely within the widget area on a particular + // dimenson, we need to translate and scale so that the fixed layers remain + // within the page boundaries. + if (mContentRect.width * tempScaleDiffX < mWidgetSize.width) { + offset.x = -metricsScrollOffset.x; + scaleDiff.x = NS_MIN(1.0f, mWidgetSize.width / (float)mContentRect.width); + } + + if (mContentRect.height * tempScaleDiffY < mWidgetSize.height) { + offset.y = -metricsScrollOffset.y; + scaleDiff.y = NS_MIN(1.0f, mWidgetSize.height / (float)mContentRect.height); + } + + TransformFixedLayers(layer, offset, scaleDiff); } void CompositorParent::SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect) { #ifdef MOZ_WIDGET_ANDROID mozilla::AndroidBridge::Bridge()->SetFirstPaintViewport(aOffset, aZoom, aPageRect, aCssPageRect);
--- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -102,20 +102,25 @@ private: // Platform specific functions /** * Does a breadth-first search to find the first layer in the tree with a * displayport set. */ Layer* GetPrimaryScrollableLayer(); /** - * Recursively applies the given translation to all fixed position layers - * that aren't children of other fixed position layers. + * Recursively applies the given translation to all top-level fixed position + * layers that are descendants of the given layer. + * aScaleDiff is considered to be the scale transformation applied when + * displaying the layers, and is used to make sure the anchor points of + * fixed position layers remain in the same position. */ - void TranslateFixedLayers(Layer* aLayer, const gfxPoint& aTranslation); + void TransformFixedLayers(Layer* aLayer, + const gfxPoint& aTranslation, + const gfxPoint& aScaleDiff); nsRefPtr<LayerManager> mLayerManager; nsIWidget* mWidget; CancelableTask *mCurrentCompositeTask; TimeStamp mLastCompose; #ifdef COMPOSITOR_PERFORMANCE_WARNING TimeStamp mExpectedComposeTime; #endif