Commit cb6ae972 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[PE] Check relative diff for scale components when checking transform changes

The case is extended from crbug.com/849382. Some elements may display
by scaling down from huge geometries with a tiny scale. When the scale
changes (e.g. from 1e-6 from 2e-6), the rasterized result will
significantly change which should not be ignored.

Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I31928d95f8d864de83a75af02fd3cfe95ef8e8fa
Reviewed-on: https://chromium-review.googlesource.com/1087812
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#564776}
parent fcefceac
{
"layers": [
{
"name": "LayoutView #document",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"paintInvalidations": [
{
"object": "LayoutSVGViewportContainer svg id='huge-symbol'",
"rect": [8, 8, 25, 25],
"reason": "paint property change"
},
{
"object": "LayoutSVGViewportContainer svg id='huge-symbol'",
"rect": [8, 8, 20, 20],
"reason": "paint property change"
}
]
}
],
"objectPaintInvalidations": [
{
"object": "LayoutBlockFlow BODY",
"reason": "geometry"
},
{
"object": "RootInlineBox",
"reason": "geometry"
},
{
"object": "LayoutSVGRoot svg id='svg'",
"reason": "full"
},
{
"object": "LayoutSVGContainer use",
"reason": "full"
}
]
}
<!DOCTYPE html>
<div style="width: 25px; height: 25px; background: black"></div>
{
"layers": [
{
"name": "LayoutView #document",
"bounds": [800, 600],
"drawsContent": false,
"backgroundColor": "#FFFFFF"
},
{
"name": "Scrolling Layer",
"bounds": [800, 600],
"drawsContent": false
},
{
"name": "Scrolling Contents Layer",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"paintInvalidations": [
{
"object": "LayoutSVGViewportContainer svg id='huge-symbol'",
"rect": [8, 8, 25, 25],
"reason": "paint property change"
},
{
"object": "LayoutSVGViewportContainer svg id='huge-symbol'",
"rect": [8, 8, 20, 20],
"reason": "paint property change"
}
]
}
],
"objectPaintInvalidations": [
{
"object": "LayoutBlockFlow BODY",
"reason": "geometry"
},
{
"object": "RootInlineBox",
"reason": "geometry"
},
{
"object": "LayoutSVGRoot svg id='svg'",
"reason": "full"
},
{
"object": "LayoutSVGContainer use",
"reason": "full"
}
]
}
<!DOCTYPE html>
<svg id="svg" width="20" height="20" overflow="visible">
<symbol viewBox="0 0 1000000 1000000" id="huge-symbol">
<path d="M0 0 L1000000 0 L1000000 1000000 L0 1000000 L0 0"></path>
</symbol>
<use xlink:href="#huge-symbol"/>
</svg>
<script src="../resources/text-based-repaint.js"></script>
<script>
function repaintTest() {
svg.setAttribute('width', 25);
svg.setAttribute('height', 25);
}
onload = runRepaintAndPixelTest;
</script>
......@@ -48,7 +48,13 @@ size_t CompositedLayerRasterInvalidator::MatchNewChunkToOldChunk(
static bool ApproximatelyEqual(const SkMatrix& a, const SkMatrix& b) {
static constexpr float kTolerance = 1e-5f;
for (int i = 0; i < 9; i++) {
if (std::abs(a[i] - b[i]) > kTolerance)
auto difference = std::abs(a[i] - b[i]);
// Check for absolute difference.
if (difference > kTolerance)
return false;
// For scale components, also check for relative difference.
if ((i == 0 || i == 4 || i == 9) &&
difference > (std::abs(a[i]) + std::abs(b[i])) * kTolerance)
return false;
}
return true;
......
......@@ -665,4 +665,52 @@ TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyTinyChange) {
EXPECT_TRUE(invalidated);
}
TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyTinyChangeScale) {
CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation);
auto layer_transform = CreateTransform(t0(), TransformationMatrix().Scale(5));
auto chunk_transform =
CreateTransform(*layer_transform, TransformationMatrix().Scale(1e-6));
FloatRect chunk_bounds(0, 0, 10000000, 10000000);
PropertyTreeState layer_state(layer_transform.get(), &c0(), &e0());
auto artifact = Chunk(0)
.Bounds(chunk_bounds)
.Properties(*chunk_transform, c0(), e0())
.Build();
GeometryMapperTransformCache::ClearCache();
invalidator.Generate(artifact, kDefaultLayerBounds, layer_state);
// Scale change from 1e-6 to 2e-6 should be treated as significant.
invalidator.SetTracksRasterInvalidations(true);
chunk_transform->Update(
*layer_state.Transform(),
TransformPaintPropertyNode::State{TransformationMatrix().Scale(2e-6)});
auto new_artifact = Chunk(0)
.Bounds(chunk_bounds)
.Properties(*chunk_transform, c0(), e0())
.Build();
GeometryMapperTransformCache::ClearCache();
invalidator.Generate(new_artifact, kDefaultLayerBounds, layer_state);
EXPECT_FALSE(TrackedRasterInvalidations(invalidator).IsEmpty());
invalidator.SetTracksRasterInvalidations(false);
// Scale change from 2e-6 to 2e-6 + 1e-15 should be ignored.
invalidator.SetTracksRasterInvalidations(true);
chunk_transform->Update(*layer_state.Transform(),
TransformPaintPropertyNode::State{
TransformationMatrix().Scale(2e-6 + 1e-15)});
auto new_artifact1 = Chunk(0)
.Bounds(chunk_bounds)
.Properties(*chunk_transform, c0(), e0())
.Build();
GeometryMapperTransformCache::ClearCache();
invalidator.Generate(new_artifact, kDefaultLayerBounds, layer_state);
EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
invalidator.SetTracksRasterInvalidations(false);
}
} // namespace blink
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