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-04 17:04:15 +12:00
parent 9367097525
commit 675c02dfe0
3 changed files with 56 additions and 1 deletions

View File

@ -166,6 +166,8 @@ void
CompositorParent::ResumeCompositionAndResize(int width, int height)
{
static_cast<LayerManagerOGL*>(mLayerManager.get())->SetSurfaceSize(width, height);
mWidgetSize.width = width;
mWidgetSize.height = height;
ResumeComposition();
}
@ -292,6 +294,33 @@ CompositorParent::GetPrimaryScrollableLayer()
return root;
}
static void
ReverseViewTranslation(gfx3DMatrix& aTransform,
const ViewTransform& aViewTransform)
{
aTransform._41 -= aViewTransform.mTranslation.x / aViewTransform.mXScale;
aTransform._42 -= aViewTransform.mTranslation.y / aViewTransform.mYScale;
}
void
CompositorParent::UntranslateFixedLayers(Layer* aLayer,
const ViewTransform& aTransform)
{
if (aLayer->GetIsFixedPosition() &&
!aLayer->GetParent()->GetIsFixedPosition()) {
gfx3DMatrix layerTransform = aLayer->GetTransform();
ReverseViewTranslation(layerTransform, aTransform);
ShadowLayer* shadow = aLayer->AsShadowLayer();
shadow->SetShadowTransform(layerTransform);
}
for (Layer* child = aLayer->GetFirstChild();
child; child = child->GetNextSibling()) {
UntranslateFixedLayers(child, aTransform);
}
}
// Go down shadow layer tree, setting properties to match their non-shadow
// counterparts.
static void
@ -374,6 +403,17 @@ 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));
treeTransform.mTranslation.x =
-(offsetX / tempScaleDiffX - metricsScrollOffset.x) * mXScale;
treeTransform.mTranslation.y =
-(offsetY / tempScaleDiffY - metricsScrollOffset.y) * mYScale;
UntranslateFixedLayers(layer, treeTransform);
} else {
ViewTransform treeTransform(nsIntPoint(0,0), mXScale, mYScale);
shadow->SetShadowTransform(gfx3DMatrix(treeTransform) * currentTransform);
@ -433,14 +473,18 @@ PLayersParent*
CompositorParent::AllocPLayers(const LayersBackend &backendType)
{
if (backendType == LayerManager::LAYERS_OPENGL) {
#ifdef MOZ_JAVA_COMPOSITOR
nsIntRect rect;
mWidget->GetBounds(rect);
mWidgetSize.width = rect.width;
mWidgetSize.height = rect.height;
#ifdef MOZ_JAVA_COMPOSITOR
nsRefPtr<LayerManagerOGL> layerManager =
new LayerManagerOGL(mWidget, rect.width, rect.height, true);
#else
nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(mWidget);
#endif
// mWidget doesn't belong to the compositor thread, so set it to NULL here
// to avoid accessing it.
mWidget = NULL;
mLayerManager = layerManager;

View File

@ -137,6 +137,13 @@ private:
*/
Layer* GetPrimaryScrollableLayer();
/**
* Recursively reverses the translation portion of the given ViewTransform on
* all fixed position layers that aren't children of other fixed position
* layers.
*/
void UntranslateFixedLayers(Layer* aLayer, const ViewTransform& aTransform);
nsRefPtr<LayerManager> mLayerManager;
nsIWidget* mWidget;
CancelableTask *mCurrentCompositeTask;
@ -150,6 +157,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).

View File

@ -411,6 +411,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();
}