diff --git a/mobile/android/base/gfx/GeckoLayerClient.java b/mobile/android/base/gfx/GeckoLayerClient.java index d4bb4ac76a0..ecda6c07c70 100644 --- a/mobile/android/base/gfx/GeckoLayerClient.java +++ b/mobile/android/base/gfx/GeckoLayerClient.java @@ -173,16 +173,21 @@ public class GeckoLayerClient implements GeckoEventResponder, GeckoAppShell.viewSizeChanged(); } - private void adjustViewport() { - ViewportMetrics viewportMetrics = - new ViewportMetrics(mLayerController.getViewportMetrics()); + void adjustViewport(DisplayPortMetrics displayPort) { + ImmutableViewportMetrics metrics = mLayerController.getViewportMetrics(); - viewportMetrics.setViewport(viewportMetrics.getClampedViewport()); + ViewportMetrics clampedMetrics = new ViewportMetrics(metrics); + clampedMetrics.setViewport(clampedMetrics.getClampedViewport()); - mDisplayPort = DisplayPortCalculator.calculate(mLayerController.getViewportMetrics(), - mLayerController.getPanZoomController().getVelocityVector()); - GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(viewportMetrics, mDisplayPort)); - mGeckoViewport = viewportMetrics; + if (displayPort == null) { + displayPort = DisplayPortCalculator.calculate(metrics, + mLayerController.getPanZoomController().getVelocityVector()); + } + + mDisplayPort = displayPort; + mGeckoViewport = clampedMetrics; + + GeckoAppShell.sendEventToGecko(GeckoEvent.createViewportEvent(clampedMetrics, displayPort)); } /** @@ -281,7 +286,7 @@ public class GeckoLayerClient implements GeckoEventResponder, /* Let Gecko know if the screensize has changed */ sendResizeEventIfNecessary(false); if (mLayerController.getRedrawHint()) - adjustViewport(); + adjustViewport(null); } /* diff --git a/mobile/android/base/gfx/LayerController.java b/mobile/android/base/gfx/LayerController.java index 6e48d52e822..1de6c3fef26 100644 --- a/mobile/android/base/gfx/LayerController.java +++ b/mobile/android/base/gfx/LayerController.java @@ -263,6 +263,18 @@ public class LayerController implements Tabs.OnTabsChangedListener { mView.requestRender(); } + public void setAnimationTarget(ViewportMetrics viewport) { + if (mLayerClient != null) { + // We know what the final viewport of the animation is going to be, so + // immediately request a draw of that area by setting the display port + // accordingly. This way we should have the content pre-rendered by the + // time the animation is done. + ImmutableViewportMetrics metrics = new ImmutableViewportMetrics(viewport); + DisplayPortMetrics displayPort = DisplayPortCalculator.calculate(metrics, null); + mLayerClient.adjustViewport(displayPort); + } + } + /** * Scales the viewport, keeping the given focus point in the same place before and after the * scale operation. You must hold the monitor while calling this. diff --git a/mobile/android/base/ui/PanZoomController.java b/mobile/android/base/ui/PanZoomController.java index 24df6fac753..bf39714c1be 100644 --- a/mobile/android/base/ui/PanZoomController.java +++ b/mobile/android/base/ui/PanZoomController.java @@ -472,7 +472,10 @@ public class PanZoomController } mState = PanZoomState.BOUNCE; - + // set the animation target *after* setting state BOUNCE, so that + // the getRedrawHint() is returning false and we don't clobber the display + // port we set as a result of this animation target call. + mController.setAnimationTarget(metrics); startAnimationTimer(new BounceRunnable(bounceStartMetrics, metrics)); }