Bug 1306107 - Stop calling ProjectTo2D() for leaf basic layers. r=mattwoodrow
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -599,35 +599,41 @@ Layer::SnapTransformTranslation(const Ma
*aResidualTransform = Matrix();
}
if (!mManager->IsSnappingEffectiveTransforms()) {
return aTransform;
}
Matrix matrix2D;
- Matrix4x4 result;
if (aTransform.CanDraw2D(&matrix2D) &&
!matrix2D.HasNonTranslation() &&
matrix2D.HasNonIntegerTranslation()) {
auto snappedTranslation = IntPoint::Round(matrix2D.GetTranslation());
Matrix snappedMatrix = Matrix::Translation(snappedTranslation.x,
snappedTranslation.y);
- result = Matrix4x4::From2D(snappedMatrix);
+ Matrix4x4 result = Matrix4x4::From2D(snappedMatrix);
if (aResidualTransform) {
// set aResidualTransform so that aResidual * snappedMatrix == matrix2D.
// (I.e., appying snappedMatrix after aResidualTransform gives the
// ideal transform.)
*aResidualTransform =
Matrix::Translation(matrix2D._31 - snappedTranslation.x,
matrix2D._32 - snappedTranslation.y);
}
return result;
}
+ return SnapTransformTranslation3D(aTransform, aResidualTransform);
+}
+
+Matrix4x4
+Layer::SnapTransformTranslation3D(const Matrix4x4& aTransform,
+ Matrix* aResidualTransform)
+{
if(aTransform.IsSingular() ||
aTransform.HasPerspectiveComponent() ||
aTransform.HasNonTranslation() ||
!aTransform.HasNonIntegerTranslation()) {
// For a singular transform, there is no reversed matrix, so we
// don't snap it.
// For a perspective transform, the content is transformed in
// non-linear, so we don't snap it too.
@@ -667,17 +673,17 @@ Layer::SnapTransformTranslation(const Ma
// The residual transform is to translate the snap to the origin
// of the content buffer.
*aResidualTransform = Matrix::Translation(-snap.x, -snap.y);
}
// Translate transformed origin to transformed snap since the
// residual transform would trnslate the snap to the origin.
Point3D transformedShift = transformedSnap - transformedOrigin;
- result = aTransform;
+ Matrix4x4 result = aTransform;
result.PostTranslate(transformedShift.x,
transformedShift.y,
transformedShift.z);
// For non-2d transform, residual translation could be more than
// 0.5 pixels for every axis.
return result;
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1816,16 +1816,18 @@ protected:
* layer's content can be rendered unpredictably (jiggling) as the scale
* interacts with the snapping of the translation, especially with animated
* transforms.
* @param aResidualTransform a transform to apply before the result transform
* in order to get the results to completely match aTransform.
*/
gfx::Matrix4x4 SnapTransformTranslation(const gfx::Matrix4x4& aTransform,
gfx::Matrix* aResidualTransform);
+ gfx::Matrix4x4 SnapTransformTranslation3D(const gfx::Matrix4x4& aTransform,
+ gfx::Matrix* aResidualTransform);
/**
* See comment for SnapTransformTranslation.
* This function implements type 2 snapping. If aTransform is a translation
* and/or scale, transform aSnapRect by aTransform, snap to pixel boundaries,
* and return the transform that maps aSnapRect to that rect. Otherwise
* just return aTransform.
* @param aSnapRect a rectangle whose edges should be snapped to pixel
* boundaries in the destination surface.
--- a/gfx/layers/basic/BasicContainerLayer.cpp
+++ b/gfx/layers/basic/BasicContainerLayer.cpp
@@ -32,28 +32,33 @@ BasicContainerLayer::~BasicContainerLaye
void
BasicContainerLayer::ComputeEffectiveTransforms(const Matrix4x4& aTransformToSurface)
{
// We push groups for container layers if we need to, which always
// are aligned in device space, so it doesn't really matter how we snap
// containers.
Matrix residual;
- Matrix4x4 idealTransform = GetLocalTransform() * aTransformToSurface;
- if (!Extend3DContext() && !Is3DContextLeaf()) {
- // For 3D transform leaked from extended parent layer.
+ Matrix4x4 transformToSurface = aTransformToSurface;
+ bool participate3DCtx = Extend3DContext() || Is3DContextLeaf();
+ if (!participate3DCtx &&
+ GetContentFlags() & CONTENT_BACKFACE_HIDDEN) {
+ // For backface-hidden layers
+ transformToSurface.ProjectTo2D();
+ }
+ Matrix4x4 idealTransform = GetLocalTransform() * transformToSurface;
+ if (!participate3DCtx &&
+ !(GetContentFlags() & CONTENT_BACKFACE_HIDDEN)) {
+ // For non-backface-hidden layers,
+ // 3D components are required to handle CONTENT_BACKFACE_HIDDEN.
idealTransform.ProjectTo2D();
}
if (!idealTransform.CanDraw2D()) {
- if (!Extend3DContext() ||
- (!idealTransform.Is2D() && Creates3DContextWithExtendingChildren())) {
- if (!Creates3DContextWithExtendingChildren()) {
- idealTransform.ProjectTo2D();
- }
+ if (!Extend3DContext()) {
mEffectiveTransform = idealTransform;
ComputeEffectiveTransformsForChildren(Matrix4x4());
ComputeEffectiveTransformForMaskLayers(Matrix4x4());
mUseIntermediateSurface = true;
return;
}
mEffectiveTransform = idealTransform;
@@ -79,22 +84,22 @@ BasicContainerLayer::ComputeEffectiveTra
* Having a blend mode also always forces our own push group
*/
mUseIntermediateSurface =
GetMaskLayer() ||
GetForceIsolatedGroup() ||
(GetMixBlendMode() != CompositionOp::OP_OVER && HasMultipleChildren()) ||
(GetEffectiveOpacity() != 1.0 && ((HasMultipleChildren() && !Extend3DContext()) || hasSingleBlendingChild));
- if (!Extend3DContext()) {
- idealTransform.ProjectTo2D();
- }
mEffectiveTransform =
!mUseIntermediateSurface ?
- idealTransform : SnapTransformTranslation(idealTransform, &residual);
+ idealTransform :
+ (!(GetContentFlags() & CONTENT_BACKFACE_HIDDEN) ?
+ SnapTransformTranslation(idealTransform, &residual) :
+ SnapTransformTranslation3D(idealTransform, &residual));
Matrix4x4 childTransformToSurface =
(!mUseIntermediateSurface ||
(mUseIntermediateSurface && !Extend3DContext() /* 2D */)) ?
idealTransform : Matrix4x4::From2D(residual);
ComputeEffectiveTransformsForChildren(childTransformToSurface);
ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
}