Bug 1257641 - Add a test for APZ paint-skipping and event transformations after a skipped paint. r?botond
MozReview-Commit-ID: KnKSmueS87J
--- a/gfx/layers/apz/test/mochitest/apz_test_utils.js
+++ b/gfx/layers/apz/test/mochitest/apz_test_utils.js
@@ -92,8 +92,22 @@ function flushApzRepaints(aCallback, aWi
SpecialPowers.Services.obs.addObserver(repaintDone, "apz-repaints-flushed", false);
if (SpecialPowers.getDOMWindowUtils(aWindow).flushApzRepaints()) {
dump("Flushed APZ repaints, waiting for callback...\n");
} else {
dump("Flushing APZ repaints was a no-op, triggering callback directly...\n");
repaintDone();
}
}
+
+function waitForApzFlushedRepaints(aCallback) {
+ // First flush the main-thread paints and send transactions to the APZ
+ waitForAllPaints(function() {
+ // Then flush the APZ to make sure any repaint requests have been sent
+ // back to the main thread
+ flushApzRepaints(function() {
+ // Then flush the main-thread again to process the repaint requests.
+ // Once this is done, we should be in a stable state with nothing
+ // pending, so we can trigger the callback.
+ waitForAllPaints(aCallback);
+ });
+ });
+}
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/test/mochitest/helper_scrollto_tap.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width; initial-scale=1.0">
+ <title>Sanity touch-tapping test</title>
+ <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
+ <script type="application/javascript" src="apz_test_utils.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
+ <script type="application/javascript">
+
+function startTest() {
+ if (window.scrollY == 0) {
+ // the scrollframe is not yet marked as APZ-scrollable. Mark it so and
+ // start over.
+ window.scrollTo(0, 1);
+ waitForApzFlushedRepaints(startTest);
+ return;
+ }
+
+ // This is a scroll by 20px that should use paint-skipping if possible.
+ // If paint-skipping is enabled, this should not trigger a paint, but go
+ // directly to the compositor using an empty transaction. We check for this
+ // by ensuring the document element did not get painted.
+ var utils = window.opener.SpecialPowers.getDOMWindowUtils(window);
+ var elem = document.documentElement;
+ var skipping = location.search == '?true';
+ utils.checkAndClearPaintedState(elem);
+ window.scrollTo(0, 20);
+ waitForAllPaints(function() {
+ window.opener.is(utils.checkAndClearPaintedState(elem), !skipping, "Document element didn't get painted");
+ // After that's done, we click on the button to make sure the
+ // skipped-paint codepath still has working APZ event transformations.
+ clickButton();
+ });
+}
+
+function clickButton() {
+ if (!window.TouchEvent) {
+ window.opener.ok(true, "Touch events are not supported on this platform, sorry!\n");
+ window.opener.testDone();
+ return;
+ }
+
+ document.addEventListener('click', clicked, false);
+
+ synthesizeNativeTap(document.getElementById('b'), 5, 5, function() {
+ dump("Finished synthesizing tap, waiting for button to be clicked...\n");
+ });
+}
+
+function clicked(e) {
+ window.opener.is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
+ window.opener.testDone();
+}
+
+window.onload = function() {
+ waitForAllPaints(function() {
+ flushApzRepaints(startTest);
+ });
+}
+ </script>
+</head>
+<body style="height: 5000px">
+ <div style="height: 50px">spacer</div>
+ <button id="b" style="width: 10px; height: 10px"></button>
+</body>
+</html>
--- a/gfx/layers/apz/test/mochitest/mochitest.ini
+++ b/gfx/layers/apz/test/mochitest/mochitest.ini
@@ -5,16 +5,17 @@ support-files =
helper_bug982141.html
helper_bug1151663.html
helper_iframe1.html
helper_iframe2.html
helper_subframe_style.css
helper_basic_pan.html
helper_div_pan.html
helper_iframe_pan.html
+ helper_scrollto_tap.html
helper_tap.html
tags = apz
[test_bug982141.html]
[test_bug1151663.html]
[test_wheel_scroll.html]
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
[test_wheel_transactions.html]
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
--- a/gfx/layers/apz/test/mochitest/test_tap.html
+++ b/gfx/layers/apz/test/mochitest/test_tap.html
@@ -7,31 +7,69 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// this page just serially loads each one of the following test helper pages in
// a new window and waits for it to call testDone()
var tests = [
- 'helper_tap.html',
+ {'file': 'helper_tap.html'},
+ // For the following two tests, disable displayport suppression 10 times to
+ // make sure displayport suppression doesn't interfere with the test.
+ {'file': 'helper_scrollto_tap.html?true', 'prefs': [["apz.paint_skipping.enabled", true]], 'dp_suppression': false},
+ {'file': 'helper_scrollto_tap.html?false', 'prefs': [["apz.paint_skipping.enabled", false]], 'dp_suppression': false}
];
var testIndex = -1;
var w = null;
function testDone() {
+ var test = tests[testIndex];
if (w) {
+ if (typeof test.dp_suppression != 'undefined') {
+ // We modified the suppression when starting the test, so now undo that.
+ SpecialPowers.getDOMWindowUtils(window).respectDisplayPortSuppression(!test.dp_suppression);
+ }
+ if (!!test.prefs) {
+ // We pushed some prefs for this test, pop them, and re-invoke
+ // testDone() after that's been processed
+ SpecialPowers.popPrefEnv(function() {
+ w.close();
+ w = null;
+ testDone();
+ });
+ return;
+ }
+
w.close();
}
+
testIndex++;
- if (testIndex < tests.length) {
- w = window.open(tests[testIndex], "_blank");
+ if (testIndex >= tests.length) {
+ SimpleTest.finish();
+ return;
+ }
+
+ test = tests[testIndex];
+ if (typeof test.dp_suppression != 'undefined') {
+ // Normally during a test, the displayport will get suppressed during page
+ // load, and unsuppressed at a non-deterministic time during the test. The
+ // unsuppression can trigger a repaint which interferes with the test, so
+ // to avoid that we can force the displayport to be unsuppressed for the
+ // entire test which is more deterministic.
+ SpecialPowers.getDOMWindowUtils(window).respectDisplayPortSuppression(test.dp_suppression);
+ }
+ if (!!test.prefs) {
+ // Got some prefs for this subtest, push them
+ SpecialPowers.pushPrefEnv({"set": test.prefs}, function() {
+ w = window.open(test.file, "_blank");
+ });
} else {
- SimpleTest.finish();
+ w = window.open(test.file, "_blank");
}
}
window.onload = function() {
if (!SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled) {
ok(true, "APZ is not enabled, this test is not relevant, sorry!\n");
SimpleTest.finish();
return;