Commit 597b2a11 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[SPv175+] Optimize chunk rasterization on clip change

- When possible, detect chunk_to_layer_clip change;
- When possible, issue incremental raster invalidation on clip change.

Bug: 771643
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I8cea00f3c3ebcd035eae9bfcf29971a7a02a96df
Reviewed-on: https://chromium-review.googlesource.com/753540
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarTien-Ren Chen <trchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517912}
parent e349345e
{
"layers": [
{
"name": "LayoutView #document",
"bounds": [800, 600],
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow DIV class='composited-child'",
"bounds": [100, 100],
"contentsOpaque": true,
"backfaceVisibility": "hidden",
"backgroundColor": "#008000"
},
{
"name": "Ancestor Clipping Layer",
"position": [0, 200],
"bounds": [200, 200],
"drawsContent": false
},
{
"name": "LayoutBlockFlow DIV class='composited-child'",
"position": [0, 200],
"bounds": [100, 100],
"contentsOpaque": true,
"backfaceVisibility": "hidden",
"backgroundColor": "#008000"
},
{
"name": "LayoutBlockFlow (relative positioned) DIV class='composited-child overflow-child'",
"position": [150, 150],
"bounds": [100, 100],
"contentsOpaque": true,
"backfaceVisibility": "hidden",
"backgroundColor": "#008000"
},
{
"name": "Ancestor Clipping Layer",
"position": [0, 200],
"bounds": [200, 200],
"drawsContent": false
},
{
"name": "LayoutBlockFlow (relative positioned) DIV class='composited-child overflow-child'",
"position": [150, 350],
"bounds": [100, 100],
"contentsOpaque": true,
"backfaceVisibility": "hidden",
"backgroundColor": "#008000"
}
],
"objectPaintInvalidations": [
{
"object": "LayoutBlockFlow DIV id='overflow1'",
"reason": "style change"
},
{
"object": "LayoutBlockFlow DIV id='overflow2'",
"reason": "style change"
}
]
}
...@@ -8,33 +8,18 @@ ...@@ -8,33 +8,18 @@
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 105, 112], "rect": [8, 58, 105, 62],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutTextControl INPUT id='target'", "object": "LayoutTextControl INPUT id='target'",
"rect": [8, 8, 105, 112], "rect": [8, 58, 105, 62],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 105, 50], "rect": [10, 58, 1, 57],
"reason": "paint property change" "reason": "incremental"
},
{
"object": "LayoutTextControl INPUT id='target'",
"rect": [8, 8, 105, 50],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [10, 8, 1, 107],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [10, 8, 1, 50],
"reason": "paint property change"
} }
] ]
} }
......
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 300, 300], "rect": [8, 8, 300, 200],
"reason": "paint property change" "reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 300, 200], "rect": [8, 208, 300, 100],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV id='s'",
"rect": [8, 156, 108, 108], "rect": [8, 156, 108, 108],
"reason": "paint property change" "reason": "geometry"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 156, 108, 56], "rect": [8, 212, 108, 52],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -7,14 +7,24 @@ ...@@ -7,14 +7,24 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "InlineTextBox 'x'",
"rect": [8, 220, 100, 100], "rect": [8, 220, 100, 100],
"reason": "paint property change" "reason": "geometry"
},
{
"object": "InlineTextBox 'x'",
"rect": [8, 220, 100, 80],
"reason": "geometry"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [8, 300, 100, 20],
"reason": "incremental"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 200, 100, 100], "rect": [8, 200, 100, 20],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{ {
"object": "LayoutBlockFlow HTML", "object": "LayoutBlockFlow HTML",
"rect": [8, 300, 60, 22], "rect": [8, 300, 60, 22],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutView #document", "object": "LayoutView #document",
......
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
"reason": "geometry" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRect rect id='targetRect'",
"rect": [9, 73, 400, 400], "rect": [9, 73, 400, 400],
"reason": "paint property change" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRoot svg",
"rect": [9, 73, 100, 400], "rect": [109, 73, 300, 400],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -12,14 +12,34 @@ ...@@ -12,14 +12,34 @@
"reason": "geometry" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGEllipse circle",
"rect": [47, 111, 324, 324], "rect": [47, 111, 324, 324],
"reason": "paint property change" "reason": "SVG resource change"
},
{
"object": "LayoutSVGRoot svg",
"rect": [47, 392, 324, 43],
"reason": "incremental"
},
{
"object": "LayoutSVGRoot svg",
"rect": [47, 111, 324, 43],
"reason": "incremental"
},
{
"object": "LayoutSVGRoot svg",
"rect": [110, 154, 261, 238],
"reason": "incremental"
},
{
"object": "LayoutSVGEllipse circle",
"rect": [8, 154, 170, 238],
"reason": "SVG resource change"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRoot svg",
"rect": [8, 154, 102, 238], "rect": [8, 154, 39, 238],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
"reason": "geometry" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGImage image",
"rect": [9, 73, 400, 400], "rect": [9, 73, 400, 400],
"reason": "paint property change" "reason": "image"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRoot svg",
"rect": [9, 73, 100, 400], "rect": [109, 73, 300, 400],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -19,16 +19,16 @@ ...@@ -19,16 +19,16 @@
{ {
"object": "LayoutSVGRect rect id='targetRect1'", "object": "LayoutSVGRect rect id='targetRect1'",
"rect": [9, 73, 200, 200], "rect": [9, 73, 200, 200],
"reason": "paint property change" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGContainer use", "object": "LayoutSVGRect rect id='targetRect1'",
"rect": [59, 273, 50, 200], "rect": [59, 73, 150, 200],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutSVGRect rect id='targetRect1'", "object": "LayoutSVGContainer use",
"rect": [9, 73, 50, 200], "rect": [59, 273, 50, 200],
"reason": "paint property change" "reason": "paint property change"
} }
] ]
......
...@@ -162,11 +162,6 @@ CASE 4, overlap1 gets removed: ...@@ -162,11 +162,6 @@ CASE 4, overlap1 gets removed:
"position": [300, 300], "position": [300, 300],
"bounds": [100, 100], "bounds": [100, 100],
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutBlockFlow (positioned) DIV id='C' class='overlap3'",
"rect": [160, 160, 100, 100],
"reason": "paint property change"
},
{ {
"object": "LayoutBlockFlow (positioned) DIV id='A' class='overlap1'", "object": "LayoutBlockFlow (positioned) DIV id='A' class='overlap1'",
"rect": [0, 0, 100, 100], "rect": [0, 0, 100, 100],
......
...@@ -8,33 +8,18 @@ ...@@ -8,33 +8,18 @@
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 105, 112], "rect": [8, 58, 105, 62],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutTextControl INPUT id='target'", "object": "LayoutTextControl INPUT id='target'",
"rect": [8, 8, 105, 112], "rect": [8, 58, 105, 62],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 105, 50], "rect": [10, 58, 1, 57],
"reason": "paint property change" "reason": "incremental"
},
{
"object": "LayoutTextControl INPUT id='target'",
"rect": [8, 8, 105, 50],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [10, 8, 1, 107],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [10, 8, 1, 50],
"reason": "paint property change"
} }
] ]
} }
......
...@@ -7,14 +7,9 @@ ...@@ -7,14 +7,9 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV id='content'",
"rect": [8, 120, 100, 300], "rect": [8, 120, 100, 300],
"reason": "paint property change" "reason": "style change"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [8, 120, 100, 100],
"reason": "paint property change"
} }
] ]
} }
......
...@@ -8,13 +8,13 @@ ...@@ -8,13 +8,13 @@
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 300, 300], "rect": [8, 8, 300, 200],
"reason": "paint property change" "reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 8, 300, 200], "rect": [8, 208, 300, 100],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -23,9 +23,14 @@ ...@@ -23,9 +23,14 @@
"bounds": [300, 654], "bounds": [300, 654],
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow HTML", "object": "InlineTextBox 'test1'",
"rect": [8, 508, 29, 19],
"reason": "appeared"
},
{
"object": "InlineTextBox 'test1'",
"rect": [8, 508, 29, 19], "rect": [8, 508, 29, 19],
"reason": "paint property change" "reason": "disappeared"
}, },
{ {
"object": "LayoutView #document", "object": "LayoutView #document",
......
...@@ -7,14 +7,14 @@ ...@@ -7,14 +7,14 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV id='s'",
"rect": [8, 156, 108, 108], "rect": [8, 156, 108, 108],
"reason": "paint property change" "reason": "geometry"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 156, 108, 56], "rect": [8, 212, 108, 52],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -7,14 +7,24 @@ ...@@ -7,14 +7,24 @@
"backgroundColor": "#FFFFFF", "backgroundColor": "#FFFFFF",
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV", "object": "InlineTextBox 'x'",
"rect": [8, 220, 100, 100], "rect": [8, 220, 100, 100],
"reason": "paint property change" "reason": "geometry"
},
{
"object": "InlineTextBox 'x'",
"rect": [8, 220, 100, 80],
"reason": "geometry"
},
{
"object": "LayoutBlockFlow DIV",
"rect": [8, 300, 100, 20],
"reason": "incremental"
}, },
{ {
"object": "LayoutBlockFlow DIV", "object": "LayoutBlockFlow DIV",
"rect": [8, 200, 100, 100], "rect": [8, 200, 100, 20],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
{ {
"object": "LayoutBlockFlow (positioned) DIV class='absolute green reflected'", "object": "LayoutBlockFlow (positioned) DIV class='absolute green reflected'",
"rect": [250, 280, 100, 100], "rect": [250, 280, 100, 100],
"reason": "paint property change" "reason": "chunk reordered"
}, },
{ {
"object": "LayoutBlockFlow (positioned) DIV id='hideMe' class='absolute red'", "object": "LayoutBlockFlow (positioned) DIV id='hideMe' class='absolute red'",
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
{ {
"object": "LayoutBlockFlow HTML", "object": "LayoutBlockFlow HTML",
"rect": [8, 300, 60, 22], "rect": [8, 300, 60, 22],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutView #document", "object": "LayoutView #document",
......
...@@ -8,23 +8,13 @@ ...@@ -8,23 +8,13 @@
"paintInvalidations": [ "paintInvalidations": [
{ {
"object": "LayoutBlockFlow DIV id='target'", "object": "LayoutBlockFlow DIV id='target'",
"rect": [8, 8, 100, 200], "rect": [8, 108, 100, 100],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutBlockFlow DIV id='target'", "object": "LayoutBlockFlow DIV id='target'",
"rect": [8, 8, 100, 200], "rect": [8, 108, 100, 100],
"reason": "paint property change" "reason": "incremental"
},
{
"object": "LayoutBlockFlow DIV id='target'",
"rect": [8, 8, 100, 100],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow DIV id='target'",
"rect": [8, 8, 100, 100],
"reason": "paint property change"
} }
] ]
} }
......
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
"reason": "geometry" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRect rect id='targetRect'",
"rect": [9, 73, 400, 400], "rect": [9, 73, 400, 400],
"reason": "paint property change" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRoot svg",
"rect": [9, 73, 100, 400], "rect": [109, 73, 300, 400],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -12,14 +12,34 @@ ...@@ -12,14 +12,34 @@
"reason": "geometry" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGEllipse circle",
"rect": [47, 111, 324, 324], "rect": [47, 111, 324, 324],
"reason": "paint property change" "reason": "SVG resource change"
},
{
"object": "LayoutSVGRoot svg",
"rect": [47, 392, 324, 43],
"reason": "incremental"
},
{
"object": "LayoutSVGRoot svg",
"rect": [47, 111, 324, 43],
"reason": "incremental"
},
{
"object": "LayoutSVGRoot svg",
"rect": [110, 154, 261, 238],
"reason": "incremental"
},
{
"object": "LayoutSVGEllipse circle",
"rect": [8, 154, 170, 238],
"reason": "SVG resource change"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRoot svg",
"rect": [8, 154, 102, 238], "rect": [8, 154, 39, 238],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -12,14 +12,14 @@ ...@@ -12,14 +12,14 @@
"reason": "geometry" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGImage image",
"rect": [9, 73, 400, 400], "rect": [9, 73, 400, 400],
"reason": "paint property change" "reason": "image"
}, },
{ {
"object": "LayoutSVGRoot svg", "object": "LayoutSVGRoot svg",
"rect": [9, 73, 100, 400], "rect": [109, 73, 300, 400],
"reason": "paint property change" "reason": "incremental"
} }
] ]
} }
......
...@@ -19,16 +19,16 @@ ...@@ -19,16 +19,16 @@
{ {
"object": "LayoutSVGRect rect id='targetRect1'", "object": "LayoutSVGRect rect id='targetRect1'",
"rect": [9, 73, 200, 200], "rect": [9, 73, 200, 200],
"reason": "paint property change" "reason": "geometry"
}, },
{ {
"object": "LayoutSVGContainer use", "object": "LayoutSVGRect rect id='targetRect1'",
"rect": [59, 273, 50, 200], "rect": [59, 73, 150, 200],
"reason": "paint property change" "reason": "incremental"
}, },
{ {
"object": "LayoutSVGRect rect id='targetRect1'", "object": "LayoutSVGContainer use",
"rect": [9, 73, 50, 200], "rect": [59, 273, 50, 200],
"reason": "paint property change" "reason": "paint property change"
} }
] ]
......
...@@ -13,10 +13,20 @@ ...@@ -13,10 +13,20 @@
"backfaceVisibility": "hidden", "backfaceVisibility": "hidden",
"backgroundColor": "#FFFF00", "backgroundColor": "#FFFF00",
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutBlockFlow (positioned) DIV id='target'",
"rect": [0, 0, 402, 542],
"reason": "paint property change"
},
{ {
"object": "LayoutBlockFlow (positioned) DIV id='target'", "object": "LayoutBlockFlow (positioned) DIV id='target'",
"rect": [0, 0, 200, 200], "rect": [0, 0, 200, 200],
"reason": "full" "reason": "full"
},
{
"object": "LayoutBlockFlow (positioned) DIV id='target'",
"rect": [0, 0, 200, 200],
"reason": "paint property change"
} }
] ]
}, },
......
...@@ -26,16 +26,6 @@ ...@@ -26,16 +26,6 @@
"position": [8, 8], "position": [8, 8],
"bounds": [700, 525], "bounds": [700, 525],
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutFlexibleBox (relative positioned) DIV",
"rect": [0, 493, 700, 32],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow (positioned) DIV",
"rect": [108, 508, 404, 2],
"reason": "paint property change"
},
{ {
"object": "LayoutBlockFlow (positioned) DIV", "object": "LayoutBlockFlow (positioned) DIV",
"rect": [580, 508, 70, 2], "rect": [580, 508, 70, 2],
...@@ -44,17 +34,17 @@ ...@@ -44,17 +34,17 @@
{ {
"object": "LayoutBlockFlow (positioned) DIV id='thumb'", "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
"rect": [632, 493, 36, 32], "rect": [632, 493, 36, 32],
"reason": "paint property change" "reason": "full"
}, },
{ {
"object": "LayoutBlockFlow (positioned) DIV id='thumb'", "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
"rect": [562, 493, 36, 32], "rect": [562, 493, 36, 32],
"reason": "paint property change" "reason": "full"
}, },
{ {
"object": "LayoutBlockFlow (positioned) DIV id='thumb'", "object": "LayoutButton INPUT class='muted'",
"rect": [90, 493, 36, 32], "rect": [530, 493, 32, 32],
"reason": "paint property change" "reason": "full"
} }
] ]
} }
......
...@@ -26,35 +26,25 @@ ...@@ -26,35 +26,25 @@
"position": [8, 8], "position": [8, 8],
"bounds": [700, 525], "bounds": [700, 525],
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutFlexibleBox (relative positioned) DIV",
"rect": [0, 493, 700, 32],
"reason": "paint property change"
},
{
"object": "LayoutBlockFlow (positioned) DIV",
"rect": [108, 508, 404, 2],
"reason": "paint property change"
},
{ {
"object": "LayoutBlockFlow (positioned) DIV id='thumb'", "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
"rect": [597, 493, 36, 32], "rect": [597, 493, 36, 32],
"reason": "paint property change" "reason": "full"
}, },
{ {
"object": "LayoutBlockFlow (positioned) DIV id='thumb'", "object": "LayoutBlockFlow (positioned) DIV id='thumb'",
"rect": [562, 493, 36, 32], "rect": [562, 493, 36, 32],
"reason": "paint property change" "reason": "full"
},
{
"object": "LayoutBlockFlow (positioned) DIV id='thumb'",
"rect": [90, 493, 36, 32],
"reason": "paint property change"
}, },
{ {
"object": "LayoutBlockFlow (positioned) DIV", "object": "LayoutBlockFlow (positioned) DIV",
"rect": [580, 508, 35, 2], "rect": [580, 508, 35, 2],
"reason": "appeared" "reason": "appeared"
},
{
"object": "LayoutButton INPUT",
"rect": [530, 493, 32, 32],
"reason": "full"
} }
] ]
} }
......
...@@ -23,12 +23,12 @@ ...@@ -23,12 +23,12 @@
}, },
{ {
"object": "LayoutView #document", "object": "LayoutView #document",
"rect": [0, 0, 600, 500], "rect": [0, 0, 600, 235],
"reason": "paint property change" "reason": "paint property change"
}, },
{ {
"object": "LayoutBlockFlow HTML", "object": "LayoutBlockFlow HTML",
"rect": [168, 8, 423, 482], "rect": [168, 8, 423, 227],
"reason": "paint property change" "reason": "paint property change"
} }
], ],
...@@ -257,17 +257,17 @@ ...@@ -257,17 +257,17 @@
}, },
{ {
"object": "LayoutView #document", "object": "LayoutView #document",
"rect": [0, 0, 939, 235], "rect": [0, 0, 400, 600],
"reason": "paint property change" "reason": "paint property change"
}, },
{ {
"object": "LayoutBlockFlow HTML", "object": "LayoutView #document",
"rect": [10, 7, 920, 213], "rect": [0, 0, 400, 235],
"reason": "paint property change" "reason": "paint property change"
}, },
{ {
"object": "LayoutView #document", "object": "LayoutBlockFlow HTML",
"rect": [0, 0, 400, 600], "rect": [10, 7, 390, 213],
"reason": "paint property change" "reason": "paint property change"
}, },
{ {
......
...@@ -42,9 +42,7 @@ IntRect CompositedLayerRasterInvalidator::MapRectFromChunkToLayer( ...@@ -42,9 +42,7 @@ IntRect CompositedLayerRasterInvalidator::MapRectFromChunkToLayer(
// so need to subtract off the layer offset. // so need to subtract off the layer offset.
rect.Rect().Move(-layer_bounds_.x(), -layer_bounds_.y()); rect.Rect().Move(-layer_bounds_.x(), -layer_bounds_.y());
rect.Rect().Inflate(chunk.outset_for_raster_effects); rect.Rect().Inflate(chunk.outset_for_raster_effects);
return Intersection( return ClipByLayerBounds(EnclosingIntRect(rect.Rect()));
EnclosingIntRect(rect.Rect()),
IntRect(0, 0, layer_bounds_.width(), layer_bounds_.height()));
} }
TransformationMatrix CompositedLayerRasterInvalidator::ChunkToLayerTransform( TransformationMatrix CompositedLayerRasterInvalidator::ChunkToLayerTransform(
...@@ -56,6 +54,24 @@ TransformationMatrix CompositedLayerRasterInvalidator::ChunkToLayerTransform( ...@@ -56,6 +54,24 @@ TransformationMatrix CompositedLayerRasterInvalidator::ChunkToLayerTransform(
return matrix; return matrix;
} }
// Returns the clip rect when we know it is precise (no radius, no complex
// transform, no pixel moving filter, etc.)
FloatClipRect CompositedLayerRasterInvalidator::ChunkToLayerClip(
const PaintChunk& chunk) const {
FloatClipRect clip_rect;
if (chunk.properties.property_tree_state.Effect() != layer_state_.Effect()) {
// Don't bother GeometryMapper because we don't need the rect when it's not
// tight because of the effect nodes.
clip_rect.ClearIsTight();
} else {
clip_rect = GeometryMapper::LocalToAncestorClipRect(
chunk.properties.property_tree_state, layer_state_);
if (clip_rect.IsTight())
clip_rect.MoveBy(FloatPoint(-layer_bounds_.x(), -layer_bounds_.y()));
}
return clip_rect;
}
size_t CompositedLayerRasterInvalidator::MatchNewChunkToOldChunk( size_t CompositedLayerRasterInvalidator::MatchNewChunkToOldChunk(
const PaintChunk& new_chunk, const PaintChunk& new_chunk,
size_t old_index) { size_t old_index) {
...@@ -70,32 +86,50 @@ size_t CompositedLayerRasterInvalidator::MatchNewChunkToOldChunk( ...@@ -70,32 +86,50 @@ size_t CompositedLayerRasterInvalidator::MatchNewChunkToOldChunk(
return kNotFound; return kNotFound;
} }
bool CompositedLayerRasterInvalidator::ChunkPropertiesChanged( PaintInvalidationReason
CompositedLayerRasterInvalidator::ChunkPropertiesChanged(
const PaintChunkInfo& new_chunk, const PaintChunkInfo& new_chunk,
const PaintChunkInfo& old_chunk) const { const PaintChunkInfo& old_chunk) const {
if (new_chunk.properties.backface_hidden != if (new_chunk.properties.backface_hidden !=
old_chunk.properties.backface_hidden) old_chunk.properties.backface_hidden)
return true; return PaintInvalidationReason::kPaintProperty;
// Treat the chunk property as changed if clip or effect node is different,
// or the value of clip or effect nodes changed between the layer state and
// the the chunk state.
const auto& new_chunk_state = new_chunk.properties.property_tree_state;
const auto& old_chunk_state = old_chunk.properties.property_tree_state;
if (new_chunk_state.Clip() != old_chunk_state.Clip() ||
new_chunk_state.Clip()->Changed(*layer_state_.Clip()) ||
new_chunk_state.Effect() != old_chunk_state.Effect() ||
new_chunk_state.Effect()->Changed(*layer_state_.Effect()))
return true;
// Special case for transform changes because we may create or delete some // Special case for transform changes because we may create or delete some
// transform nodes when no raster invalidation is needed. For example, when // transform nodes when no raster invalidation is needed. For example, when
// a composited layer previously not transformed now gets transformed. // a composited layer previously not transformed now gets transformed.
// Check for real accumulated transform change instead. // Check for real accumulated transform change instead.
if (new_chunk.chunk_to_layer_transform != old_chunk.chunk_to_layer_transform) if (new_chunk.chunk_to_layer_transform != old_chunk.chunk_to_layer_transform)
return true; return PaintInvalidationReason::kPaintProperty;
return false; // Treat the chunk property as changed if the effect node pointer is
// different, or the effect node's value changed between the layer state and
// the chunk state.
const auto& new_chunk_state = new_chunk.properties.property_tree_state;
const auto& old_chunk_state = old_chunk.properties.property_tree_state;
if (new_chunk_state.Effect() != old_chunk_state.Effect() ||
new_chunk_state.Effect()->Changed(*layer_state_.Effect()))
return PaintInvalidationReason::kPaintProperty;
// Check for accumulated clip rect change, if the clip rects are tight.
if (new_chunk.chunk_to_layer_clip.IsTight() &&
old_chunk.chunk_to_layer_clip.IsTight()) {
if (new_chunk.chunk_to_layer_clip == old_chunk.chunk_to_layer_clip)
return PaintInvalidationReason::kNone;
// Ignore differences out of the current layer bounds.
if (ClipByLayerBounds(new_chunk.chunk_to_layer_clip.Rect()) ==
ClipByLayerBounds(old_chunk.chunk_to_layer_clip.Rect()))
return PaintInvalidationReason::kNone;
return PaintInvalidationReason::kIncremental;
}
// Otherwise treat the chunk property as changed if the clip node pointer is
// different, or the clip node's value changed between the layer state and the
// chunk state.
if (new_chunk_state.Clip() != old_chunk_state.Clip() ||
new_chunk_state.Clip()->Changed(*layer_state_.Clip()))
return PaintInvalidationReason::kPaintProperty;
return PaintInvalidationReason::kNone;
} }
// Generates raster invalidations by checking changes (appearing, disappearing, // Generates raster invalidations by checking changes (appearing, disappearing,
...@@ -120,7 +154,7 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( ...@@ -120,7 +154,7 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations(
const auto& new_chunk_info = new_chunks_info[new_index]; const auto& new_chunk_info = new_chunks_info[new_index];
if (!new_chunk.is_cacheable) { if (!new_chunk.is_cacheable) {
InvalidateRasterForNewChunk(new_chunk_info, FullyInvalidateNewChunk(new_chunk_info,
PaintInvalidationReason::kChunkUncacheable); PaintInvalidationReason::kChunkUncacheable);
continue; continue;
} }
...@@ -128,47 +162,50 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( ...@@ -128,47 +162,50 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations(
size_t matched_old_index = MatchNewChunkToOldChunk(new_chunk, old_index); size_t matched_old_index = MatchNewChunkToOldChunk(new_chunk, old_index);
if (matched_old_index == kNotFound) { if (matched_old_index == kNotFound) {
// The new chunk doesn't match any old chunk. // The new chunk doesn't match any old chunk.
InvalidateRasterForNewChunk(new_chunk_info, FullyInvalidateNewChunk(new_chunk_info,
PaintInvalidationReason::kAppeared); PaintInvalidationReason::kAppeared);
continue; continue;
} }
DCHECK(!old_chunks_matched[matched_old_index]); DCHECK(!old_chunks_matched[matched_old_index]);
old_chunks_matched[matched_old_index] = true; old_chunks_matched[matched_old_index] = true;
bool moved_earlier = matched_old_index < max_matched_old_index;
max_matched_old_index = std::max(max_matched_old_index, matched_old_index);
bool properties_changed = ChunkPropertiesChanged( auto& old_chunk_info = paint_chunks_info_[matched_old_index];
new_chunk_info, paint_chunks_info_[matched_old_index]); // Clip the old chunk bounds by the new layer bounds.
if (!properties_changed && !moved_earlier) { old_chunk_info.bounds_in_layer =
// Add the raster invalidations found by PaintController within the chunk. ClipByLayerBounds(old_chunk_info.bounds_in_layer);
AddDisplayItemRasterInvalidations(new_chunk);
} else { PaintInvalidationReason reason =
matched_old_index < max_matched_old_index
? PaintInvalidationReason::kChunkReordered
: ChunkPropertiesChanged(new_chunk_info, old_chunk_info);
if (IsFullPaintInvalidationReason(reason)) {
// Invalidate both old and new bounds of the chunk if the chunk's paint // Invalidate both old and new bounds of the chunk if the chunk's paint
// properties changed, or is moved backward and may expose area that was // properties changed, or is moved backward and may expose area that was
// previously covered by it. // previously covered by it.
const auto& old_chunk_info = paint_chunks_info_[matched_old_index]; FullyInvalidateChunk(old_chunk_info, new_chunk_info, reason);
PaintInvalidationReason reason =
properties_changed ? PaintInvalidationReason::kPaintProperty
: PaintInvalidationReason::kChunkReordered;
InvalidateRasterForOldChunk(old_chunk_info, reason);
if (old_chunk_info.bounds_in_layer != new_chunk_info.bounds_in_layer)
InvalidateRasterForNewChunk(new_chunk_info, reason);
// Ignore the display item raster invalidations because we have fully // Ignore the display item raster invalidations because we have fully
// invalidated the chunk. // invalidated the chunk.
} else {
if (reason == PaintInvalidationReason::kIncremental)
IncrementallyInvalidateChunk(old_chunk_info, new_chunk_info);
// Add the raster invalidations found by PaintController within the chunk.
AddDisplayItemRasterInvalidations(new_chunk);
} }
old_index = matched_old_index + 1; old_index = matched_old_index + 1;
if (old_index == paint_chunks_info_.size()) if (old_index == paint_chunks_info_.size())
old_index = 0; old_index = 0;
max_matched_old_index = std::max(max_matched_old_index, matched_old_index);
} }
// Invalidate remaining unmatched (disappeared or uncacheable) old chunks. // Invalidate remaining unmatched (disappeared or uncacheable) old chunks.
for (size_t i = 0; i < paint_chunks_info_.size(); ++i) { for (size_t i = 0; i < paint_chunks_info_.size(); ++i) {
if (old_chunks_matched[i]) if (old_chunks_matched[i])
continue; continue;
InvalidateRasterForOldChunk( FullyInvalidateOldChunk(paint_chunks_info_[i],
paint_chunks_info_[i],
paint_chunks_info_[i].is_cacheable paint_chunks_info_[i].is_cacheable
? PaintInvalidationReason::kDisappeared ? PaintInvalidationReason::kDisappeared
: PaintInvalidationReason::kChunkUncacheable); : PaintInvalidationReason::kChunkUncacheable);
...@@ -196,31 +233,53 @@ void CompositedLayerRasterInvalidator::AddDisplayItemRasterInvalidations( ...@@ -196,31 +233,53 @@ void CompositedLayerRasterInvalidator::AddDisplayItemRasterInvalidations(
} }
} }
void CompositedLayerRasterInvalidator::InvalidateRasterForNewChunk( void CompositedLayerRasterInvalidator::IncrementallyInvalidateChunk(
const PaintChunkInfo& info, const PaintChunkInfo& old_chunk,
const PaintChunkInfo& new_chunk) {
SkRegion diff(old_chunk.bounds_in_layer);
diff.op(new_chunk.bounds_in_layer, SkRegion::kXOR_Op);
for (SkRegion::Iterator it(diff); !it.done(); it.next()) {
const SkIRect& r = it.rect();
AddRasterInvalidation(IntRect(r.x(), r.y(), r.width(), r.height()),
&new_chunk.id.client,
PaintInvalidationReason::kIncremental);
}
}
void CompositedLayerRasterInvalidator::FullyInvalidateChunk(
const PaintChunkInfo& old_chunk,
const PaintChunkInfo& new_chunk,
PaintInvalidationReason reason) { PaintInvalidationReason reason) {
raster_invalidation_function_(info.bounds_in_layer); FullyInvalidateOldChunk(old_chunk, reason);
if (old_chunk.bounds_in_layer != new_chunk.bounds_in_layer)
FullyInvalidateNewChunk(new_chunk, reason);
}
if (tracking_info_) { void CompositedLayerRasterInvalidator::FullyInvalidateNewChunk(
tracking_info_->tracking.AddInvalidation(&info.id.client, const PaintChunkInfo& info,
info.id.client.DebugName(), PaintInvalidationReason reason) {
info.bounds_in_layer, reason); AddRasterInvalidation(info.bounds_in_layer, &info.id.client, reason);
}
} }
void CompositedLayerRasterInvalidator::InvalidateRasterForOldChunk( void CompositedLayerRasterInvalidator::FullyInvalidateOldChunk(
const PaintChunkInfo& info, const PaintChunkInfo& info,
PaintInvalidationReason reason) { PaintInvalidationReason reason) {
auto bounds = info.bounds_in_layer; String debug_name;
bounds.Intersect( if (tracking_info_)
IntRect(0, 0, layer_bounds_.width(), layer_bounds_.height())); debug_name = tracking_info_->old_client_debug_names.at(&info.id.client);
raster_invalidation_function_(bounds); AddRasterInvalidation(info.bounds_in_layer, &info.id.client, reason,
&debug_name);
}
void CompositedLayerRasterInvalidator::AddRasterInvalidation(
const IntRect& rect,
const DisplayItemClient* client,
PaintInvalidationReason reason,
const String* debug_name) {
raster_invalidation_function_(rect);
if (tracking_info_) { if (tracking_info_) {
tracking_info_->tracking.AddInvalidation( tracking_info_->tracking.AddInvalidation(
&info.id.client, client, debug_name ? *debug_name : client->DebugName(), rect, reason);
tracking_info_->old_client_debug_names.at(&info.id.client),
info.bounds_in_layer, reason);
} }
} }
...@@ -245,10 +304,9 @@ void CompositedLayerRasterInvalidator::Generate( ...@@ -245,10 +304,9 @@ void CompositedLayerRasterInvalidator::Generate(
Vector<PaintChunkInfo> new_chunks_info; Vector<PaintChunkInfo> new_chunks_info;
new_chunks_info.ReserveCapacity(paint_chunks.size()); new_chunks_info.ReserveCapacity(paint_chunks.size());
for (const auto* chunk : paint_chunks) { for (const auto* chunk : paint_chunks) {
auto chunk_to_layer_transform = ChunkToLayerTransform(*chunk); new_chunks_info.push_back(PaintChunkInfo(
new_chunks_info.push_back( MapRectFromChunkToLayer(chunk->bounds, *chunk),
PaintChunkInfo(MapRectFromChunkToLayer(chunk->bounds, *chunk), ChunkToLayerTransform(*chunk), ChunkToLayerClip(*chunk), *chunk));
chunk_to_layer_transform, *chunk));
if (tracking_info_) { if (tracking_info_) {
tracking_info_->new_client_debug_names.insert( tracking_info_->new_client_debug_names.insert(
&chunk->id.client, chunk->id.client.DebugName()); &chunk->id.client, chunk->id.client.DebugName());
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CompositedLayerRasterInvalidator_h #ifndef CompositedLayerRasterInvalidator_h
#define CompositedLayerRasterInvalidator_h #define CompositedLayerRasterInvalidator_h
#include "platform/graphics/paint/FloatClipRect.h"
#include "platform/graphics/paint/PaintChunk.h" #include "platform/graphics/paint/PaintChunk.h"
#include "platform/graphics/paint/RasterInvalidationTracking.h" #include "platform/graphics/paint/RasterInvalidationTracking.h"
#include "platform/wtf/HashMap.h" #include "platform/wtf/HashMap.h"
...@@ -46,12 +47,16 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { ...@@ -46,12 +47,16 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator {
const gfx::Rect& LayerBounds() const { return layer_bounds_; } const gfx::Rect& LayerBounds() const { return layer_bounds_; }
private: private:
friend class CompositedLayerRasterInvalidatorTest;
struct PaintChunkInfo { struct PaintChunkInfo {
PaintChunkInfo(const IntRect& bounds, PaintChunkInfo(const IntRect& bounds,
const TransformationMatrix& chunk_to_layer_transform, const TransformationMatrix& chunk_to_layer_transform,
const FloatClipRect& chunk_to_layer_clip,
const PaintChunk& chunk) const PaintChunk& chunk)
: bounds_in_layer(bounds), : bounds_in_layer(bounds),
chunk_to_layer_transform(chunk_to_layer_transform), chunk_to_layer_transform(chunk_to_layer_transform),
chunk_to_layer_clip(chunk_to_layer_clip),
id(chunk.id), id(chunk.id),
is_cacheable(chunk.is_cacheable), is_cacheable(chunk.is_cacheable),
properties(chunk.properties) {} properties(chunk.properties) {}
...@@ -62,6 +67,7 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { ...@@ -62,6 +67,7 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator {
IntRect bounds_in_layer; IntRect bounds_in_layer;
TransformationMatrix chunk_to_layer_transform; TransformationMatrix chunk_to_layer_transform;
FloatClipRect chunk_to_layer_clip;
PaintChunk::Id id; PaintChunk::Id id;
bool is_cacheable; bool is_cacheable;
PaintChunkProperties properties; PaintChunkProperties properties;
...@@ -69,19 +75,37 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { ...@@ -69,19 +75,37 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator {
IntRect MapRectFromChunkToLayer(const FloatRect&, const PaintChunk&) const; IntRect MapRectFromChunkToLayer(const FloatRect&, const PaintChunk&) const;
TransformationMatrix ChunkToLayerTransform(const PaintChunk&) const; TransformationMatrix ChunkToLayerTransform(const PaintChunk&) const;
FloatClipRect ChunkToLayerClip(const PaintChunk&) const;
void GenerateRasterInvalidations( void GenerateRasterInvalidations(
const Vector<const PaintChunk*>& new_chunks, const Vector<const PaintChunk*>& new_chunks,
const Vector<PaintChunkInfo>& new_chunks_info); const Vector<PaintChunkInfo>& new_chunks_info);
size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk, size_t old_index); size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk, size_t old_index);
void AddDisplayItemRasterInvalidations(const PaintChunk&); void AddDisplayItemRasterInvalidations(const PaintChunk&);
void InvalidateRasterForNewChunk(const PaintChunkInfo&, void IncrementallyInvalidateChunk(const PaintChunkInfo& old_chunk,
const PaintChunkInfo& new_chunk);
void FullyInvalidateChunk(const PaintChunkInfo& old_chunk,
const PaintChunkInfo& new_chunk,
PaintInvalidationReason);
ALWAYS_INLINE void FullyInvalidateNewChunk(const PaintChunkInfo&,
PaintInvalidationReason); PaintInvalidationReason);
void InvalidateRasterForOldChunk(const PaintChunkInfo&, ALWAYS_INLINE void FullyInvalidateOldChunk(const PaintChunkInfo&,
PaintInvalidationReason); PaintInvalidationReason);
bool ChunkPropertiesChanged(const PaintChunkInfo& new_chunk, ALWAYS_INLINE void AddRasterInvalidation(const IntRect&,
const DisplayItemClient*,
PaintInvalidationReason,
const String* debug_name = nullptr);
PaintInvalidationReason ChunkPropertiesChanged(
const PaintChunkInfo& new_chunk,
const PaintChunkInfo& old_chunk) const; const PaintChunkInfo& old_chunk) const;
// Clip a rect in the layer space by the layer bounds.
template <typename Rect>
Rect ClipByLayerBounds(const Rect& r) const {
return Intersection(
r, Rect(0, 0, layer_bounds_.width(), layer_bounds_.height()));
}
RasterInvalidationFunction raster_invalidation_function_; RasterInvalidationFunction raster_invalidation_function_;
gfx::Rect layer_bounds_; gfx::Rect layer_bounds_;
PropertyTreeState layer_state_; PropertyTreeState layer_state_;
......
...@@ -64,42 +64,48 @@ class CompositedLayerRasterInvalidatorTest ...@@ -64,42 +64,48 @@ class CompositedLayerRasterInvalidatorTest
return EnclosingIntRect(r); return EnclosingIntRect(r);
} }
static void ExpectDisplayItemInvalidations(
const Vector<RasterInvalidationInfo>& invalidations,
size_t index,
const PaintChunk& chunk,
const IntPoint& chunk_offset_from_layer =
-kDefaultLayerBounds.Location()) {
for (size_t i = 0; i < chunk.raster_invalidation_rects.size(); ++i) {
SCOPED_TRACE(index + i);
const auto& info = invalidations[index + i];
EXPECT_EQ(ChunkRectToLayer(chunk.raster_invalidation_rects[i],
chunk_offset_from_layer),
info.rect);
EXPECT_EQ(&chunk.id.client, info.client);
EXPECT_EQ(chunk.raster_invalidation_tracking[i].reason, info.reason);
}
}
static void ExpectChunkInvalidation(
const Vector<RasterInvalidationInfo>& invalidations,
size_t index,
const PaintChunk& chunk,
PaintInvalidationReason reason,
const IntPoint& layer_offset = -kDefaultLayerBounds.Location()) {
SCOPED_TRACE(index);
const auto& info = invalidations[index];
EXPECT_EQ(ChunkRectToLayer(chunk.bounds, layer_offset), info.rect);
EXPECT_EQ(&chunk.id.client, info.client);
EXPECT_EQ(reason, info.reason);
}
CompositedLayerRasterInvalidator::RasterInvalidationFunction CompositedLayerRasterInvalidator::RasterInvalidationFunction
kNoopRasterInvalidation = [this](const IntRect& rect) {}; kNoopRasterInvalidation = [this](const IntRect& rect) {};
Vector<IntRect> raster_invalidations_; Vector<IntRect> raster_invalidations_;
}; };
#define EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, index, chunk) \
do { \
for (size_t i = 0; i < (chunk).raster_invalidation_rects.size(); ++i) { \
SCOPED_TRACE(index + i); \
const auto& info = (invalidations)[index + i]; \
EXPECT_EQ(ChunkRectToLayer((chunk).raster_invalidation_rects[i], \
-kDefaultLayerBounds.Location()), \
info.rect); \
EXPECT_EQ(&(chunk).id.client, info.client); \
EXPECT_EQ((chunk).raster_invalidation_tracking[i].reason, info.reason); \
} \
} while (false)
#define EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET( \
invalidations, index, chunk, expected_reason, layer_offset) \
do { \
const auto& info = (invalidations)[index]; \
EXPECT_EQ(ChunkRectToLayer((chunk).bounds, layer_offset), info.rect); \
EXPECT_EQ(&(chunk).id.client, info.client); \
EXPECT_EQ(expected_reason, info.reason); \
} while (false)
#define EXPECT_CHUNK_INVALIDATION(invalidations, index, chunk, reason) \
EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET( \
invalidations, index, chunk, reason, -kDefaultLayerBounds.Location())
#define EXPECT_INCREMENTAL_INVALIDATION(invalidations, index, chunk, \
chunk_rect) \
do { \
const auto& info = (invalidations)[index]; \
EXPECT_EQ(ChunkRectToLayer(chunk_rect, -kDefaultLayerBounds.Location()), \
info.rect); \
EXPECT_EQ(&(chunk).id.client, info.client); \
EXPECT_EQ(PaintInvalidationReason::kIncremental, info.reason); \
} while (false)
#define CHUNKS(name, ...) \ #define CHUNKS(name, ...) \
PaintChunk name##_array[] = {__VA_ARGS__}; \ PaintChunk name##_array[] = {__VA_ARGS__}; \
Vector<const PaintChunk*> name; \ Vector<const PaintChunk*> name; \
...@@ -125,10 +131,10 @@ TEST_F(CompositedLayerRasterInvalidatorTest, LayerBounds) { ...@@ -125,10 +131,10 @@ TEST_F(CompositedLayerRasterInvalidatorTest, LayerBounds) {
// Change of layer origin causes change of chunk0's transform to layer. // Change of layer origin causes change of chunk0's transform to layer.
const auto& invalidations = TrackedRasterInvalidations(invalidator); const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(2u, invalidations.size()); ASSERT_EQ(2u, invalidations.size());
ExpectChunkInvalidation(invalidations, 0, *chunks[0], EXPECT_CHUNK_INVALIDATION(invalidations, 0, *chunks[0],
PaintInvalidationReason::kPaintProperty); PaintInvalidationReason::kPaintProperty);
ExpectChunkInvalidation(invalidations, 1, *chunks[0], EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET(
PaintInvalidationReason::kPaintProperty, invalidations, 1, *chunks[0], PaintInvalidationReason::kPaintProperty,
-new_layer_bounds.Location()); -new_layer_bounds.Location());
} }
...@@ -150,13 +156,13 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunks) { ...@@ -150,13 +156,13 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunks) {
// CompositedLayerRasterInvalidator (which is according to the first chunk's // CompositedLayerRasterInvalidator (which is according to the first chunk's
// id). For matched chunk, we issue raster invalidations if any found by // id). For matched chunk, we issue raster invalidations if any found by
// PaintController. // PaintController.
ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, *new_chunks[0]);
ExpectDisplayItemInvalidations(invalidations, 2, *new_chunks[1]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, *new_chunks[1]);
// Invalidated new chunk 2's old (as chunks[1]) and new (as new_chunks[2]) // Invalidated new chunk 2's old (as chunks[1]) and new (as new_chunks[2])
// bounds. // bounds.
ExpectChunkInvalidation(invalidations, 6, *chunks[1], EXPECT_CHUNK_INVALIDATION(invalidations, 6, *chunks[1],
PaintInvalidationReason::kChunkReordered); PaintInvalidationReason::kChunkReordered);
ExpectChunkInvalidation(invalidations, 7, *new_chunks[2], EXPECT_CHUNK_INVALIDATION(invalidations, 7, *new_chunks[2],
PaintInvalidationReason::kChunkReordered); PaintInvalidationReason::kChunkReordered);
} }
...@@ -180,18 +186,18 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunkSubsequences) { ...@@ -180,18 +186,18 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunkSubsequences) {
// CompositedLayerRasterInvalidator (which is according to the first chunk's // CompositedLayerRasterInvalidator (which is according to the first chunk's
// id). For matched chunk, we issue raster invalidations if any found by // id). For matched chunk, we issue raster invalidations if any found by
// PaintController. // PaintController.
ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, *new_chunks[0]);
ExpectDisplayItemInvalidations(invalidations, 2, *new_chunks[1]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, *new_chunks[1]);
ExpectDisplayItemInvalidations(invalidations, 5, *new_chunks[2]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 5, *new_chunks[2]);
// Invalidated new chunk 3's old (as chunks[1]) and new (as new_chunks[3]) // Invalidated new chunk 3's old (as chunks[1]) and new (as new_chunks[3])
// bounds. // bounds.
ExpectChunkInvalidation(invalidations, 9, *chunks[1], EXPECT_CHUNK_INVALIDATION(invalidations, 9, *chunks[1],
PaintInvalidationReason::kChunkReordered); PaintInvalidationReason::kChunkReordered);
ExpectChunkInvalidation(invalidations, 10, *new_chunks[3], EXPECT_CHUNK_INVALIDATION(invalidations, 10, *new_chunks[3],
PaintInvalidationReason::kChunkReordered); PaintInvalidationReason::kChunkReordered);
// Invalidated new chunk 4's new bounds. Didn't invalidate old bounds because // Invalidated new chunk 4's new bounds. Didn't invalidate old bounds because
// it's the same as the new bounds. // it's the same as the new bounds.
ExpectChunkInvalidation(invalidations, 11, *new_chunks[4], EXPECT_CHUNK_INVALIDATION(invalidations, 11, *new_chunks[4],
PaintInvalidationReason::kChunkReordered); PaintInvalidationReason::kChunkReordered);
} }
...@@ -209,14 +215,14 @@ TEST_F(CompositedLayerRasterInvalidatorTest, AppearAndDisappear) { ...@@ -209,14 +215,14 @@ TEST_F(CompositedLayerRasterInvalidatorTest, AppearAndDisappear) {
DefaultPropertyTreeState()); DefaultPropertyTreeState());
const auto& invalidations = TrackedRasterInvalidations(invalidator); const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(6u, invalidations.size()); ASSERT_EQ(6u, invalidations.size());
ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, *new_chunks[0]);
ExpectChunkInvalidation(invalidations, 2, *new_chunks[1], EXPECT_CHUNK_INVALIDATION(invalidations, 2, *new_chunks[1],
PaintInvalidationReason::kAppeared); PaintInvalidationReason::kAppeared);
ExpectChunkInvalidation(invalidations, 3, *new_chunks[2], EXPECT_CHUNK_INVALIDATION(invalidations, 3, *new_chunks[2],
PaintInvalidationReason::kAppeared); PaintInvalidationReason::kAppeared);
ExpectChunkInvalidation(invalidations, 4, *chunks[1], EXPECT_CHUNK_INVALIDATION(invalidations, 4, *chunks[1],
PaintInvalidationReason::kDisappeared); PaintInvalidationReason::kDisappeared);
ExpectChunkInvalidation(invalidations, 5, *chunks[2], EXPECT_CHUNK_INVALIDATION(invalidations, 5, *chunks[2],
PaintInvalidationReason::kDisappeared); PaintInvalidationReason::kDisappeared);
} }
...@@ -232,10 +238,10 @@ TEST_F(CompositedLayerRasterInvalidatorTest, AppearAtEnd) { ...@@ -232,10 +238,10 @@ TEST_F(CompositedLayerRasterInvalidatorTest, AppearAtEnd) {
DefaultPropertyTreeState()); DefaultPropertyTreeState());
const auto& invalidations = TrackedRasterInvalidations(invalidator); const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(4u, invalidations.size()); ASSERT_EQ(4u, invalidations.size());
ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, *new_chunks[0]);
ExpectChunkInvalidation(invalidations, 2, *new_chunks[1], EXPECT_CHUNK_INVALIDATION(invalidations, 2, *new_chunks[1],
PaintInvalidationReason::kAppeared); PaintInvalidationReason::kAppeared);
ExpectChunkInvalidation(invalidations, 3, *new_chunks[2], EXPECT_CHUNK_INVALIDATION(invalidations, 3, *new_chunks[2],
PaintInvalidationReason::kAppeared); PaintInvalidationReason::kAppeared);
} }
...@@ -253,18 +259,22 @@ TEST_F(CompositedLayerRasterInvalidatorTest, UncacheableChunks) { ...@@ -253,18 +259,22 @@ TEST_F(CompositedLayerRasterInvalidatorTest, UncacheableChunks) {
DefaultPropertyTreeState()); DefaultPropertyTreeState());
const auto& invalidations = TrackedRasterInvalidations(invalidator); const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(7u, invalidations.size()); ASSERT_EQ(7u, invalidations.size());
ExpectDisplayItemInvalidations(invalidations, 0, *new_chunks[0]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, *new_chunks[0]);
ExpectDisplayItemInvalidations(invalidations, 2, *new_chunks[1]); EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, *new_chunks[1]);
ExpectChunkInvalidation(invalidations, 5, *new_chunks[2], EXPECT_CHUNK_INVALIDATION(invalidations, 5, *new_chunks[2],
PaintInvalidationReason::kChunkUncacheable); PaintInvalidationReason::kChunkUncacheable);
ExpectChunkInvalidation(invalidations, 6, *chunks[1], EXPECT_CHUNK_INVALIDATION(invalidations, 6, *chunks[1],
PaintInvalidationReason::kChunkUncacheable); PaintInvalidationReason::kChunkUncacheable);
} }
TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChange) { // Tests the path based on ClipPaintPropertyNode::Changed().
TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChangeRounded) {
CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation);
CHUNKS(chunks, Chunk(0), Chunk(1), Chunk(2)); CHUNKS(chunks, Chunk(0), Chunk(1), Chunk(2));
FloatRoundedRect clip_rect(-100000, -100000, 200000, 200000); FloatRoundedRect::Radii radii(FloatSize(1, 2), FloatSize(2, 3),
FloatSize(3, 4), FloatSize(4, 5));
FloatRoundedRect clip_rect(FloatRect(-1000, -1000, 2000, 2000), radii);
LOG(ERROR) << "new_clip_rect: " << clip_rect.ToString();
scoped_refptr<ClipPaintPropertyNode> clip0 = ClipPaintPropertyNode::Create( scoped_refptr<ClipPaintPropertyNode> clip0 = ClipPaintPropertyNode::Create(
ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(),
clip_rect); clip_rect);
...@@ -279,29 +289,33 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChange) { ...@@ -279,29 +289,33 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChange) {
PropertyTreeState(TransformPaintPropertyNode::Root(), clip2.get(), PropertyTreeState(TransformPaintPropertyNode::Root(), clip2.get(),
EffectPaintPropertyNode::Root())); EffectPaintPropertyNode::Root()));
GeometryMapperClipCache::ClearCache();
invalidator.SetTracksRasterInvalidations(true); invalidator.SetTracksRasterInvalidations(true);
invalidator.Generate(kDefaultLayerBounds, chunks, layer_state); invalidator.Generate(kDefaultLayerBounds, chunks, layer_state);
EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
// Change both clip0 and clip2. // Change both clip0 and clip2.
LOG(ERROR) << "22222222222222222222222222222222222222222222";
CHUNKS(new_chunks, Chunk(0), Chunk(1), Chunk(2)); CHUNKS(new_chunks, Chunk(0), Chunk(1), Chunk(2));
FloatRoundedRect new_clip_rect(-200000, -200000, 400000, 400000); FloatRoundedRect new_clip_rect(FloatRect(-2000, -2000, 4000, 4000), radii);
LOG(ERROR) << "new_clip_rect: " << new_clip_rect.ToString();
clip0->Update(clip0->Parent(), clip0->LocalTransformSpace(), new_clip_rect); clip0->Update(clip0->Parent(), clip0->LocalTransformSpace(), new_clip_rect);
clip2->Update(clip2->Parent(), clip2->LocalTransformSpace(), new_clip_rect); clip2->Update(clip2->Parent(), clip2->LocalTransformSpace(), new_clip_rect);
new_chunks_array[0].properties = chunks[0]->properties; new_chunks_array[0].properties = chunks[0]->properties;
new_chunks_array[1].properties = chunks[1]->properties; new_chunks_array[1].properties = chunks[1]->properties;
new_chunks_array[2].properties = chunks[2]->properties; new_chunks_array[2].properties = chunks[2]->properties;
GeometryMapperTransformCache::ClearCache(); GeometryMapperClipCache::ClearCache();
invalidator.Generate(kDefaultLayerBounds, new_chunks, layer_state); invalidator.Generate(kDefaultLayerBounds, new_chunks, layer_state);
const auto& invalidations = TrackedRasterInvalidations(invalidator); const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(1u, invalidations.size()); ASSERT_EQ(1u, invalidations.size());
// Property change in the layer state should not trigger raster invalidation. // Property change in the layer state should not trigger raster invalidation.
// |clip2| change should trigger raster invalidation. // |clip2| change should trigger raster invalidation.
ExpectChunkInvalidation(invalidations, 0, *new_chunks[2], EXPECT_CHUNK_INVALIDATION(invalidations, 0, *new_chunks[2],
PaintInvalidationReason::kPaintProperty); PaintInvalidationReason::kPaintProperty);
invalidator.SetTracksRasterInvalidations(false); invalidator.SetTracksRasterInvalidations(false);
clip2->ClearChangedToRoot(); clip2->ClearChangedToRoot();
LOG(ERROR) << "333333333333333333333333333333333333333333333";
// Change chunk1's properties to use a different property tree state. // Change chunk1's properties to use a different property tree state.
CHUNKS(new_chunks1, Chunk(0), Chunk(1), Chunk(2)); CHUNKS(new_chunks1, Chunk(0), Chunk(1), Chunk(2));
...@@ -309,15 +323,103 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChange) { ...@@ -309,15 +323,103 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChange) {
new_chunks1_array[1].properties = chunks[2]->properties; new_chunks1_array[1].properties = chunks[2]->properties;
new_chunks1_array[2].properties = chunks[2]->properties; new_chunks1_array[2].properties = chunks[2]->properties;
GeometryMapperClipCache::ClearCache();
invalidator.SetTracksRasterInvalidations(true); invalidator.SetTracksRasterInvalidations(true);
invalidator.Generate(kDefaultLayerBounds, new_chunks1, layer_state); invalidator.Generate(kDefaultLayerBounds, new_chunks1, layer_state);
const auto& invalidations1 = TrackedRasterInvalidations(invalidator); const auto& invalidations1 = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(1u, invalidations1.size()); ASSERT_EQ(1u, invalidations1.size());
ExpectChunkInvalidation(invalidations1, 0, *new_chunks1[1], EXPECT_CHUNK_INVALIDATION(invalidations1, 0, *new_chunks1[1],
PaintInvalidationReason::kPaintProperty); PaintInvalidationReason::kPaintProperty);
invalidator.SetTracksRasterInvalidations(false); invalidator.SetTracksRasterInvalidations(false);
} }
// Tests the path detecting change of PaintChunkInfo::chunk_to_layer_clip.
TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChangeSimple) {
CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation);
CHUNKS(chunks, Chunk(0), Chunk(1));
FloatRoundedRect clip_rect(-1000, -1000, 2000, 2000);
scoped_refptr<ClipPaintPropertyNode> clip0 = ClipPaintPropertyNode::Create(
ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(),
clip_rect);
scoped_refptr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::Create(
clip0, TransformPaintPropertyNode::Root(), clip_rect);
PropertyTreeState layer_state = PropertyTreeState::Root();
chunks_array[0].properties = PaintChunkProperties(
PropertyTreeState(TransformPaintPropertyNode::Root(), clip0.get(),
EffectPaintPropertyNode::Root()));
chunks_array[0].bounds = clip_rect.Rect();
chunks_array[1].properties = PaintChunkProperties(
PropertyTreeState(TransformPaintPropertyNode::Root(), clip1.get(),
EffectPaintPropertyNode::Root()));
chunks_array[1].bounds = clip_rect.Rect();
GeometryMapperClipCache::ClearCache();
invalidator.SetTracksRasterInvalidations(true);
invalidator.Generate(kDefaultLayerBounds, chunks, layer_state);
EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
// Change clip1 to bigger, which is still bound by clip0, resulting no actual
// visual change.
CHUNKS(new_chunks1, Chunk(0), Chunk(1));
FloatRoundedRect new_clip_rect1(-2000, -2000, 4000, 4000);
clip1->Update(clip1->Parent(), clip1->LocalTransformSpace(), new_clip_rect1);
new_chunks1_array[0].properties = chunks[0]->properties;
new_chunks1_array[0].bounds = chunks[0]->bounds;
new_chunks1_array[1].properties = chunks[1]->properties;
new_chunks1_array[1].bounds = chunks[1]->bounds;
GeometryMapperClipCache::ClearCache();
invalidator.Generate(kDefaultLayerBounds, new_chunks1, layer_state);
EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty());
clip1->ClearChangedToRoot();
// Change clip1 to smaller.
CHUNKS(new_chunks2, Chunk(0), Chunk(1));
FloatRoundedRect new_clip_rect2(-500, -500, 1000, 1000);
clip1->Update(clip1->Parent(), clip1->LocalTransformSpace(), new_clip_rect2);
new_chunks2_array[0].properties = chunks[0]->properties;
new_chunks2_array[0].bounds = chunks[0]->bounds;
new_chunks2_array[1].properties = chunks[1]->properties;
new_chunks2_array[1].bounds = new_clip_rect2.Rect();
GeometryMapperClipCache::ClearCache();
invalidator.Generate(kDefaultLayerBounds, new_chunks2, layer_state);
const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(4u, invalidations.size());
// |clip1| change should trigger incremental raster invalidation.
EXPECT_INCREMENTAL_INVALIDATION(invalidations, 0, *new_chunks2[1],
IntRect(-1000, -1000, 2000, 500));
EXPECT_INCREMENTAL_INVALIDATION(invalidations, 1, *new_chunks2[1],
IntRect(-1000, -500, 500, 1000));
EXPECT_INCREMENTAL_INVALIDATION(invalidations, 2, *new_chunks2[1],
IntRect(500, -500, 500, 1000));
EXPECT_INCREMENTAL_INVALIDATION(invalidations, 3, *new_chunks2[1],
IntRect(-1000, 500, 2000, 500));
invalidator.SetTracksRasterInvalidations(false);
clip1->ClearChangedToRoot();
// Change clip1 bigger at one side.
CHUNKS(new_chunks3, Chunk(0), Chunk(1));
FloatRoundedRect new_clip_rect3(-500, -500, 2000, 1000);
clip1->Update(clip1->Parent(), clip1->LocalTransformSpace(), new_clip_rect3);
new_chunks3_array[0].properties = chunks[0]->properties;
new_chunks3_array[0].bounds = chunks[0]->bounds;
new_chunks3_array[1].properties = chunks[1]->properties;
new_chunks3_array[1].bounds = new_clip_rect3.Rect();
GeometryMapperClipCache::ClearCache();
invalidator.SetTracksRasterInvalidations(true);
invalidator.Generate(kDefaultLayerBounds, new_chunks3, layer_state);
const auto& invalidations1 = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(1u, invalidations1.size());
// |clip1| change should trigger incremental raster invalidation.
EXPECT_INCREMENTAL_INVALIDATION(invalidations1, 0, *new_chunks3[1],
IntRect(500, -500, 500, 1000));
invalidator.SetTracksRasterInvalidations(false);
clip1->ClearChangedToRoot();
}
TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyChange) { TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyChange) {
CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation);
CHUNKS(chunks, Chunk(0), Chunk(1)); CHUNKS(chunks, Chunk(0), Chunk(1));
...@@ -408,10 +510,12 @@ TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyChange) { ...@@ -408,10 +510,12 @@ TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyChange) {
invalidator.Generate(kDefaultLayerBounds, new_chunks3, layer_state); invalidator.Generate(kDefaultLayerBounds, new_chunks3, layer_state);
const auto& invalidations = TrackedRasterInvalidations(invalidator); const auto& invalidations = TrackedRasterInvalidations(invalidator);
ASSERT_EQ(2u, invalidations.size()); ASSERT_EQ(2u, invalidations.size());
ExpectChunkInvalidation(invalidations, 0, *new_chunks3[0], EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET(
invalidations, 0, *new_chunks3[0],
PaintInvalidationReason::kPaintProperty, PaintInvalidationReason::kPaintProperty,
-kDefaultLayerBounds.Location() + IntSize(10, 20)); -kDefaultLayerBounds.Location() + IntSize(10, 20));
ExpectChunkInvalidation(invalidations, 1, *new_chunks3[0], EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET(
invalidations, 1, *new_chunks3[0],
PaintInvalidationReason::kPaintProperty, PaintInvalidationReason::kPaintProperty,
-kDefaultLayerBounds.Location() + IntSize(30, 50)); -kDefaultLayerBounds.Location() + IntSize(30, 50));
invalidator.SetTracksRasterInvalidations(false); invalidator.SetTracksRasterInvalidations(false);
......
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