blob: d5a56eb5c76fdd778cb2138989ddcdf8cebc2aa2 [file] [log] [blame]
<!DOCTYPE HTML>
<html>
<head>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}
if (window.internals)
internals.settings.setPreferCompositingToLCDTextEnabled(false);
function hasRepaint(layerTree) {
var layers = JSON.parse(layerTree).layers;
for (var i = 0; i < layers.length; ++i) {
var layer = layers[i];
// Exclude repaint in the vertical scrollbar layer which always happens on scroll.
if (layer.name == "Vertical Scrollbar Layer")
continue;
if (layer.paintInvalidations)
return true;
}
return false;
}
function rAF() {
return new Promise(function(resolve) {
requestAnimationFrame(resolve);
});
}
async function testScrollRepaint(description, expectsRepaint, scroller) {
var result = description + ":\n";
// Ensure that any dirtiness has been committed
await rAF();
await rAF();
if (window.internals)
internals.startTrackingRepaints(document);
scroller.scrollTop = 100;
// Wait until the next frame reflecting the new scroll position.
await rAF();
if (window.internals) {
var layer_tree = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS);
var repainted = hasRepaint(layer_tree);
var repaintedMessage = repainted ? "repainted" : "did not repaint";
var expectedMessage = expectsRepaint ? " when expected" : " when unexpected";
if (repainted == expectsRepaint)
result += "PASS " + repaintedMessage + expectedMessage + "\n";
else
result += "FAIL " + repaintedMessage + expectedMessage + "\n" + layer_tree + "\n";
internals.stopTrackingRepaints(document);
}
// Do all cleanup here (so as not to affect repaint rects).
scroller.scrollTop = 0;
return result;
}
async function testNoRepaint() {
return testScrollRepaint("Overflow scroll", false, container);
}
async function testWithSelection() {
var selection = getSelection();
var range = document.createRange();
range.selectNode(document.getElementById("selection-start"));
selection.addRange(range);
range = document.createRange();
range.selectNode(document.getElementById("selection-end"));
selection.addRange(range);
var result = await testScrollRepaint("Overflow scroll with selection", false, container);
getSelection().removeAllRanges();
return result;
}
async function testMarquee() {
container.style.display = "none";
marquee.style.display = "block";
var result = await testScrollRepaint("Marquee", false, marquee);
marquee.style.display = "none";
container.style.display = "block";
return result;
}
async function testWithInlineChild() {
span.style.display = "inline";
var result = await testScrollRepaint("Overflow scroll with inline child", false, container);
span.style.display = "none";
return result;
}
async function testOverflowHidden() {
container.style.overflow = "hidden";
var result = testScrollRepaint("Overflow hidden", false, container);
container.style.overflow = "scroll";
return result;
}
async function doTests() {
marquee.stop();
var result = await testNoRepaint();
result += await testWithSelection();
result += await testMarquee();
result += await testWithInlineChild();
result += await testOverflowHidden();
if (window.testRunner) {
testRunner.setCustomTextOutput(result);
testRunner.notifyDone();
}
}
window.onload = doTests;
</script>
<style>
#target::selection { background-color: green; }
#container {
width:100px;
height:300px;
border: 1px black solid;
overflow: scroll;
backface-visibility: hidden;
position: relative;
}
#fixed {
width: 50px;
height: 50px;
position: fixed;
top: 200px;
left: 200px;
background-color: blue;
backface-visibility: hidden;
}
.scrolled {
width: 50px;
height: 50px;
margin: 10px;
position: relative;
background-color: green;
backface-visibility: hidden;
}
#span {
display: none;
}
#description {
display: none;
}
marquee {
width: 60px;
height: 60px;
backface-visibility: hidden;
position: relative;
display: none;
}
</style>
</head>
<body>
<pre id="description">
This test ensures that if the only thing that scrolls is a composited layer,
we do not repaint. It passes if we repaint when we have to draw the selection
block gaps or if we have content that is not in a composited layer. It also
checks that we do not repaint when all the content is in a composited layer.
</pre>
<div id="container">
<span id="span">Hello!</span>
<div id="fixed"></div>
<div class="scrolled" id="selection-start"></div>
<div class="scrolled" id="selection-end"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
<div class="scrolled"></div>
</div>
<marquee id="marquee" direction="up" scrollamount="1">
<p>Lorem ipsum dolor amet</p>
<p>Lorem ipsum dolor amet</p>
<p>Lorem ipsum dolor amet</p>
<p>Lorem ipsum dolor amet</p>
<p>Lorem ipsum dolor amet</p>
<p>Lorem ipsum dolor amet</p>
<p>Lorem ipsum dolor amet</p>
</marquee>
</body>
</html>