зеркало из https://github.com/mozilla/gecko-dev.git
Bug 876542 - Restore async fixed layer margin animation. r=roc, kats
Restore the reconciliation between content document fixed position margins at render time and the fixed layer margins as retrieved via SyncViewportInfo during async panning/zooming.
This commit is contained in:
Родитель
867e300fd9
Коммит
7291650c62
|
@ -117,10 +117,96 @@ GetBaseTransform2D(Layer* aLayer, gfxMatrix* aTransform)
|
||||||
aLayer->GetLocalTransform() : aLayer->GetTransform()).Is2D(aTransform);
|
aLayer->GetLocalTransform() : aLayer->GetTransform()).Is2D(aTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
TranslateShadowLayer2D(Layer* aLayer,
|
||||||
|
const gfxPoint& aTranslation)
|
||||||
|
{
|
||||||
|
gfxMatrix layerTransform;
|
||||||
|
if (!GetBaseTransform2D(aLayer, &layerTransform)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the 2D translation to the layer transform.
|
||||||
|
layerTransform.x0 += aTranslation.x;
|
||||||
|
layerTransform.y0 += aTranslation.y;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
gfx3DMatrix layerTransform3D = gfx3DMatrix::From2D(layerTransform);
|
||||||
|
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
|
||||||
|
layerTransform3D.Scale(1.0f/c->GetPreXScale(),
|
||||||
|
1.0f/c->GetPreYScale(),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
layerTransform3D.ScalePost(1.0f/aLayer->GetPostXScale(),
|
||||||
|
1.0f/aLayer->GetPostYScale(),
|
||||||
|
1);
|
||||||
|
|
||||||
|
LayerComposite* layerComposite = aLayer->AsLayerComposite();
|
||||||
|
layerComposite->SetShadowTransform(layerTransform3D);
|
||||||
|
layerComposite->SetShadowTransformSetByAnimation(false);
|
||||||
|
|
||||||
|
const nsIntRect* clipRect = aLayer->GetClipRect();
|
||||||
|
if (clipRect) {
|
||||||
|
nsIntRect transformedClipRect(*clipRect);
|
||||||
|
transformedClipRect.MoveBy(aTranslation.x, aTranslation.y);
|
||||||
|
layerComposite->SetShadowClipRect(&transformedClipRect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AccumulateLayerTransforms2D(Layer* aLayer,
|
||||||
|
Layer* aAncestor,
|
||||||
|
gfxMatrix& aMatrix)
|
||||||
|
{
|
||||||
|
// Accumulate the transforms between this layer and the subtree root layer.
|
||||||
|
for (Layer* l = aLayer; l && l != aAncestor; l = l->GetParent()) {
|
||||||
|
gfxMatrix l2D;
|
||||||
|
if (!GetBaseTransform2D(l, &l2D)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
aMatrix.Multiply(l2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gfxPoint
|
||||||
|
GetLayerFixedMarginsOffset(Layer* aLayer,
|
||||||
|
const gfx::Margin& aFixedLayerMargins)
|
||||||
|
{
|
||||||
|
// Work out the necessary translation, in root scrollable layer space.
|
||||||
|
// Because fixed layer margins are stored relative to the root scrollable
|
||||||
|
// layer, we can just take the difference between these values.
|
||||||
|
gfxPoint translation;
|
||||||
|
const gfxPoint& anchor = aLayer->GetFixedPositionAnchor();
|
||||||
|
const gfx::Margin& fixedMargins = aLayer->GetFixedPositionMargins();
|
||||||
|
|
||||||
|
if (fixedMargins.left >= 0) {
|
||||||
|
if (anchor.x > 0) {
|
||||||
|
translation.x -= aFixedLayerMargins.right - fixedMargins.right;
|
||||||
|
} else {
|
||||||
|
translation.x += aFixedLayerMargins.left - fixedMargins.left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixedMargins.top >= 0) {
|
||||||
|
if (anchor.y > 0) {
|
||||||
|
translation.y -= aFixedLayerMargins.bottom - fixedMargins.bottom;
|
||||||
|
} else {
|
||||||
|
translation.y += aFixedLayerMargins.top - fixedMargins.top;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AsyncCompositionManager::AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
AsyncCompositionManager::AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
||||||
Layer* aTransformedSubtreeRoot,
|
Layer* aTransformedSubtreeRoot,
|
||||||
const gfx3DMatrix& aPreviousTransformForRoot)
|
const gfx3DMatrix& aPreviousTransformForRoot,
|
||||||
|
const gfx::Margin& aFixedLayerMargins)
|
||||||
{
|
{
|
||||||
if (aLayer != aTransformedSubtreeRoot && aLayer->GetIsFixedPosition() &&
|
if (aLayer != aTransformedSubtreeRoot && aLayer->GetIsFixedPosition() &&
|
||||||
!aLayer->GetParent()->GetIsFixedPosition()) {
|
!aLayer->GetParent()->GetIsFixedPosition()) {
|
||||||
|
@ -130,13 +216,9 @@ AsyncCompositionManager::AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
||||||
|
|
||||||
// Accumulate the transforms between this layer and the subtree root layer.
|
// Accumulate the transforms between this layer and the subtree root layer.
|
||||||
gfxMatrix ancestorTransform;
|
gfxMatrix ancestorTransform;
|
||||||
for (Layer* l = aLayer->GetParent(); l != aTransformedSubtreeRoot;
|
if (!AccumulateLayerTransforms2D(aLayer->GetParent(), aTransformedSubtreeRoot,
|
||||||
l = l->GetParent()) {
|
ancestorTransform)) {
|
||||||
gfxMatrix l2D;
|
return;
|
||||||
if (!GetBaseTransform2D(l, &l2D)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ancestorTransform.Multiply(l2D);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxMatrix oldRootTransform;
|
gfxMatrix oldRootTransform;
|
||||||
|
@ -156,6 +238,11 @@ AsyncCompositionManager::AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
||||||
gfxMatrix newCumulativeTransformInverse = newCumulativeTransform;
|
gfxMatrix newCumulativeTransformInverse = newCumulativeTransform;
|
||||||
newCumulativeTransformInverse.Invert();
|
newCumulativeTransformInverse.Invert();
|
||||||
|
|
||||||
|
// Calculate any offset necessary, in previous transform sub-tree root
|
||||||
|
// space. This is used to make sure fixed position content respects
|
||||||
|
// content document fixed position margins.
|
||||||
|
gfxPoint offsetInOldSpace = GetLayerFixedMarginsOffset(aLayer, aFixedLayerMargins);
|
||||||
|
|
||||||
// Now work out the translation necessary to make sure the layer doesn't
|
// Now work out the translation necessary to make sure the layer doesn't
|
||||||
// move given the new sub-tree root transform.
|
// move given the new sub-tree root transform.
|
||||||
// Transforming the locallyTransformedAnchor by oldCumulativeTransform
|
// Transforming the locallyTransformedAnchor by oldCumulativeTransform
|
||||||
|
@ -169,40 +256,18 @@ AsyncCompositionManager::AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
||||||
if (!GetBaseTransform2D(aLayer, &layerTransform)) {
|
if (!GetBaseTransform2D(aLayer, &layerTransform)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gfxPoint locallyTransformedAnchor =
|
|
||||||
layerTransform.Transform(aLayer->GetFixedPositionAnchor());
|
const gfxPoint& anchor = aLayer->GetFixedPositionAnchor();
|
||||||
|
gfxPoint locallyTransformedAnchor = layerTransform.Transform(anchor);
|
||||||
|
gfxPoint locallyTransformedOffsetAnchor = layerTransform.Transform(anchor + offsetInOldSpace);
|
||||||
|
|
||||||
gfxPoint oldAnchorPositionInNewSpace =
|
gfxPoint oldAnchorPositionInNewSpace =
|
||||||
newCumulativeTransformInverse.Transform(
|
newCumulativeTransformInverse.Transform(
|
||||||
oldCumulativeTransform.Transform(locallyTransformedAnchor));
|
oldCumulativeTransform.Transform(locallyTransformedOffsetAnchor));
|
||||||
gfxPoint translation = oldAnchorPositionInNewSpace - locallyTransformedAnchor;
|
gfxPoint translation = oldAnchorPositionInNewSpace - locallyTransformedAnchor;
|
||||||
|
|
||||||
// Finally, apply the 2D translation to the layer transform.
|
// Finally, apply the 2D translation to the layer transform.
|
||||||
layerTransform.x0 += translation.x;
|
TranslateShadowLayer2D(aLayer, translation);
|
||||||
layerTransform.y0 += translation.y;
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
gfx3DMatrix layerTransform3D = gfx3DMatrix::From2D(layerTransform);
|
|
||||||
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
|
|
||||||
layerTransform3D.Scale(1.0f/c->GetPreXScale(),
|
|
||||||
1.0f/c->GetPreYScale(),
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
layerTransform3D.ScalePost(1.0f/aLayer->GetPostXScale(),
|
|
||||||
1.0f/aLayer->GetPostYScale(),
|
|
||||||
1);
|
|
||||||
|
|
||||||
LayerComposite* layerComposite = aLayer->AsLayerComposite();
|
|
||||||
layerComposite->SetShadowTransform(layerTransform3D);
|
|
||||||
layerComposite->SetShadowTransformSetByAnimation(false);
|
|
||||||
|
|
||||||
const nsIntRect* clipRect = aLayer->GetClipRect();
|
|
||||||
if (clipRect) {
|
|
||||||
nsIntRect transformedClipRect(*clipRect);
|
|
||||||
transformedClipRect.MoveBy(translation.x, translation.y);
|
|
||||||
layerComposite->SetShadowClipRect(&transformedClipRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The transform has now been applied, so there's no need to iterate over
|
// The transform has now been applied, so there's no need to iterate over
|
||||||
// child layers.
|
// child layers.
|
||||||
|
@ -211,7 +276,8 @@ AsyncCompositionManager::AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
||||||
|
|
||||||
for (Layer* child = aLayer->GetFirstChild();
|
for (Layer* child = aLayer->GetFirstChild();
|
||||||
child; child = child->GetNextSibling()) {
|
child; child = child->GetNextSibling()) {
|
||||||
AlignFixedLayersForAnchorPoint(child, aTransformedSubtreeRoot, aPreviousTransformForRoot);
|
AlignFixedLayersForAnchorPoint(child, aTransformedSubtreeRoot,
|
||||||
|
aPreviousTransformForRoot, aFixedLayerMargins);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +482,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||||
#endif
|
#endif
|
||||||
oldTransform.Scale(resolution.scale, resolution.scale, 1);
|
oldTransform.Scale(resolution.scale, resolution.scale, 1);
|
||||||
|
|
||||||
AlignFixedLayersForAnchorPoint(aLayer, aLayer, oldTransform);
|
AlignFixedLayersForAnchorPoint(aLayer, aLayer, oldTransform, fixedLayerMargins);
|
||||||
|
|
||||||
appliedTransform = true;
|
appliedTransform = true;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +583,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer, const LayoutDev
|
||||||
|
|
||||||
// Make sure fixed position layers don't move away from their anchor points
|
// Make sure fixed position layers don't move away from their anchor points
|
||||||
// when we're asynchronously panning or zooming
|
// when we're asynchronously panning or zooming
|
||||||
AlignFixedLayersForAnchorPoint(aLayer, aLayer, oldTransform);
|
AlignFixedLayersForAnchorPoint(aLayer, aLayer, oldTransform, fixedLayerMargins);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -149,10 +149,14 @@ private:
|
||||||
* chosen so that the layer's anchor point relative to aTransformedSubtreeRoot's
|
* chosen so that the layer's anchor point relative to aTransformedSubtreeRoot's
|
||||||
* parent layer is the same as it was when aTransformedSubtreeRoot's
|
* parent layer is the same as it was when aTransformedSubtreeRoot's
|
||||||
* GetLocalTransform() was aPreviousTransformForRoot.
|
* GetLocalTransform() was aPreviousTransformForRoot.
|
||||||
|
* This function will also adjust layers so that the given content document
|
||||||
|
* fixed position margins will be respected during asynchronous panning and
|
||||||
|
* zooming.
|
||||||
*/
|
*/
|
||||||
void AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
void AlignFixedLayersForAnchorPoint(Layer* aLayer,
|
||||||
Layer* aTransformedSubtreeRoot,
|
Layer* aTransformedSubtreeRoot,
|
||||||
const gfx3DMatrix& aPreviousTransformForRoot);
|
const gfx3DMatrix& aPreviousTransformForRoot,
|
||||||
|
const gfx::Margin& aFixedLayerMargins);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DRAWING PHASE ONLY
|
* DRAWING PHASE ONLY
|
||||||
|
|
Загрузка…
Ссылка в новой задаче