1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
8 def result_contains_repaint_rects(text):
9 return isinstance(text, str) and (
10 re.search('"repaintRects": \[$', text, re.MULTILINE) != None or
11 text.find('Minimum repaint:') != -1)
14 def extract_layer_tree(input_str):
15 if not isinstance(input_str, str):
18 if input_str[0:2] == '{\n':
21 start = input_str.find('\n{\n')
25 end = input_str.find('\n}\n', start)
29 # FIXME: There may be multiple layer trees in the result.
30 return input_str[start:end + 3]
33 def generate_repaint_overlay_html(test_name, actual_text, expected_text):
34 if not result_contains_repaint_rects(actual_text) and not result_contains_repaint_rects(expected_text):
37 expected_layer_tree = extract_layer_tree(expected_text)
38 actual_layer_tree = extract_layer_tree(actual_text)
40 minimum_repaint = '[]'
41 minimum_repaint_match = re.search('Minimum repaint:\n(\[.*\n\])', actual_text, re.DOTALL)
42 if minimum_repaint_match:
43 minimum_repaint = minimum_repaint_match.group(1)
45 return """<!DOCTYPE HTML>
48 <title>%(title)s</title>
67 #actual, #minimum-repaint {
73 <a href="http://crbug.com/381221">Known issues</a><br>
74 <label><input id="show-test" type="checkbox" checked onchange="toggle_test(this.checked)">Show test</label>
75 <label title="See fast/repaint/resources/text-based-repaint.js for how this works">
76 <input id="show-minimum-repaint" type="checkbox" onchange="toggle_minimum_repaint(this.checked)">Minimum repaint
78 <label><input id="use-solid-colors" type="checkbox" onchange="toggle_solid_color(this.checked)">Use solid colors</label>
80 <button title="See fast/repaint/resources/text-based-repaint.js for how this works" onclick="highlight_under_repaint()">
81 Highlight under-repaint
84 <span id='type'>Expected Invalidations</span>
86 <canvas id='minimum-repaint' width='2000' height='2000'></canvas>
87 <canvas id='expected' width='2000' height='2000'></canvas>
88 <canvas id='actual' width='2000' height='2000'></canvas>
91 var overlay_opacity = 0.25;
93 function toggle_test(show_test) {
94 iframe.style.display = show_test ? 'block' : 'none';
97 function toggle_minimum_repaint(show_minimum_repaint) {
98 document.getElementById('minimum-repaint').style.display = show_minimum_repaint ? 'block' : 'none';
101 function toggle_solid_color(use_solid_color) {
102 overlay_opacity = use_solid_color ? 1 : 0.25;
103 draw_repaint_rects();
104 draw_minimum_repaint();
107 function highlight_under_repaint() {
108 document.getElementById('show-test').checked = false;
110 document.getElementById('show-minimum-repaint').checked = true;
111 toggle_minimum_repaint(true);
112 document.getElementById('use-solid-colors').checked = true;
113 toggle_solid_color(true);
116 var expected = %(expected)s;
117 var actual = %(actual)s;
118 var minimum_repaint = %(minimum_repaint)s;
120 function rectsEqual(rect1, rect2) {
121 return rect1[0] == rect2[0] && rect1[1] == rect2[1] && rect1[2] == rect2[2] && rect1[3] == rect2[3];
124 function draw_rects(context, rects) {
125 for (var i = 0; i < rects.length; ++i) {
127 context.fillRect(rect[0], rect[1], rect[2], rect[3]);
131 function draw_layer_rects(context, result) {
134 context.translate(result.position[0], result.position[1]);
135 var t = result.transform;
137 var origin = result.transformOrigin || [result.bounds[0] / 2, result.bounds[1] / 2];
138 context.translate(origin[0], origin[1]);
139 context.transform(t[0][0], t[0][1], t[1][0], t[1][1], t[3][0], t[3][1]);
140 context.translate(-origin[0], -origin[1]);
142 if (result.repaintRects)
143 draw_rects(context, result.repaintRects);
144 if (result.children) {
145 for (var i = 0; i < result.children.length; ++i)
146 draw_layer_rects(context, result.children[i]);
151 var expected_canvas = document.getElementById('expected');
152 var actual_canvas = document.getElementById('actual');
153 var minimum_repaint_canvas = document.getElementById('minimum-repaint');
155 function draw_repaint_rects() {
156 var expected_ctx = expected_canvas.getContext("2d");
157 expected_ctx.clearRect(0, 0, 2000, 2000);
158 expected_ctx.fillStyle = 'rgba(255, 0, 0, ' + overlay_opacity + ')';
159 draw_layer_rects(expected_ctx, expected);
161 var actual_ctx = actual_canvas.getContext("2d");
162 actual_ctx.clearRect(0, 0, 2000, 2000);
163 actual_ctx.fillStyle = 'rgba(0, 255, 0, ' + overlay_opacity + ')';
164 draw_layer_rects(actual_ctx, actual);
167 function draw_minimum_repaint() {
168 var context = minimum_repaint_canvas.getContext("2d");
169 context.fillStyle = 'rgba(0, 0, 0, 1)';
170 draw_rects(context, minimum_repaint);
173 draw_repaint_rects();
174 draw_minimum_repaint();
176 var path = decodeURIComponent(location.search).substr(1);
177 var iframe = document.createElement('iframe');
178 iframe.id = 'test-frame';
183 var overlay = document.getElementById('overlay');
184 overlay.appendChild(iframe);
186 var type = document.getElementById('type');
187 var expected_showing = true;
189 if (expected_showing) {
190 type.textContent = 'Actual Invalidations';
191 expected_canvas.style.display = 'none';
192 actual_canvas.style.display = 'block';
194 type.textContent = 'Expected Invalidations';
195 actual_canvas.style.display = 'none';
196 expected_canvas.style.display = 'block';
198 expected_showing = !expected_showing
200 setInterval(flip, 3000);
206 'expected': expected_layer_tree,
207 'actual': actual_layer_tree,
208 'minimum_repaint': minimum_repaint,