Commit 56aadb8e authored by fmalita@chromium.org's avatar fmalita@chromium.org

[SVG] Poor filter resolution when using CSS 3D transforms.

calculateTransformationToOutermostCoordinateSystem() should stop at the
first composited layer to match its backing resolution. Currently, we
are incorrectly taking the layer transform into account (the stop
condition is off by one).

R=pdr@chromium.org,schenney@chromium.org,senorblanco@chromium.org

BUG=345441

Review URL: https://codereview.chromium.org/196413023

git-svn-id: svn://svn.chromium.org/blink/trunk@169472 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent b5825005
...@@ -628,6 +628,8 @@ crbug.com/308952 [ XP ] inspector/editor/text-editor-reveal-line.html [ Failure ...@@ -628,6 +628,8 @@ crbug.com/308952 [ XP ] inspector/editor/text-editor-reveal-line.html [ Failure
crbug.com/310992 virtual/threaded/animations/play-state.html [ Pass Failure ] crbug.com/310992 virtual/threaded/animations/play-state.html [ Pass Failure ]
crbug.com/310992 animations/play-state.html [ Pass Failure ] crbug.com/310992 animations/play-state.html [ Pass Failure ]
Bug(fmalita) svg/custom/filter-css-transform-resolution.html [ NeedsRebaseline ]
crbug.com/327447 [ Linux Win Debug ] animations/combo-transform-translate+scale.html [ Pass Failure ] crbug.com/327447 [ Linux Win Debug ] animations/combo-transform-translate+scale.html [ Pass Failure ]
crbug.com/337736 [ Linux Win ] fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html [ Failure Pass ] crbug.com/337736 [ Linux Win ] fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html [ Failure Pass ]
......
layer at (0,0) size 800x600
RenderView at (0,0) size 800x600
layer at (0,0) size 800x321
RenderBlock {HTML} at (0,0) size 800x321
RenderBody {BODY} at (8,8) size 784x305
RenderBlock {DIV} at (0,0) size 784x305
RenderSVGRoot {svg} at (8,8) size 200x200
RenderSVGHiddenContainer {defs} at (0,0) size 0x0
RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
[feOffset dx="0.00" dy="0.00"]
[SourceGraphic]
RenderSVGEllipse {circle} at (8,8) size 200x200 [fill={[type=SOLID] [color=#008000]}] [cx=100.00] [cy=100.00] [r=100.00]
[filter="filter"] RenderSVGResourceFilter {filter} at (0,0) size 200x200
RenderText {#text} at (0,0) size 0x0
<!DOCTYPE html>
<html>
<head>
<script src="../../fast/repaint/resources/repaint.js"></script>
<script>
function repaintTest() {
document.getElementById('div').style.webkitTransform = '';
}
</script>
</head>
<body onload="runRepaintTest()">
<!-- Test for http://crbug.com/345441 - the circle edge should not be blurry -->
<div id="div" style="-webkit-transform: rotate3d(1, 0, 0, 85deg); -webkit-transform-origin: 100px 100px 0px;">
<svg width="300" height="300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<filter x="0" y="0" width="100%" height="100%" id="filter">
<feOffset/>
</filter>
</defs>
<circle cx="100" cy="100" r="100" fill="green" filter="url(#filter)"/>
</svg>
</div>
</body>
</html>
...@@ -171,7 +171,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, ...@@ -171,7 +171,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
// Determine absolute transformation matrix for filter. // Determine absolute transformation matrix for filter.
AffineTransform absoluteTransform; AffineTransform absoluteTransform;
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform); SVGRenderingContext::calculateDeviceSpaceTransformation(object, absoluteTransform);
if (!absoluteTransform.isInvertible()) if (!absoluteTransform.isInvertible())
return false; return false;
......
...@@ -85,7 +85,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign ...@@ -85,7 +85,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
return 0; return 0;
AffineTransform absoluteTransformIgnoringRotation; AffineTransform absoluteTransformIgnoringRotation;
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransformIgnoringRotation); SVGRenderingContext::calculateDeviceSpaceTransformation(object, absoluteTransformIgnoringRotation);
// Ignore 2D rotation, as it doesn't affect the size of the tile. // Ignore 2D rotation, as it doesn't affect the size of the tile.
SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation); SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
......
...@@ -203,12 +203,17 @@ float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObje ...@@ -203,12 +203,17 @@ float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObje
ASSERT(renderer); ASSERT(renderer);
AffineTransform ctm; AffineTransform ctm;
calculateTransformationToOutermostCoordinateSystem(renderer, ctm); // FIXME: calculateDeviceSpaceTransformation() queries layer compositing state - which is not
// supported during layout. Hence, the result may not include all CSS transforms.
calculateDeviceSpaceTransformation(renderer, ctm);
return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2)); return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
} }
void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform) void SVGRenderingContext::calculateDeviceSpaceTransformation(const RenderObject* renderer, AffineTransform& absoluteTransform)
{ {
// FIXME: trying to compute a device space transform at record time is wrong. All clients
// should be updated to avoid relying on this information, and the method should be removed.
ASSERT(renderer); ASSERT(renderer);
// We're about to possibly clear renderer, so save the deviceScaleFactor now. // We're about to possibly clear renderer, so save the deviceScaleFactor now.
float deviceScaleFactor = renderer->document().frameHost()->deviceScaleFactor(); float deviceScaleFactor = renderer->document().frameHost()->deviceScaleFactor();
...@@ -224,18 +229,18 @@ void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(con ...@@ -224,18 +229,18 @@ void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(con
// Continue walking up the layer tree, accumulating CSS transforms. // Continue walking up the layer tree, accumulating CSS transforms.
RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0; RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0;
while (layer) { while (layer && layer->isAllowedToQueryCompositingState()) {
if (TransformationMatrix* layerTransform = layer->transform())
absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform;
// We can stop at compositing layers, to match the backing resolution. // We can stop at compositing layers, to match the backing resolution.
// FIXME: should we be computing the transform to the nearest composited layer, // FIXME: should we be computing the transform to the nearest composited layer,
// or the nearest composited layer that does not paint into its ancestor? // or the nearest composited layer that does not paint into its ancestor?
// I think this is the nearest composited ancestor since we will inherit its // I think this is the nearest composited ancestor since we will inherit its
// transforms in the composited layer tree. // transforms in the composited layer tree.
if (layer->hasCompositedLayerMapping()) if (layer->compositingState() != NotComposited)
break; break;
if (TransformationMatrix* layerTransform = layer->transform())
absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform;
layer = layer->parent(); layer = layer->parent();
} }
......
...@@ -79,7 +79,7 @@ public: ...@@ -79,7 +79,7 @@ public:
static void renderSubtree(GraphicsContext*, RenderObject*, const AffineTransform&); static void renderSubtree(GraphicsContext*, RenderObject*, const AffineTransform&);
static float calculateScreenFontSizeScalingFactor(const RenderObject*); static float calculateScreenFontSizeScalingFactor(const RenderObject*);
static void calculateTransformationToOutermostCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform); static void calculateDeviceSpaceTransformation(const RenderObject*, AffineTransform& absoluteTransform);
static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect); static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
static void clear2DRotation(AffineTransform&); static void clear2DRotation(AffineTransform&);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment