mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-07 23:43:37 +00:00
Backout 55d5f3cd5c85, d89ae7f40549 & 270391fca858 (bug 663776) for assertions
This commit is contained in:
parent
af7472b3b6
commit
2f3183fde3
@ -44,7 +44,7 @@ void ImageLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurfa
|
||||
// transform, then we'd snap again when compositing the ThebesLayer).
|
||||
mEffectiveTransform =
|
||||
SnapTransform(local, sourceRect, nullptr) *
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nullptr);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -545,70 +545,39 @@ Layer::GetEffectiveVisibleRegion()
|
||||
return GetVisibleRegion();
|
||||
}
|
||||
|
||||
gfx3DMatrix
|
||||
Layer::SnapTransformTranslation(const gfx3DMatrix& aTransform,
|
||||
gfxMatrix* aResidualTransform)
|
||||
{
|
||||
gfxMatrix matrix2D;
|
||||
gfx3DMatrix result;
|
||||
if (mManager->IsSnappingEffectiveTransforms() &&
|
||||
aTransform.Is2D(&matrix2D) &&
|
||||
!matrix2D.HasNonTranslation() &&
|
||||
matrix2D.HasNonIntegerTranslation()) {
|
||||
gfxPoint snappedTranslation(matrix2D.GetTranslation());
|
||||
snappedTranslation.Round();
|
||||
gfxMatrix snappedMatrix = gfxMatrix().Translate(snappedTranslation);
|
||||
result = gfx3DMatrix::From2D(snappedMatrix);
|
||||
if (aResidualTransform) {
|
||||
// set aResidualTransform so that aResidual * snappedMatrix == matrix2D.
|
||||
// (I.e., appying snappedMatrix after aResidualTransform gives the
|
||||
// ideal transform.)
|
||||
*aResidualTransform =
|
||||
gfxMatrix().Translate(matrix2D.GetTranslation() - snappedTranslation);
|
||||
}
|
||||
} else {
|
||||
result = aTransform;
|
||||
if (aResidualTransform) {
|
||||
*aResidualTransform = gfxMatrix();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
ComputeMatrixForSnappedRect(const gfxMatrix& aMatrix,
|
||||
const gfxRect& aSnapRect,
|
||||
gfxMatrix* aResult)
|
||||
{
|
||||
if (!aMatrix.PreservesAxisAlignedRectangles())
|
||||
return false;
|
||||
|
||||
gfxPoint transformedTopLeft = aMatrix.Transform(aSnapRect.TopLeft());
|
||||
transformedTopLeft.Round();
|
||||
gfxPoint transformedTopRight = aMatrix.Transform(aSnapRect.TopRight());
|
||||
transformedTopRight.Round();
|
||||
gfxPoint transformedBottomRight = aMatrix.Transform(aSnapRect.BottomRight());
|
||||
transformedBottomRight.Round();
|
||||
|
||||
*aResult = gfxUtils::TransformRectToRect(aSnapRect, transformedTopLeft,
|
||||
transformedTopRight, transformedBottomRight);
|
||||
return true;
|
||||
}
|
||||
|
||||
gfx3DMatrix
|
||||
Layer::SnapTransform(const gfx3DMatrix& aTransform,
|
||||
const gfxRect& aSnapRect,
|
||||
gfxMatrix* aResidualTransform)
|
||||
{
|
||||
if (aResidualTransform) {
|
||||
*aResidualTransform = gfxMatrix();
|
||||
}
|
||||
|
||||
gfxMatrix matrix2D;
|
||||
gfx3DMatrix result;
|
||||
gfxPoint snappedTopLeft;
|
||||
gfxPoint snappedTopRight;
|
||||
gfxPoint snappedBottomRight;
|
||||
gfxMatrix snappedMatrix;
|
||||
if (mManager->IsSnappingEffectiveTransforms() &&
|
||||
aTransform.Is2D(&matrix2D) &&
|
||||
ComputeMatrixForSnappedRect(matrix2D, aSnapRect, &snappedMatrix)) {
|
||||
matrix2D.HasNonIntegerTranslation() &&
|
||||
!matrix2D.IsSingular() &&
|
||||
!matrix2D.HasNonAxisAlignedTransform()) {
|
||||
gfxMatrix snappedMatrix;
|
||||
gfxPoint topLeft = matrix2D.Transform(aSnapRect.TopLeft());
|
||||
topLeft.Round();
|
||||
// first compute scale factors that scale aSnapRect to the snapped rect
|
||||
if (aSnapRect.IsEmpty()) {
|
||||
snappedMatrix.xx = matrix2D.xx;
|
||||
snappedMatrix.yy = matrix2D.yy;
|
||||
} else {
|
||||
gfxPoint bottomRight = matrix2D.Transform(aSnapRect.BottomRight());
|
||||
bottomRight.Round();
|
||||
snappedMatrix.xx = (bottomRight.x - topLeft.x)/aSnapRect.Width();
|
||||
snappedMatrix.yy = (bottomRight.y - topLeft.y)/aSnapRect.Height();
|
||||
}
|
||||
// compute translation factors that will move aSnapRect to the snapped rect
|
||||
// given those scale factors
|
||||
snappedMatrix.x0 = topLeft.x - aSnapRect.X()*snappedMatrix.xx;
|
||||
snappedMatrix.y0 = topLeft.y - aSnapRect.Y()*snappedMatrix.yy;
|
||||
result = gfx3DMatrix::From2D(snappedMatrix);
|
||||
if (aResidualTransform && !snappedMatrix.IsSingular()) {
|
||||
// set aResidualTransform so that aResidual * snappedMatrix == matrix2D.
|
||||
@ -620,9 +589,6 @@ Layer::SnapTransform(const gfx3DMatrix& aTransform,
|
||||
}
|
||||
} else {
|
||||
result = aTransform;
|
||||
if (aResidualTransform) {
|
||||
*aResidualTransform = gfxMatrix();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -807,7 +773,7 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const gfx3DMatrix& aTransformT
|
||||
gfxMatrix residual;
|
||||
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
|
||||
idealTransform.ProjectTo2D();
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual);
|
||||
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), &residual);
|
||||
|
||||
bool useIntermediateSurface;
|
||||
if (GetMaskLayer()) {
|
||||
|
@ -1066,42 +1066,15 @@ protected:
|
||||
const float GetLocalOpacity();
|
||||
|
||||
/**
|
||||
* We can snap layer transforms for two reasons:
|
||||
* 1) To avoid unnecessary resampling when a transform is a translation
|
||||
* by a non-integer number of pixels.
|
||||
* Snapping the translation to an integer number of pixels avoids
|
||||
* blurring the layer and can be faster to composite.
|
||||
* 2) When a layer is used to render a rectangular object, we need to
|
||||
* emulate the rendering of rectangular inactive content and snap the
|
||||
* edges of the rectangle to pixel boundaries. This is both to ensure
|
||||
* layer rendering is consistent with inactive content rendering, and to
|
||||
* avoid seams.
|
||||
* This function implements type 1 snapping. If aTransform is a 2D
|
||||
* translation, and this layer's layer manager has enabled snapping
|
||||
* (which is the default), return aTransform with the translation snapped
|
||||
* to nearest pixels. Otherwise just return aTransform. Call this when the
|
||||
* layer does not correspond to a single rectangular content object.
|
||||
* This function does not try to snap if aTransform has a scale, because in
|
||||
* that case resampling is inevitable and there's no point in trying to
|
||||
* avoid it. In fact snapping can cause problems because pixel edges in the
|
||||
* 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.
|
||||
*/
|
||||
gfx3DMatrix SnapTransformTranslation(const gfx3DMatrix& aTransform,
|
||||
gfxMatrix* 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.
|
||||
* Computes a tweaked version of aTransform that snaps a point or a rectangle
|
||||
* to pixel boundaries. Snapping is only performed if this layer's
|
||||
* layer manager has enabled snapping (which is the default).
|
||||
* @param aSnapRect a rectangle whose edges should be snapped to pixel
|
||||
* boundaries in the destination surface.
|
||||
* @param aResidualTransform a transform to apply before the result transform
|
||||
* in order to get the results to completely match aTransform.
|
||||
* boundaries in the destination surface. If the rectangle is empty,
|
||||
* then the snapping process should preserve the scale factors of the
|
||||
* transform matrix
|
||||
* @param aResidualTransform a transform to apply before mEffectiveTransform
|
||||
* in order to get the results to completely match aTransform
|
||||
*/
|
||||
gfx3DMatrix SnapTransform(const gfx3DMatrix& aTransform,
|
||||
const gfxRect& aSnapRect,
|
||||
@ -1182,12 +1155,14 @@ public:
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
// The default implementation just snaps 0,0 to pixels.
|
||||
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
|
||||
gfxMatrix residual;
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform,
|
||||
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0),
|
||||
mAllowResidualTranslation ? &residual : nullptr);
|
||||
// The residual can only be a translation because SnapTransformTranslation
|
||||
// only changes the transform if it's a translation
|
||||
// The residual can only be a translation because ThebesLayer snapping
|
||||
// only aligns a single point with the pixel grid; scale factors are always
|
||||
// preserved exactly
|
||||
NS_ASSERTION(!residual.HasNonTranslation(),
|
||||
"Residual transform can only be a translation");
|
||||
if (!residual.GetTranslation().WithinEpsilonOf(mResidualTranslation, 1e-3f)) {
|
||||
@ -1414,8 +1389,9 @@ public:
|
||||
|
||||
virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
|
||||
{
|
||||
// Snap 0,0 to pixel boundaries, no extra internal transform.
|
||||
gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface;
|
||||
mEffectiveTransform = SnapTransformTranslation(idealTransform, nullptr);
|
||||
mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), nullptr);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
@ -1526,7 +1502,7 @@ public:
|
||||
mEffectiveTransform =
|
||||
SnapTransform(GetLocalTransform(), gfxRect(0, 0, mBounds.width, mBounds.height),
|
||||
nullptr)*
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nullptr);
|
||||
ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
mEffectiveTransform =
|
||||
SnapTransform(GetLocalTransform(), gfxRect(0, 0, mSize.width, mSize.height),
|
||||
nullptr)*
|
||||
SnapTransformTranslation(aTransformToSurface, nullptr);
|
||||
SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,9 +147,9 @@ ContainerComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface,
|
||||
}
|
||||
|
||||
aContainer->mEffectiveTransform =
|
||||
aContainer->SnapTransformTranslation(idealTransform, &residual);
|
||||
aContainer->SnapTransform(idealTransform, gfxRect(0, 0, 0, 0), &residual);
|
||||
// We always pass the ideal matrix down to our children, so there is no
|
||||
// need to apply any compensation using the residual from SnapTransformTranslation.
|
||||
// need to apply any compensation using the residual from SnapTransform.
|
||||
aContainer->ComputeEffectiveTransformsForChildren(idealTransform);
|
||||
|
||||
aContainer->ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
|
||||
|
@ -619,29 +619,6 @@ gfxUtils::PathFromRegionSnapped(gfxContext* aContext, const nsIntRegion& aRegion
|
||||
PathFromRegionInternal(aContext, aRegion, true);
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
gfxUtils::TransformRectToRect(const gfxRect& aFrom, const gfxPoint& aToTopLeft,
|
||||
const gfxPoint& aToTopRight, const gfxPoint& aToBottomRight)
|
||||
{
|
||||
gfxMatrix m;
|
||||
if (aToTopRight.y == aToTopLeft.y && aToTopRight.x == aToBottomRight.x) {
|
||||
// Not a rotation, so xy and yx are zero
|
||||
m.xy = m.yx = 0.0;
|
||||
m.xx = (aToBottomRight.x - aToTopLeft.x)/aFrom.width;
|
||||
m.yy = (aToBottomRight.y - aToTopLeft.y)/aFrom.height;
|
||||
m.x0 = aToTopLeft.x - m.xx*aFrom.x;
|
||||
m.y0 = aToTopLeft.y - m.yy*aFrom.y;
|
||||
} else {
|
||||
NS_ASSERTION(aToTopRight.y == aToBottomRight.y && aToTopRight.x == aToTopLeft.x,
|
||||
"Destination rectangle not axis-aligned");
|
||||
m.xx = m.yy = 0.0;
|
||||
m.xy = (aToBottomRight.x - aToTopLeft.x)/aFrom.height;
|
||||
m.yx = (aToBottomRight.y - aToTopLeft.y)/aFrom.width;
|
||||
m.x0 = aToTopLeft.x - m.xy*aFrom.y;
|
||||
m.y0 = aToTopLeft.y - m.yx*aFrom.x;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut)
|
||||
|
@ -86,16 +86,6 @@ public:
|
||||
*/
|
||||
static int ImageFormatToDepth(gfxASurface::gfxImageFormat aFormat);
|
||||
|
||||
/**
|
||||
* Return the transform matrix that maps aFrom to the rectangle defined by
|
||||
* aToTopLeft/aToTopRight/aToBottomRight. aFrom must be
|
||||
* nonempty and the destination rectangle must be axis-aligned.
|
||||
*/
|
||||
static gfxMatrix TransformRectToRect(const gfxRect& aFrom,
|
||||
const gfxPoint& aToTopLeft,
|
||||
const gfxPoint& aToTopRight,
|
||||
const gfxPoint& aToBottomRight);
|
||||
|
||||
/**
|
||||
* If aIn can be represented exactly using an nsIntRect (i.e.
|
||||
* integer-aligned edges and coordinates in the int32_t range) then we
|
||||
|
@ -2783,11 +2783,10 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
||||
// or it was previously unscaled.
|
||||
bool clamp = true;
|
||||
gfxMatrix oldFrameTransform2d;
|
||||
if (aLayer->GetBaseTransform().Is2D(&oldFrameTransform2d)) {
|
||||
if (aLayer->GetTransform().Is2D(&oldFrameTransform2d)) {
|
||||
gfxSize oldScale = oldFrameTransform2d.ScaleFactors(true);
|
||||
if (oldScale == scale || oldScale == gfxSize(1.0, 1.0)) {
|
||||
if (oldScale == scale || oldScale == gfxSize(1.0, 1.0))
|
||||
clamp = false;
|
||||
}
|
||||
}
|
||||
if (clamp) {
|
||||
scale.width = gfxUtils::ClampToScaleFactor(scale.width);
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "mozilla/Types.h"
|
||||
#include <ctime>
|
||||
#include <cstdlib> // for std::abs(int/long)
|
||||
#include "gfxUtils.h"
|
||||
#include <cmath> // for std::abs(float/double)
|
||||
|
||||
using namespace mozilla;
|
||||
@ -2075,6 +2074,35 @@ FindTileStart(nscoord aDirtyCoord, nscoord aTilePos, nscoord aTileDim)
|
||||
return NSToCoordRound(multiples*aTileDim + aTilePos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the transform matrix that maps aFrom to the rectangle defined by
|
||||
* aToTopLeft/aToTopRight/aToBottomRight. The destination rectangle must be
|
||||
* nonempty and must be axis-aligned.
|
||||
*/
|
||||
static gfxMatrix
|
||||
TransformRectToRect(const gfxRect& aFrom, const gfxPoint& aToTopLeft,
|
||||
const gfxPoint& aToTopRight, const gfxPoint& aToBottomRight)
|
||||
{
|
||||
gfxMatrix m;
|
||||
if (aToTopRight.y == aToTopLeft.y && aToTopRight.x == aToBottomRight.x) {
|
||||
// Not a rotation, so xy and yx are zero
|
||||
m.xy = m.yx = 0.0;
|
||||
m.xx = (aToBottomRight.x - aToTopLeft.x)/aFrom.width;
|
||||
m.yy = (aToBottomRight.y - aToTopLeft.y)/aFrom.height;
|
||||
m.x0 = aToTopLeft.x - m.xx*aFrom.x;
|
||||
m.y0 = aToTopLeft.y - m.yy*aFrom.y;
|
||||
} else {
|
||||
NS_ASSERTION(aToTopRight.y == aToBottomRight.y && aToTopRight.x == aToTopLeft.x,
|
||||
"Destination rectangle not axis-aligned");
|
||||
m.xx = m.yy = 0.0;
|
||||
m.xy = (aToBottomRight.x - aToTopLeft.x)/aFrom.height;
|
||||
m.yx = (aToBottomRight.y - aToTopLeft.y)/aFrom.width;
|
||||
m.x0 = aToTopLeft.x - m.xy*aFrom.y;
|
||||
m.y0 = aToTopLeft.y - m.yx*aFrom.x;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
|
||||
nsRenderingContext& aRenderingContext,
|
||||
@ -2412,7 +2440,7 @@ nsCSSRendering::PaintGradient(nsPresContext* aPresContext,
|
||||
// Set the context's transform to the transform that maps fillRect to
|
||||
// snappedFillRect. The part of the gradient that was going to
|
||||
// exactly fill fillRect will fill snappedFillRect instead.
|
||||
gfxMatrix transform = gfxUtils::TransformRectToRect(fillRect,
|
||||
gfxMatrix transform = TransformRectToRect(fillRect,
|
||||
snappedFillRectTopLeft, snappedFillRectTopRight,
|
||||
snappedFillRectBottomRight);
|
||||
ctx->SetMatrix(transform);
|
||||
|
Loading…
x
Reference in New Issue
Block a user