diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 5ee470177a36..327f0f5d6975 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -166,6 +166,8 @@ void CompositorParent::ResumeCompositionAndResize(int width, int height) { static_cast(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 layerManager = new LayerManagerOGL(mWidget, rect.width, rect.height, true); #else nsRefPtr 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; diff --git a/gfx/layers/ipc/CompositorParent.h b/gfx/layers/ipc/CompositorParent.h index 0e1cccb337de..af972e766ca4 100644 --- a/gfx/layers/ipc/CompositorParent.h +++ b/gfx/layers/ipc/CompositorParent.h @@ -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 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). diff --git a/mobile/android/base/GeckoAppShell.java b/mobile/android/base/GeckoAppShell.java index aa1e536967f8..c7c7892d3894 100644 --- a/mobile/android/base/GeckoAppShell.java +++ b/mobile/android/base/GeckoAppShell.java @@ -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(); }