Index: LayoutTests/fast/repaint/resources/text-based-repaint-minimum-repaint.js |
diff --git a/LayoutTests/fast/repaint/resources/text-based-repaint-minimum-repaint.js b/LayoutTests/fast/repaint/resources/text-based-repaint-minimum-repaint.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..935d309b22af20f6772c0c115e04bee5f7e74221 |
--- /dev/null |
+++ b/LayoutTests/fast/repaint/resources/text-based-repaint-minimum-repaint.js |
@@ -0,0 +1,166 @@ |
+// Visualizes under-repaint bugs. |
+// |
+// Definitions |
+// - minimum-repaint = region(diff(snapshot-before-repaintTest, |
+// snapshot-after-repaintTest-and-full-repaint)) |
+// It includes all pixels that should be changed after repaintTest. |
+// - actual-repaint = repaint rects recorded during repaintTest() and |
+// forceStyleRecalc(). |
+// - under-repaint = subtract(minimum-repaint, actual-repaint) |
+// Under-repaint will be shown in layout test overlay in black if any minimum- |
+// repaint region is not covered by actual-repaint. |
+// Any under-repaint means bug (given that we show it correct. See known |
+// issues below). |
+// |
+// How to use |
+// 1. For single repaint test: replace the original |
+// <script src="resources/text-based-repaint.js"> |
+// with |
+// <script src="resources/text-based-repaint-minimum-repaint.js"> |
+// For all repaint tests: copy text-based-repaint-minimum-repaint.js to |
+// text-based-repaint.js |
+// 2. Run layout tests. Repaint tests will result text diffs, which is because |
+// of the minimum repaint output in the actual results and doesn't mean the |
+// tests failed. |
+// 3. In layout test result page, click 'overlay' link or expand the test to |
+// see the 'overlay' pane. |
+// 4. Click 'Highlight under-repaint' button. You'll see black region if there |
+// is any under-repaint. |
+// |
+// Known issues |
+// crbug.com/381221 |
+ |
+window.testIsAsync = false; |
+window.outputRepaintRects = true; |
+ |
+function runRepaintTest() |
enne (OOO)
2014/06/05 22:13:42
I'm not super happy with all the duplication here.
Xianzhu
2014/06/05 22:51:06
Agreed. Done.
|
+{ |
+ if (!window.testRunner || !window.internals) { |
+ setTimeout(repaintTest, 500); |
+ return; |
+ } |
+ |
+ // TODO(enne): this is a workaround for multiple svg onload events. |
+ // See: http://crbug.com/372946 |
+ if (window.hasRunRepaintTest) |
+ return; |
+ window.hasRunRepaintTest = true; |
+ |
+ if (window.enablePixelTesting) |
+ testRunner.dumpAsTextWithPixelResults(); |
+ else |
+ testRunner.dumpAsText(); |
+ |
+ // All repaint tests are asynchronous. |
+ testRunner.waitUntilDone(); |
+ |
+ testRunner.capturePixelsAsyncThen(function(width, height, snapshot) { |
+ window.widthBeforeRepaint = width; |
+ window.heightBeforeRepaint = height; |
+ window.snapshotBeforeRepaint = snapshot; |
+ |
+ window.internals.startTrackingRepaints(document); |
+ repaintTest(); |
+ if (!window.testIsAsync) |
+ finishRepaintTest(); |
+ }); |
+} |
+ |
+function runRepaintAndPixelTest() |
+{ |
+ window.enablePixelTesting = true; |
+ runRepaintTest(); |
+} |
+ |
+function forceStyleRecalc() |
+{ |
+ if (document.body) |
+ document.body.offsetTop; |
+ else if (document.documentElement) |
+ document.documentElement.offsetTop; |
+} |
+ |
+function finishRepaintTest() |
+{ |
+ // Force a style recalc. |
+ forceStyleRecalc(); |
+ |
+ var repaintRects = window.internals.layerTreeAsText(document, window.internals.LAYER_TREE_INCLUDES_REPAINT_RECTS); |
+ |
+ internals.stopTrackingRepaints(document); |
+ |
+ internals.forceFullRepaint(document); |
+ testRunner.capturePixelsAsyncThen(function(width, height, snapshot) { |
+ // Play nice with JS tests which may want to print out assert results. |
+ if (window.isJsTest) |
+ window.outputRepaintRects = false; |
+ |
+ if (window.outputRepaintRects) { |
+ var minimumRepaint = computeMinimumRepaint(width, height, snapshot); |
+ if (minimumRepaint.length) |
+ repaintRects += '\nMinimum repaint:\n' + JSON.stringify(minimumRepaint, null, 2); |
+ testRunner.setCustomTextOutput(repaintRects); |
+ } |
+ |
+ if (window.afterTest) |
+ window.afterTest(); |
+ |
+ // Play nice with async JS tests which want to notifyDone themselves. |
+ if (!window.jsTestIsAsync) |
+ testRunner.notifyDone(); |
+ }); |
+} |
+ |
+function computeMinimumRepaint(width, height, snapshot) |
+{ |
+ var result = []; |
+ if (width > widthBeforeRepaint) { |
+ result.push([widthBeforeRepaint, 0, width - widthBeforeRepaint, Math.max(height, heightBeforeRepaint)]); |
+ width = widthBeforeRepaint; |
+ } |
+ if (height > heightBeforeRepaint) { |
+ result.push([0, heightBeforeRepaint, width, height - heightBeforeRepaint]); |
+ height = heightBeforeRepaint; |
+ } |
+ |
+ var dataBefore = new Uint32Array(snapshotBeforeRepaint); |
+ var dataAfter = new Uint32Array(snapshot); |
+ var rectsMayContinue = []; |
+ var index = 0; |
+ for (var y = 0; y < height; ++y) { |
+ var x = 0; |
+ var rectsMayContinueIndex = 0; |
+ var nextRectsMayContinue = []; |
+ while (true) { |
+ while (x < width && dataBefore[index] == dataAfter[index]) { |
+ ++x; |
+ ++index; |
+ } |
+ xBegin = x; |
+ while (x < width && dataBefore[index] != dataAfter[index]) { |
+ ++x; |
+ ++index; |
+ } |
+ xEnd = x; |
+ |
+ var xWidth = xEnd - xBegin; |
+ if (!xWidth) |
+ break; |
+ |
+ var rectMayContinue = rectsMayContinue[rectsMayContinueIndex]; |
+ while (rectMayContinue && rectMayContinue[0] < xBegin) |
+ rectMayContinue = rectsMayContinue[++rectsMayContinueIndex]; |
+ |
+ if (rectMayContinue && rectMayContinue[0] == xBegin && rectMayContinue[2] == xWidth) { |
+ ++rectMayContinue[3]; |
+ nextRectsMayContinue.push(rectMayContinue); |
+ } else { |
+ var newRect = [xBegin, y, xWidth, 1]; |
+ nextRectsMayContinue.push(newRect); |
+ result.push(newRect); |
+ } |
+ } |
+ rectsMayContinue = nextRectsMayContinue; |
+ } |
+ return result; |
+} |