aedc5208c7430a90828c2d18684a27cb9e7b681b
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Tools / Scripts / webkitpy / layout_tests / controllers / repaint_overlay.py
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.
4
5 import re
6
7
8 def result_contains_repaint_rects(text):
9     return isinstance(text, str) and re.search('^\s*\(repaint rects$', text, re.MULTILINE) != None
10
11
12 def generate_repaint_overlay_html(test_name, actual_text, expected_text):
13     if not result_contains_repaint_rects(expected_text):
14         return ''
15
16     def make_js_rect(input_str):
17         rect_pattern = '\(rect\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\)'
18         rects = []
19         for m in re.finditer(rect_pattern, input_str):
20             rects.append('[' + ','.join(m.groups()) + ']')
21         return '[' + ','.join(rects) + ']'
22
23     # FIXME: Need to consider layer offset and transforms.
24     expected_rects = make_js_rect(expected_text)
25     actual_rects = make_js_rect(actual_text)
26
27     minimum_repaint = '[]'
28     minimum_repaint_match = re.search('Minimum repaint:\n(\[.*\n\])', actual_text, re.DOTALL)
29     if minimum_repaint_match:
30         minimum_repaint = minimum_repaint_match.group(1)
31
32     return """<!DOCTYPE HTML>
33 <html>
34 <head>
35 <title>%(title)s</title>
36 <style>
37     body {
38         margin: 0;
39         padding: 0;
40     }
41     iframe {
42       position: absolute;
43       top: 80px;
44       left: 0;
45       border: 0;
46       z-index: -1;
47     }
48     canvas {
49       position: absolute;
50       top: 80px;
51       left: 0;
52       z-index: 1;
53     }
54     #actual, #minimum-repaint {
55       display: none;
56     }
57     #dump {
58       position: absolute;
59       top: 80px;
60       left: 0;
61       z-index: 2;
62       display: none;
63     }
64 </style>
65 </head>
66 <body>
67 <a href="http://crbug.com/381221">Known issues (layer transformations, layer offsets, etc.)</a><br>
68 <label><input id="show-test" type="checkbox" checked onchange="toggle_test(this.checked)">Show test</label>
69 <label><input id="show-diff-only" type="checkbox" checked onchange="toggle_diff_only(this.checked)">Diffs only</label>
70 <label><input type="checkbox" checked onchange="toggle_hide_duplicate_rects(this.checked)">Hide duplicate rects</label>
71 <label><input type="checkbox" onchange="toggle_dump_rects(this.checked)">Dump rects</label>
72 <label title="See fast/repaint/resources/text-based-repaint.js for how this works">
73     <input id="show-minimum-repaint" type="checkbox" onchange="toggle_minimum_repaint(this.checked)">Minimum repaint
74 </label>
75 <label><input id="use-solid-colors" type="checkbox" onchange="toggle_solid_color(this.checked)">Use solid colors</label>
76 <br>
77 <button title="See fast/repaint/resources/text-based-repaint.js for how this works" onclick="highlight_under_repaint()">
78     Highlight under-repaint
79 </button>
80 <br>
81 <span id='type'>Expected Invalidations</span>
82 <div id=overlay>
83     <canvas id='minimum-repaint' width='2000' height='2000'></canvas>
84     <canvas id='expected' width='2000' height='2000'></canvas>
85     <canvas id='actual' width='2000' height='2000'></canvas>
86     <pre id='dump'></pre>
87 </div>
88 <script>
89 var show_diff_only = true;
90 var hide_duplicate_rects = true;
91 var overlay_opacity = 0.25;
92
93 function toggle_test(show_test) {
94     iframe.style.display = show_test ? 'block' : 'none';
95 }
96
97 function toggle_diff_only(new_show_diff_only) {
98     show_diff_only = new_show_diff_only;
99     draw_repaint_rects();
100 }
101
102 function toggle_hide_duplicate_rects(new_hide_duplicate_rects) {
103     hide_duplicate_rects = new_hide_duplicate_rects;
104     draw_repaint_rects();
105 }
106
107 function toggle_dump_rects(dump_rects) {
108     document.getElementById('dump').style.display = dump_rects ? 'block' : 'none';
109 }
110
111 function toggle_minimum_repaint(show_minimum_repaint) {
112     document.getElementById('minimum-repaint').style.display = show_minimum_repaint ? 'block' : 'none';
113 }
114
115 function toggle_solid_color(use_solid_color) {
116     overlay_opacity = use_solid_color ? 1 : 0.25;
117     draw_repaint_rects();
118     draw_minimum_repaint();
119 }
120
121 function highlight_under_repaint() {
122     document.getElementById('show-test').checked = false;
123     toggle_test(false);
124     document.getElementById('show-diff-only').checked = false;
125     show_diff_only = false;
126     document.getElementById('show-minimum-repaint').checked = true;
127     toggle_minimum_repaint(true);
128     document.getElementById('use-solid-colors').checked = true;
129     toggle_solid_color(true);
130 }
131
132 var original_expected_rects = %(expected_rects)s;
133 var original_actual_rects = %(actual_rects)s;
134 var minimum_repaint = %(minimum_repaint)s;
135
136 function rectsEqual(rect1, rect2) {
137     return rect1[0] == rect2[0] && rect1[1] == rect2[1] && rect1[2] == rect2[2] && rect1[3] == rect2[3];
138 }
139
140 function findDifference(rects1, rects2) {
141     for (var i = rects1.length - 1; i >= 0; i--) {
142         for (var k = rects2.length - 1; k >= 0; k--) {
143             if (rectsEqual(rects1[i], rects2[k])) {
144                 rects1.splice(i, 1);
145                 rects2.splice(k, 1);
146                 break;
147             }
148         }
149     }
150 }
151
152 function removeDuplicateRects(rects) {
153     for (var i = rects.length - 1; i > 0; i--) {
154         for (var k = i - 1; k >= 0; k--) {
155             if (rectsEqual(rects[i], rects[k])) {
156                 rects.splice(i, 1);
157                 break;
158             }
159         }
160     }
161 }
162
163 function draw_rects(context, rects) {
164     context.clearRect(0, 0, 2000, 2000);
165     for (var i = 0; i < rects.length; i++) {
166         var rect = rects[i];
167         context.fillRect(rect[0], rect[1], rect[2], rect[3]);
168     }
169 }
170
171 var expected_canvas = document.getElementById('expected');
172 var actual_canvas = document.getElementById('actual');
173 var minimum_repaint_canvas = document.getElementById('minimum-repaint');
174
175 function dump_rects(rects) {
176     var result = '';
177     for (var i = 0; i < rects.length; i++)
178         result += '(' + rects[i].toString() + ')\\n';
179     return result;
180 }
181
182 function draw_repaint_rects() {
183     var expected_rects = original_expected_rects.slice(0);
184     var actual_rects = original_actual_rects.slice(0);
185
186     if (hide_duplicate_rects) {
187         removeDuplicateRects(expected_rects);
188         removeDuplicateRects(actual_rects);
189     }
190
191     if (show_diff_only)
192         findDifference(expected_rects, actual_rects);
193
194     document.getElementById('dump').textContent =
195         'Expected:\\n' + dump_rects(expected_rects)
196         + '\\nActual:\\n' + dump_rects(actual_rects)
197         + '\\nMinimal:\\n' + dump_rects(minimum_repaint);
198
199     var expected_ctx = expected_canvas.getContext("2d");
200     expected_ctx.fillStyle = 'rgba(255, 0, 0, ' + overlay_opacity + ')';
201     draw_rects(expected_ctx, expected_rects);
202
203     var actual_ctx = actual_canvas.getContext("2d");
204     actual_ctx.fillStyle = 'rgba(0, 255, 0, ' + overlay_opacity + ')';
205     draw_rects(actual_ctx, actual_rects);
206 }
207
208 function draw_minimum_repaint() {
209     var context = minimum_repaint_canvas.getContext("2d");
210     context.fillStyle = 'rgba(0, 0, 0, 1)';
211     draw_rects(context, minimum_repaint);
212 }
213
214 draw_repaint_rects();
215 draw_minimum_repaint();
216
217 var path = decodeURIComponent(location.search).substr(1);
218 var iframe = document.createElement('iframe');
219 iframe.id = 'test-frame';
220 iframe.width = 800;
221 iframe.height = 600;
222 iframe.src = path;
223
224 var overlay = document.getElementById('overlay');
225 overlay.appendChild(iframe);
226
227 var type = document.getElementById('type');
228 var expected_showing = true;
229 function flip() {
230     if (expected_showing) {
231         type.textContent = 'Actual Invalidations';
232         expected_canvas.style.display = 'none';
233         actual_canvas.style.display = 'block';
234     } else {
235         type.textContent = 'Expected Invalidations';
236         actual_canvas.style.display = 'none';
237         expected_canvas.style.display = 'block';
238     }
239     expected_showing = !expected_showing
240 }
241 setInterval(flip, 3000);
242 </script>
243 </body>
244 </html>
245 """ % {
246         'title': test_name,
247         'expected_rects': expected_rects,
248         'actual_rects': actual_rects,
249         'minimum_repaint': minimum_repaint,
250     }