Bug 811950 - Fix async scrolling of position:fixed. r=cjones
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -976,17 +976,17 @@ void AsyncPanZoomController::RequestCont
mWaitingForContentToPaint = true;
// Set the zoom back to what it was for the purpose of logic control.
mFrameMetrics.mZoom = gfxSize(actualZoom, actualZoom);
}
bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ContainerLayer* aLayer,
- gfx3DMatrix* aNewTransform) {
+ ViewTransform* aNewTransform) {
// The eventual return value of this function. The compositor needs to know
// whether or not to advance by a frame as soon as it can. For example, if a
// fling is happening, it has to keep compositing so that the animation is
// smooth. If an animation frame is requested, it is the compositor's
// responsibility to schedule a composite.
bool requestAnimationFrame = false;
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
@@ -1059,28 +1059,17 @@ bool AsyncPanZoomController::SampleConte
scrollOffset = mFrameMetrics.mScrollOffset;
}
nsIntPoint scrollCompensation(
NS_lround((scrollOffset.x / rootScaleX - metricsScrollOffset.x) * localScaleX),
NS_lround((scrollOffset.y / rootScaleY - metricsScrollOffset.y) * localScaleY));
- ViewTransform treeTransform(-scrollCompensation, localScaleX, localScaleY);
- *aNewTransform = gfx3DMatrix(treeTransform) * currentTransform;
-
- // The transform already takes the resolution scale into account. Since we
- // will apply the resolution scale again when computing the effective
- // transform, we must apply the inverse resolution scale here.
- aNewTransform->Scale(1.0f/aLayer->GetPreXScale(),
- 1.0f/aLayer->GetPreYScale(),
- 1);
- aNewTransform->ScalePost(1.0f/aLayer->GetPostXScale(),
- 1.0f/aLayer->GetPostYScale(),
- 1);
+ *aNewTransform = ViewTransform(-scrollCompensation, localScaleX, localScaleY);
mLastSampleTime = aSampleTime;
return requestAnimationFrame;
}
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFrame, bool aIsFirstPaint) {
MonitorAutoLock monitor(mMonitor);
--- a/gfx/layers/ipc/AsyncPanZoomController.h
+++ b/gfx/layers/ipc/AsyncPanZoomController.h
@@ -20,16 +20,17 @@
#include "base/message_loop.h"
namespace mozilla {
namespace layers {
class CompositorParent;
class GestureEventListener;
class ContainerLayer;
+class ViewTransform;
/**
* Controller for all panning and zooming logic. Any time a user input is
* detected and it must be processed in some way to affect what the user sees,
* it goes through here. Listens for any input event from InputData and can
* optionally handle nsGUIEvent-derived touch events, but this must be done on
* the main thread. Note that this class completely cross-platform.
*
@@ -154,17 +155,17 @@ public:
* this internally with |aLayer|'s transform).
*
* Return value indicates whether or not any currently running animation
* should continue. That is, if true, the compositor should schedule another
* composite.
*/
bool SampleContentTransformForFrame(const TimeStamp& aSampleTime,
ContainerLayer* aLayer,
- gfx3DMatrix* aNewTransform);
+ ViewTransform* aTransform);
/**
* A shadow layer update has arrived. |aViewportFrame| is the new FrameMetrics
* for the top-level frame. |aIsFirstPaint| is a flag passed from the shadow
* layers code indicating that the frame metrics being sent with this call are
* the initial metrics and the initial paint of the frame has just happened.
*/
void NotifyLayersUpdated(const FrameMetrics& aViewportFrame, bool aIsFirstPaint);
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -850,23 +850,39 @@ CompositorParent::ApplyAsyncContentTrans
} else {
// Check if a derived implementation provides a default AsyncPanZoomController.
controller = GetDefaultPanZoomController();
}
if (controller) {
ShadowLayer* shadow = aLayer->AsShadowLayer();
- gfx3DMatrix newTransform;
+ ViewTransform treeTransform;
*aWantNextFrame |=
controller->SampleContentTransformForFrame(aCurrentFrame,
container,
- &newTransform);
+ &treeTransform);
- shadow->SetShadowTransform(newTransform);
+ gfx3DMatrix transform(gfx3DMatrix(treeTransform) * aLayer->GetTransform());
+ // The transform already takes the resolution scale into account. Since we
+ // will apply the resolution scale again when computing the effective
+ // transform, we must apply the inverse resolution scale here.
+ transform.Scale(1.0f/container->GetPreXScale(),
+ 1.0f/container->GetPreYScale(),
+ 1);
+ transform.ScalePost(1.0f/aLayer->GetPostXScale(),
+ 1.0f/aLayer->GetPostYScale(),
+ 1);
+ shadow->SetShadowTransform(transform);
+
+ TransformFixedLayers(
+ aLayer,
+ -gfxPoint(treeTransform.mTranslation.x / treeTransform.mXScale,
+ treeTransform.mTranslation.y / treeTransform.mYScale),
+ gfxPoint(treeTransform.mXScale, treeTransform.mYScale));
appliedTransform = true;
}
return appliedTransform;
}
bool