Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / fast / repaint / resources / text-based-repaint.js
blob4e79123e50688e2e4fff604ab09f4b1f9732b2fe
1 // Asynchronous tests should manually call finishRepaintTest at the appropriate
2 // time.
3 window.testIsAsync = false;
4 window.outputRepaintRects = true;
5 window.generateMinimumRepaint = false; // See comments about 'Minimum repaint' below.
7 // All repaint tests are asynchronous.
8 if (window.testRunner)
9     testRunner.waitUntilDone();
11 function runRepaintTest()
13     if (!window.testRunner || !window.internals) {
14         setTimeout(repaintTest, 500);
15         return;
16     }
18     // TODO(enne): this is a workaround for multiple svg onload events.
19     // See: http://crbug.com/372946
20     if (window.hasRunRepaintTest)
21         return;
22     window.hasRunRepaintTest = true;
24     if (window.enablePixelTesting)
25         testRunner.dumpAsTextWithPixelResults();
26     else
27         testRunner.dumpAsText();
29     function continueRepaintTest()
30     {
31         window.internals.startTrackingRepaints(document);
32         repaintTest();
33         if (!window.testIsAsync)
34             finishRepaintTest();
35     }
37     if (window.generateMinimumRepaint) {
38         testRunner.capturePixelsAsyncThen(function(width, height, snapshot) {
39             window.widthBeforeRepaint = width;
40             window.heightBeforeRepaint = height;
41             window.snapshotBeforeRepaint = snapshot;
42             continueRepaintTest();
43         });
44     } else {
45         testRunner.layoutAndPaintAsyncThen(continueRepaintTest);
46     };
49 function runRepaintAndPixelTest()
51     window.enablePixelTesting = true;
52     runRepaintTest();
55 function forceStyleRecalc()
57     if (document.body)
58         document.body.offsetTop;
59     else if (document.documentElement)
60         document.documentElement.offsetTop;
63 function finishRepaintTest()
65     if (!window.testRunner || !window.internals)
66         return;
68     // Force a style recalc.
69     forceStyleRecalc();
71     var repaintRects = window.internals.layerTreeAsText(document, window.internals.LAYER_TREE_INCLUDES_REPAINT_RECTS | window.internals.LAYER_TREE_INCLUDES_PAINT_INVALIDATION_OBJECTS);
73     internals.stopTrackingRepaints(document);
75     function repaintTestDone()
76     {
77         // Play nice with JS tests which may want to print out assert results.
78         if (window.isJsTest)
79             window.outputRepaintRects = false;
81         if (window.outputRepaintRects)
82             testRunner.setCustomTextOutput(repaintRects);
84         if (window.afterTest)
85             window.afterTest();
87         // Play nice with async JS tests which want to notifyDone themselves.
88         if (!window.jsTestIsAsync)
89             testRunner.notifyDone();
90     }
92     if (window.generateMinimumRepaint) {
93         internals.forceFullRepaint(document);
94         testRunner.capturePixelsAsyncThen(function(width, height, snapshot) {
95             if (window.outputRepaintRects) {
96                 var minimumRepaint = computeMinimumRepaint(width, height, snapshot);
97                 if (minimumRepaint.length)
98                     repaintRects += '\nMinimum repaint:\n' + JSON.stringify(minimumRepaint, null, 2);
99             }
100             repaintTestDone();
101         });
102     } else {
103         repaintTestDone();
104     }
107 // Minimum repaint
109 // Definitions
110 // - minimum-repaint = region(diff(snapshot-before-repaintTest,
111 //                                 snapshot-after-repaintTest-and-full-repaint))
112 //   It includes all pixels that should be changed after repaintTest.
113 // - actual-repaint = repaint rects recorded during repaintTest() and
114 //   forceStyleRecalc().
115 // - potential-under-repaint = subtract(minimum-repaint, actual-repaint)
116 //   Potential-under-repaint will be shown in layout test overlay in black if
117 //   any minimum-repaint region is not covered by actual-repaint.
119 // Potential-under-repaints don't always mean bug:
120 // - Some know visualization issues (crbug.com/381221) may cause false
121 //   under-repaint;
122 // - Screen updates caused by composited layer re-compositing may not need
123 //   repaint.
125 // How to use
126 // 1. Set window.generateMinimumRepaint to true in some repaint test or change
127 //    this script to force window.generateMinimumRepaint to true.
128 // 2. Run layout tests. Repaint tests will result text diffs, which is because
129 //    of the minimum repaint output in the actual results and doesn't mean the
130 //    tests failed.
131 // 3. In layout test result page, click 'overlay' link or expand the test to
132 //    see the 'overlay' pane.
133 // 4. Click 'Highlight under-repaint' button. You'll see black region if there
134 //    is any under-repaint.
136 // Known issues
137 //    crbug.com/381221
139 function computeMinimumRepaint(width, height, snapshot)
141     var result = [];
142     if (width > widthBeforeRepaint) {
143         result.push([widthBeforeRepaint, 0, width - widthBeforeRepaint, Math.max(height, heightBeforeRepaint)]);
144         width = widthBeforeRepaint;
145     }
146     if (height > heightBeforeRepaint) {
147         result.push([0, heightBeforeRepaint, width, height - heightBeforeRepaint]);
148         height = heightBeforeRepaint;
149     }
151     var dataBefore = new Uint32Array(snapshotBeforeRepaint);
152     var dataAfter = new Uint32Array(snapshot);
153     var rectsMayContinue = [];
154     var index = 0;
155     for (var y = 0; y < height; ++y) {
156         var x = 0;
157         var rectsMayContinueIndex = 0;
158         var nextRectsMayContinue = [];
159         while (true) {
160             while (x < width && dataBefore[index] == dataAfter[index]) {
161                 ++x;
162                 ++index;
163             }
164             xBegin = x;
165             while (x < width && dataBefore[index] != dataAfter[index]) {
166                 ++x;
167                 ++index;
168             }
169             xEnd = x;
171             var xWidth = xEnd - xBegin;
172             if (!xWidth)
173                 break;
175             var rectMayContinue = rectsMayContinue[rectsMayContinueIndex];
176             while (rectMayContinue && rectMayContinue[0] < xBegin)
177                 rectMayContinue = rectsMayContinue[++rectsMayContinueIndex];
179             if (rectMayContinue && rectMayContinue[0] == xBegin && rectMayContinue[2] == xWidth) {
180                 ++rectMayContinue[3];
181                 nextRectsMayContinue.push(rectMayContinue);
182             } else {
183                 var newRect = [xBegin, y, xWidth, 1];
184                 nextRectsMayContinue.push(newRect);
185                 result.push(newRect);
186             }
187         }
188         rectsMayContinue = nextRectsMayContinue;
189     }
190     return result;