Bug 607417 - Reconcile async scrolling for fixed position layers. r=ajuma

Untranslate fixed position layers when doing async scrolling so that they don't
jump about as content re-renders them in the correct place.
This commit is contained in:
Chris Lord 2012-05-23 09:36:39 +01:00
Родитель 6190143055
Коммит 62d6014cc8
3 изменённых файлов: 60 добавлений и 0 удалений

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

@ -153,6 +153,8 @@ CompositorParent::SetEGLSurfaceSize(int width, int height)
void
CompositorParent::ResumeCompositionAndResize(int width, int height)
{
mWidgetSize.width = width;
mWidgetSize.height = height;
SetEGLSurfaceSize(width, height);
ResumeComposition();
}
@ -289,6 +291,38 @@ CompositorParent::GetPrimaryScrollableLayer()
return root;
}
static void
Translate2D(gfx3DMatrix& aTransform, const gfxPoint& aOffset)
{
aTransform._41 += aOffset.x;
aTransform._42 += aOffset.y;
}
void
CompositorParent::TranslateFixedLayers(Layer* aLayer,
const gfxPoint& aTranslation)
{
if (aLayer->GetIsFixedPosition() &&
!aLayer->GetParent()->GetIsFixedPosition()) {
gfx3DMatrix layerTransform = aLayer->GetTransform();
Translate2D(layerTransform, aTranslation);
ShadowLayer* shadow = aLayer->AsShadowLayer();
shadow->SetShadowTransform(layerTransform);
const nsIntRect* clipRect = aLayer->GetClipRect();
if (clipRect) {
nsIntRect transformedClipRect(*clipRect);
transformedClipRect.MoveBy(aTranslation.x, aTranslation.y);
shadow->SetShadowClipRect(&transformedClipRect);
}
}
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
TranslateFixedLayers(child, aTranslation);
}
}
// Go down shadow layer tree, setting properties to match their non-shadow
// counterparts.
static void
@ -371,6 +405,15 @@ CompositorParent::TransformShadowTree()
(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.
int offsetX = NS_MAX(0, NS_MIN(mScrollOffset.x, mContentSize.width - mWidgetSize.width));
int offsetY = NS_MAX(0, NS_MIN(mScrollOffset.y, mContentSize.height - mWidgetSize.height));
gfxPoint reverseViewTranslation(offsetX / tempScaleDiffX - metricsScrollOffset.x,
offsetY / tempScaleDiffY - metricsScrollOffset.y);
TranslateFixedLayers(layer, reverseViewTranslation);
} else {
ViewTransform treeTransform(nsIntPoint(0,0), mXScale, mYScale);
shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
@ -429,6 +472,13 @@ CompositorParent::ShadowLayersUpdated(bool isFirstPaint)
PLayersParent*
CompositorParent::AllocPLayers(const LayersBackend& aBackendType, int* aMaxTextureSize)
{
// mWidget doesn't belong to the compositor thread, so it should be set to
// NULL before returning from this method, to avoid accessing it elsewhere.
nsIntRect rect;
mWidget->GetBounds(rect);
mWidgetSize.width = rect.width;
mWidgetSize.height = rect.height;
if (aBackendType == LayerManager::LAYERS_OPENGL) {
nsRefPtr<LayerManagerOGL> layerManager;
layerManager =

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

@ -107,6 +107,12 @@ private:
*/
Layer* GetPrimaryScrollableLayer();
/**
* Recursively applies the given translation to all fixed position layers
* that aren't children of other fixed position layers.
*/
void TranslateFixedLayers(Layer* aLayer, const gfxPoint& aTranslation);
nsRefPtr<LayerManager> mLayerManager;
nsIWidget* mWidget;
CancelableTask *mCurrentCompositeTask;
@ -120,6 +126,7 @@ private:
float mYScale;
nsIntPoint mScrollOffset;
nsIntSize mContentSize;
nsIntSize mWidgetSize;
// When this flag is set, the next composition will be the first for a
// particular document (i.e. the document displayed on the screen will change).

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

@ -380,6 +380,9 @@ public class GeckoAppShell
f = Environment.getDownloadCacheDirectory();
GeckoAppShell.putenv("EXTERNAL_STORAGE=" + f.getPath());
// Enable fixed position layers
GeckoAppShell.putenv("MOZ_ENABLE_FIXED_POSITION_LAYERS=1");
putLocaleEnv();
}