Bug 608812 - GetTransformForRendering() should have the same rounding behavior r=emilio

The comment in nsDisplayTransform::GetTransformForRendering() clearly
says that |aOutOrigin| should return the same offset as GetTransform().

GetTransform() will pass the offset to GetResultingTransformMatrix()
which will round it in many cases to avoid subpixel blurry rendering.

But GetTransformForRendering() doesn't take this rounding into account,
thus contradicting the intent described by the comment.

This rounding is important to keep subpixel behavior consistent with
or without webrender enabled. Currently, SVG will be rendered blurry
in some cases if it's at a subpixel position. After fixing the problem
in non-webrender case, the strange blur still occurs in webrender case.
It turns out to be caused by this inconsistency.

Differential Revision: https://phabricator.services.mozilla.com/D29495

--HG--
extra : moz-landing-system : lando
This commit is contained in:
violet 2019-05-01 15:20:31 +00:00
parent d6376ab7df
commit 96e3a70dc5
2 changed files with 18 additions and 13 deletions

View File

@ -7773,6 +7773,14 @@ Matrix4x4 nsDisplayTransform::GetResultingTransformMatrix(
aFlags, aBoundsOverride);
}
static bool ShouldRoundTransformOrigin(const nsIFrame* aFrame) {
// An SVG frame should not have its translation rounded.
// Note it's possible that the SVG frame doesn't have an SVG
// transform but only has a CSS transform.
return !aFrame || !aFrame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT) ||
aFrame->IsSVGOuterSVGAnonChildFrame();
}
Matrix4x4 nsDisplayTransform::GetResultingTransformMatrixInternal(
const FrameTransformProperties& aProperties, const nsPoint& aOrigin,
float aAppUnitsPerPixel, uint32_t aFlags, const nsRect* aBoundsOverride) {
@ -7803,15 +7811,7 @@ Matrix4x4 nsDisplayTransform::GetResultingTransformMatrixInternal(
frame &&
frame->IsSVGTransformed(&svgTransform, &parentsChildrenOnlyTransform);
bool shouldRound = true;
// An SVG frame should not have its translation rounded.
// Note it's possible that the SVG frame doesn't have an SVG
// transform but only has a CSS transform.
if (frame && frame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT) &&
!frame->IsSVGOuterSVGAnonChildFrame()) {
shouldRound = false;
}
bool shouldRound = ShouldRoundTransformOrigin(frame);
/* Transformed frames always have a transform, or are preserving 3d (and might
* still have perspective!) */
@ -8113,6 +8113,11 @@ Matrix4x4 nsDisplayTransform::GetTransformForRendering(
// to what GetTransform() would have returned.
float scale = mFrame->PresContext()->AppUnitsPerDevPixel();
*aOutOrigin = LayoutDevicePoint::FromAppUnits(ToReferenceFrame(), scale);
// The rounding behavior should also be the same as GetTransform().
if (ShouldRoundTransformOrigin(mFrame)) {
aOutOrigin->Round();
}
return GetResultingTransformMatrix(mFrame, nsPoint(0, 0), scale,
INCLUDE_PERSPECTIVE);
}

View File

@ -181,13 +181,13 @@ fails-if(!webrender) == object-position-png-002c.html object-position-png-002-re
== object-position-png-002i.html object-position-png-002-ref.html
== object-position-png-002o.html object-position-png-002-ref.html
== object-position-png-002p.html object-position-png-002-ref.html
random-if(webrender) == object-position-svg-001e.html object-position-svg-001-ref.html # bug 1103286
== object-position-svg-001e.html object-position-svg-001-ref.html
== object-position-svg-001i.html object-position-svg-001-ref.html
random-if(webrender) == object-position-svg-001o.html object-position-svg-001-ref.html # bug 1103286
== object-position-svg-001o.html object-position-svg-001-ref.html
== object-position-svg-001p.html object-position-svg-001-ref.html
fails-if(webrender) == object-position-svg-002e.html object-position-svg-002-ref.html # bug 1103286
== object-position-svg-002e.html object-position-svg-002-ref.html
== object-position-svg-002i.html object-position-svg-002-ref.html
fails-if(webrender) == object-position-svg-002o.html object-position-svg-002-ref.html # bug 1103286
== object-position-svg-002o.html object-position-svg-002-ref.html
== object-position-svg-002p.html object-position-svg-002-ref.html
# Tests for gradient color stops with 'currentcolor'