Home | History | Annotate | Download | only in controllers
      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 (
     10         re.search('"repaintRects": \[$', text, re.MULTILINE) != None or
     11         text.find('Minimum repaint:') != -1)
     12 
     13 
     14 def extract_layer_tree(input_str):
     15     if not isinstance(input_str, str):
     16         return '{}'
     17 
     18     if input_str[0:2] == '{\n':
     19         start = 0
     20     else:
     21         start = input_str.find('\n{\n')
     22         if start == -1:
     23             return '{}'
     24 
     25     end = input_str.find('\n}\n', start)
     26     if end == -1:
     27         return '{}'
     28 
     29     # FIXME: There may be multiple layer trees in the result.
     30     return input_str[start:end + 3]
     31 
     32 
     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):
     35         return ''
     36 
     37     expected_layer_tree = extract_layer_tree(expected_text)
     38     actual_layer_tree = extract_layer_tree(actual_text)
     39 
     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)
     44 
     45     return """<!DOCTYPE HTML>
     46 <html>
     47 <head>
     48 <title>%(title)s</title>
     49 <style>
     50     body {
     51         margin: 0;
     52         padding: 0;
     53     }
     54     iframe {
     55       position: absolute;
     56       top: 80px;
     57       left: 0;
     58       border: 0;
     59       z-index: -1;
     60     }
     61     canvas {
     62       position: absolute;
     63       top: 80px;
     64       left: 0;
     65       z-index: 1;
     66     }
     67     #actual, #minimum-repaint {
     68       display: none;
     69     }
     70 </style>
     71 </head>
     72 <body>
     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
     77 </label>
     78 <label><input id="use-solid-colors" type="checkbox" onchange="toggle_solid_color(this.checked)">Use solid colors</label>
     79 <br>
     80 <button title="See fast/repaint/resources/text-based-repaint.js for how this works" onclick="highlight_under_repaint()">
     81     Highlight under-repaint
     82 </button>
     83 <br>
     84 <span id='type'>Expected Invalidations</span>
     85 <div id=overlay>
     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>
     89 </div>
     90 <script>
     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_minimum_repaint(show_minimum_repaint) {
     98     document.getElementById('minimum-repaint').style.display = show_minimum_repaint ? 'block' : 'none';
     99 }
    100 
    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();
    105 }
    106 
    107 function highlight_under_repaint() {
    108     document.getElementById('show-test').checked = false;
    109     toggle_test(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);
    114 }
    115 
    116 var expected = %(expected)s;
    117 var actual = %(actual)s;
    118 var minimum_repaint = %(minimum_repaint)s;
    119 
    120 function rectsEqual(rect1, rect2) {
    121     return rect1[0] == rect2[0] && rect1[1] == rect2[1] && rect1[2] == rect2[2] && rect1[3] == rect2[3];
    122 }
    123 
    124 function draw_rects(context, rects) {
    125     for (var i = 0; i < rects.length; ++i) {
    126         var rect = rects[i];
    127         context.fillRect(rect[0], rect[1], rect[2], rect[3]);
    128     }
    129 }
    130 
    131 function draw_layer_rects(context, result) {
    132     context.save();
    133     if (result.position)
    134         context.translate(result.position[0], result.position[1]);
    135     var t = result.transform;
    136     if (t) {
    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]);
    141     }
    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]);
    147     }
    148     context.restore();
    149 }
    150 
    151 var expected_canvas = document.getElementById('expected');
    152 var actual_canvas = document.getElementById('actual');
    153 var minimum_repaint_canvas = document.getElementById('minimum-repaint');
    154 
    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);
    160 
    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);
    165 }
    166 
    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);
    171 }
    172 
    173 draw_repaint_rects();
    174 draw_minimum_repaint();
    175 
    176 var path = decodeURIComponent(location.search).substr(1);
    177 var iframe = document.createElement('iframe');
    178 iframe.id = 'test-frame';
    179 iframe.width = 800;
    180 iframe.height = 600;
    181 iframe.src = path;
    182 
    183 var overlay = document.getElementById('overlay');
    184 overlay.appendChild(iframe);
    185 
    186 var type = document.getElementById('type');
    187 var expected_showing = true;
    188 function flip() {
    189     if (expected_showing) {
    190         type.textContent = 'Actual Invalidations';
    191         expected_canvas.style.display = 'none';
    192         actual_canvas.style.display = 'block';
    193     } else {
    194         type.textContent = 'Expected Invalidations';
    195         actual_canvas.style.display = 'none';
    196         expected_canvas.style.display = 'block';
    197     }
    198     expected_showing = !expected_showing
    199 }
    200 setInterval(flip, 3000);
    201 </script>
    202 </body>
    203 </html>
    204 """ % {
    205         'title': test_name,
    206         'expected': expected_layer_tree,
    207         'actual': actual_layer_tree,
    208         'minimum_repaint': minimum_repaint,
    209     }
    210