| <!-- Generated by third_party/blink/tools/run_blinkpy_tests.py |
| test case: TestRepaintOverlay.test_generate_repaint_overlay_html. --> |
| <!DOCTYPE HTML> |
| <html> |
| <head> |
| <title>paint/invalidation/repaint-overlay/layers.html</title> |
| <style> |
| body { |
| margin: 0; |
| padding: 0; |
| } |
| #overlay { |
| width: 2000px; |
| height: 2000px; |
| border: 1px solid black; |
| } |
| #test_frame { |
| position: absolute; |
| width: 800px; |
| height: 600px; |
| border: 0; |
| display: none; |
| } |
| canvas { |
| position: absolute; |
| } |
| #actual_canvas { |
| display: none; |
| } |
| </style> |
| </head> |
| <body> |
| <label><input id="show-test" type="checkbox" onchange="toggle_test(this.checked)">Show test</label> |
| <label><input id="use-solid-colors" type="checkbox" onchange="toggle_solid_color(this.checked)">Use solid colors</label> |
| <br> |
| <span id="overlay_type">Expected Invalidations</span> |
| <div id="overlay"> |
| <iframe id="test_frame"></iframe> |
| <canvas id="expected_canvas" width="2000" height="2000"></canvas> |
| <canvas id="actual_canvas" width="2000" height="2000"></canvas> |
| </div> |
| <script> |
| var overlay_opacity = 0.25; |
| |
| function toggle_test(show_test) { |
| test_frame.style.display = show_test ? 'block' : 'none'; |
| if (!test_frame.src) |
| test_frame.src = decodeURIComponent(location.search).substr(1); |
| } |
| |
| function toggle_solid_color(use_solid_color) { |
| overlay_opacity = use_solid_color ? 1 : 0.25; |
| draw_repaint_rects(); |
| } |
| |
| var expected = { |
| "layers": [ |
| { |
| "name": "Scrolling Contents Layer", |
| "bounds": [800, 2016], |
| "contentsOpaque": true, |
| "backgroundColor": "#FFFFFF", |
| "transform": 1 |
| }, |
| { |
| "name": "LayoutNGBlockFlow (positioned) DIV id='container'", |
| "bounds": [100, 100], |
| "backgroundColor": "#0000FF80", |
| "invalidations": [ |
| [20, 20, 10, 10] |
| ], |
| "transform": 2 |
| }, |
| { |
| "name": "LayoutNGBlockFlow (relative positioned) DIV id='scrollable'", |
| "bounds": [302, 302], |
| "transform": 3 |
| }, |
| { |
| "name": "Horizontal Scrollbar Layer", |
| "position": [1, 301], |
| "bounds": [300, 0], |
| "transform": 3 |
| }, |
| { |
| "name": "Vertical Scrollbar Layer", |
| "position": [301, 1], |
| "bounds": [0, 300], |
| "transform": 3 |
| }, |
| { |
| "name": "LayoutNGBlockFlow (relative positioned) DIV id='transform'", |
| "bounds": [200, 200], |
| "contentsOpaque": true, |
| "backgroundColor": "#FFFF00", |
| "invalidations": [ |
| [20, 20, 10, 10] |
| ], |
| "transform": 6 |
| }, |
| { |
| "name": "Vertical Scrollbar Layer", |
| "position": [800, 0], |
| "bounds": [0, 600] |
| } |
| ], |
| "transforms": [ |
| { |
| "id": 1, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [0, -20, 0, 1] |
| ] |
| }, |
| { |
| "id": 2, |
| "parent": 1, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [40, 50, 0, 1] |
| ] |
| }, |
| { |
| "id": 3, |
| "parent": 2, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [64, 53, 0, 1] |
| ] |
| }, |
| { |
| "id": 4, |
| "parent": 3, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [0, -30, 0, 1] |
| ] |
| }, |
| { |
| "id": 5, |
| "parent": 4, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [89, 78, 0, 1] |
| ] |
| }, |
| { |
| "id": 6, |
| "parent": 5, |
| "transform": [ |
| [3.53553390593274, 3.53553390593274, 0, 0], |
| [-3.53553390593274, 3.53553390593274, 0, 0], |
| [0, 0, 1, 0], |
| [0, 0, 0, 1] |
| ], |
| "origin": [0, 0] |
| } |
| ] |
| } |
| ; |
| var actual = { |
| "layers": [ |
| { |
| "name": "Scrolling Contents Layer", |
| "bounds": [800, 2016], |
| "contentsOpaque": true, |
| "backgroundColor": "#FFFFFF", |
| "transform": 1 |
| }, |
| { |
| "name": "LayoutNGBlockFlow (positioned) DIV id='container'", |
| "bounds": [100, 100], |
| "backgroundColor": "#0000FF80", |
| "invalidations": [ |
| [20, 20, 10, 10] |
| ], |
| "transform": 2 |
| }, |
| { |
| "name": "LayoutNGBlockFlow (relative positioned) DIV id='scrollable'", |
| "bounds": [302, 302], |
| "transform": 3 |
| }, |
| { |
| "name": "Horizontal Scrollbar Layer", |
| "position": [1, 301], |
| "bounds": [300, 0], |
| "transform": 3 |
| }, |
| { |
| "name": "Vertical Scrollbar Layer", |
| "position": [301, 1], |
| "bounds": [0, 300], |
| "transform": 3 |
| }, |
| { |
| "name": "LayoutNGBlockFlow (relative positioned) DIV id='transform'", |
| "bounds": [200, 200], |
| "contentsOpaque": true, |
| "backgroundColor": "#FFFF00", |
| "invalidations": [ |
| [20, 20, 10, 10] |
| ], |
| "transform": 6 |
| }, |
| { |
| "name": "Vertical Scrollbar Layer", |
| "position": [800, 0], |
| "bounds": [0, 600] |
| } |
| ], |
| "transforms": [ |
| { |
| "id": 1, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [0, -20, 0, 1] |
| ] |
| }, |
| { |
| "id": 2, |
| "parent": 1, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [40, 50, 0, 1] |
| ] |
| }, |
| { |
| "id": 3, |
| "parent": 2, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [64, 53, 0, 1] |
| ] |
| }, |
| { |
| "id": 4, |
| "parent": 3, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [0, -30, 0, 1] |
| ] |
| }, |
| { |
| "id": 5, |
| "parent": 4, |
| "transform": [ |
| [1, 0, 0, 0], |
| [0, 1, 0, 0], |
| [0, 0, 1, 0], |
| [89, 78, 0, 1] |
| ] |
| }, |
| { |
| "id": 6, |
| "parent": 5, |
| "transform": [ |
| [3.53553390593274, 3.53553390593274, 0, 0], |
| [-3.53553390593274, 3.53553390593274, 0, 0], |
| [0, 0, 1, 0], |
| [0, 0, 0, 1] |
| ], |
| "origin": [0, 0] |
| } |
| ] |
| } |
| ; |
| |
| function draw_rects(context, rects) { |
| for (var i = 0; i < rects.length; ++i) { |
| var rect = rects[i]; |
| context.fillRect(rect[0], rect[1], rect[2], rect[3]); |
| } |
| } |
| |
| function draw_layer_rects(context, transforms, layer) { |
| context.save(); |
| var transform_path = []; |
| for (var id = layer.transform; id; id = transforms[id].parent) |
| transform_path.push(transforms[id]); |
| |
| for (var i = transform_path.length - 1; i >= 0; i--) { |
| var m = transform_path[i].transform; |
| if (!m) |
| continue; |
| var origin = transform_path[i].origin; |
| if (origin) |
| context.translate(origin[0], origin[1]); |
| context.transform(m[0][0], m[0][1], m[1][0], m[1][1], m[3][0], m[3][1]); |
| if (origin) |
| context.translate(-origin[0], -origin[1]); |
| } |
| if (layer.position) |
| context.translate(layer.position[0], layer.position[1]); |
| if (layer.invalidations) |
| draw_rects(context, layer.invalidations); |
| context.restore(); |
| } |
| |
| function draw_result_rects(context, result) { |
| var transforms = {}; |
| if (result.transforms) { |
| for (var i = 0; i < result.transforms.length; ++i) { |
| var transform = result.transforms[i]; |
| transforms[transform.id] = transform; |
| } |
| } |
| if (result.layers) { |
| for (var i = 0; i < result.layers.length; ++i) |
| draw_layer_rects(context, transforms, result.layers[i]); |
| } |
| } |
| |
| function draw_repaint_rects() { |
| var expected_ctx = expected_canvas.getContext("2d"); |
| expected_ctx.clearRect(0, 0, 2000, 2000); |
| expected_ctx.fillStyle = 'rgba(255, 0, 0, ' + overlay_opacity + ')'; |
| draw_result_rects(expected_ctx, expected); |
| |
| var actual_ctx = actual_canvas.getContext("2d"); |
| actual_ctx.clearRect(0, 0, 2000, 2000); |
| actual_ctx.fillStyle = 'rgba(0, 255, 0, ' + overlay_opacity + ')'; |
| draw_result_rects(actual_ctx, actual); |
| } |
| |
| draw_repaint_rects(); |
| |
| var expected_showing = true; |
| function flip() { |
| if (expected_showing) { |
| overlay_type.textContent = 'Actual Invalidations'; |
| expected_canvas.style.display = 'none'; |
| actual_canvas.style.display = 'block'; |
| } else { |
| overlay_type.textContent = 'Expected Invalidations'; |
| actual_canvas.style.display = 'none'; |
| expected_canvas.style.display = 'block'; |
| } |
| expected_showing = !expected_showing |
| } |
| setInterval(flip, 1500); |
| </script> |
| </body> |
| </html> |