1 // Asynchronous tests should manually call finishRepaintTest at the appropriate
3 window.testIsAsync = false;
4 window.outputRepaintRects = true;
5 window.generateMinimumRepaint = false; // See comments about 'Minimum repaint' below.
7 // All repaint tests are asynchronous.
9 testRunner.waitUntilDone();
11 function runRepaintTest()
13 if (!window.testRunner || !window.internals) {
14 setTimeout(repaintTest, 500);
18 // TODO(enne): this is a workaround for multiple svg onload events.
19 // See: http://crbug.com/372946
20 if (window.hasRunRepaintTest)
22 window.hasRunRepaintTest = true;
24 if (window.enablePixelTesting)
25 testRunner.dumpAsTextWithPixelResults();
27 testRunner.dumpAsText();
29 function continueRepaintTest()
31 window.internals.startTrackingRepaints(document);
33 if (!window.testIsAsync)
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();
45 testRunner.layoutAndPaintAsyncThen(continueRepaintTest);
49 function runRepaintAndPixelTest()
51 window.enablePixelTesting = true;
55 function forceStyleRecalc()
58 document.body.offsetTop;
59 else if (document.documentElement)
60 document.documentElement.offsetTop;
63 function finishRepaintTest()
65 if (!window.testRunner || !window.internals)
68 // Force a style recalc.
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()
77 // Play nice with JS tests which may want to print out assert results.
79 window.outputRepaintRects = false;
81 if (window.outputRepaintRects)
82 testRunner.setCustomTextOutput(repaintRects);
87 // Play nice with async JS tests which want to notifyDone themselves.
88 if (!window.jsTestIsAsync)
89 testRunner.notifyDone();
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);
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
122 // - Screen updates caused by composited layer re-compositing may not need
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
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.
139 function computeMinimumRepaint(width, height, snapshot)
142 if (width > widthBeforeRepaint) {
143 result.push([widthBeforeRepaint, 0, width - widthBeforeRepaint, Math.max(height, heightBeforeRepaint)]);
144 width = widthBeforeRepaint;
146 if (height > heightBeforeRepaint) {
147 result.push([0, heightBeforeRepaint, width, height - heightBeforeRepaint]);
148 height = heightBeforeRepaint;
151 var dataBefore = new Uint32Array(snapshotBeforeRepaint);
152 var dataAfter = new Uint32Array(snapshot);
153 var rectsMayContinue = [];
155 for (var y = 0; y < height; ++y) {
157 var rectsMayContinueIndex = 0;
158 var nextRectsMayContinue = [];
160 while (x < width && dataBefore[index] == dataAfter[index]) {
165 while (x < width && dataBefore[index] != dataAfter[index]) {
171 var xWidth = xEnd - xBegin;
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);
183 var newRect = [xBegin, y, xWidth, 1];
184 nextRectsMayContinue.push(newRect);
185 result.push(newRect);
188 rectsMayContinue = nextRectsMayContinue;