Commit b6f6dab6 authored by wangxianzhu's avatar wangxianzhu Committed by Commit bot

Fix under-invalidation of media slider thumb when network state changes

When we invalidate a media control, we need to invalidate the whole
subtree because not only the top-level layout object but also the
descendants may paint differently.

BUG=645225
TEST=paint/invalidation/video-play-no-source-under-invalidation.html

Review-Url: https://codereview.chromium.org/2343713003
Cr-Commit-Position: refs/heads/master@{#418750}
parent acc8ce6a
CONSOLE MESSAGE: line 29: FAIL! An unexpected number of repaints occurred; expected 3 to 4 with rects of [8, 8, 300, 150]. Actual layer tree: {
"name": "Content Root Layer",
"bounds": [800, 600],
"children": [
{
"name": "LayoutView #document",
"bounds": [800, 600],
"contentsOpaque": true,
"drawsContent": true,
"paintInvalidations": [
{
"object": "LayoutVideo VIDEO",
"rect": [8, 8, 300, 150],
"reason": "full"
},
{
"object": "LayoutVideo VIDEO",
"rect": [8, 8, 300, 150],
"reason": "full"
},
{
"object": "LayoutVideo VIDEO",
"rect": [8, 8, 300, 150],
"reason": "style change"
}
]
}
],
"objectPaintInvalidations": [
{
"object": "LayoutVideo VIDEO",
"reason": "full"
},
{
"object": "LayoutVideo VIDEO",
"reason": "style change"
},
{
"object": "LayoutVideo VIDEO",
"reason": "full"
}
]
}
This is a testharness.js-based test.
FAIL Verifies there are no spurious repaints for audio in a video tag. Cannot read property 'length' of undefined
Harness: the test ran to completion.
<!doctype html> <!doctype html>
<title>Verifies there are no spurious repaints for audio in a video tag.</title> <title>Verifies there are no spurious repaints for audio in a video tag.</title>
<script src="../resources/testharness.js"></script> <script src="../../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script> <script src="../../resources/testharnessreport.js"></script>
<video></video> <video></video>
<script> <script>
async_test(function(t) { async_test(function(t) {
...@@ -15,7 +15,7 @@ async_test(function(t) { ...@@ -15,7 +15,7 @@ async_test(function(t) {
video.addEventListener('ended', t.step_func(function() { video.addEventListener('ended', t.step_func(function() {
var layerTree = internals.layerTreeAsText( var layerTree = internals.layerTreeAsText(
document, internals.LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS); document, internals.LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS);
var repaintRects = JSON.parse(layerTree).children[0].repaintRects; var paintInvalidations = JSON.parse(layerTree).children[0].paintInvalidations;
internals.stopTrackingRepaints(document); internals.stopTrackingRepaints(document);
// Manually verify the number of repaints instead of using a repaint // Manually verify the number of repaints instead of using a repaint
...@@ -32,13 +32,13 @@ async_test(function(t) { ...@@ -32,13 +32,13 @@ async_test(function(t) {
' Actual layer tree: ' + layerTree); ' Actual layer tree: ' + layerTree);
}); });
assert_between_inclusive(repaintRects.length, minExpected, maxExpected); assert_between_inclusive(paintInvalidations.length, minExpected, maxExpected);
for (var i = 0; i < repaintRects.length; ++i) for (var i = 0; i < paintInvalidations.length; ++i)
assert_array_equals(repaintRects[i], expectedRect); assert_array_equals(paintInvalidations[i].rect, expectedRect);
t.done(); t.done();
}), false); }), false);
video.src = 'content/silence.wav'; video.src = '../../media/content/silence.wav';
}); });
</script> </script>
...@@ -29,30 +29,35 @@ ...@@ -29,30 +29,35 @@
"bounds": [700, 525], "bounds": [700, 525],
"drawsContent": true, "drawsContent": true,
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutBlockFlow DIV id='track'",
"rect": [562, 485, 106, 48],
"reason": "subtree"
},
{ {
"object": "LayoutFlexibleBox DIV", "object": "LayoutFlexibleBox DIV",
"rect": [580, 508, 70, 2], "rect": [580, 508, 70, 2],
"reason": "forced by layout" "reason": "subtree"
}, },
{ {
"object": "LayoutSlider INPUT", "object": "LayoutSlider INPUT",
"rect": [580, 508, 70, 2], "rect": [580, 508, 70, 2],
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV id='thumb'", "object": "LayoutBlockFlow DIV id='thumb'",
"rect": [632, 485, 36, 48], "rect": [632, 485, 36, 48],
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV id='thumb'", "object": "LayoutBlockFlow DIV id='thumb'",
"rect": [562, 485, 36, 48], "rect": [562, 485, 36, 48],
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutButton INPUT", "object": "LayoutButton INPUT",
"rect": [530, 493, 32, 32], "rect": [530, 493, 32, 32],
"reason": "full" "reason": "subtree"
} }
] ]
} }
...@@ -68,19 +73,23 @@ ...@@ -68,19 +73,23 @@
}, },
{ {
"object": "LayoutButton INPUT", "object": "LayoutButton INPUT",
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutSlider INPUT", "object": "LayoutSlider INPUT",
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutFlexibleBox DIV", "object": "LayoutFlexibleBox DIV",
"reason": "forced by layout" "reason": "subtree"
},
{
"object": "LayoutBlockFlow DIV id='track'",
"reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV id='thumb'", "object": "LayoutBlockFlow DIV id='thumb'",
"reason": "full" "reason": "subtree"
} }
] ]
} }
......
Tests playing video with invalid source with paintUnderInvalidationChecking enabled. Passes if no under-invalidation reported.
<!DOCTYPE html>
<script>
if (window.testRunner)
testRunner.dumpAsText();
if (window.internals)
internals.runtimeFlags.paintUnderInvalidationCheckingEnabled = true;
</script>
Tests playing video with invalid source with paintUnderInvalidationChecking enabled.
Passes if no under-invalidation reported.<br>
<video controls="">
<source src="does-not-exist.webm">
</video>
...@@ -29,30 +29,35 @@ ...@@ -29,30 +29,35 @@
"bounds": [700, 525], "bounds": [700, 525],
"drawsContent": true, "drawsContent": true,
"paintInvalidations": [ "paintInvalidations": [
{
"object": "LayoutBlockFlow DIV id='track'",
"rect": [562, 485, 106, 48],
"reason": "subtree"
},
{ {
"object": "LayoutFlexibleBox DIV", "object": "LayoutFlexibleBox DIV",
"rect": [580, 508, 70, 2], "rect": [580, 508, 70, 2],
"reason": "forced by layout" "reason": "subtree"
}, },
{ {
"object": "LayoutSlider INPUT", "object": "LayoutSlider INPUT",
"rect": [580, 508, 70, 2], "rect": [580, 508, 70, 2],
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV id='thumb'", "object": "LayoutBlockFlow DIV id='thumb'",
"rect": [597, 485, 36, 48], "rect": [597, 485, 36, 48],
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV id='thumb'", "object": "LayoutBlockFlow DIV id='thumb'",
"rect": [562, 485, 36, 48], "rect": [562, 485, 36, 48],
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutButton INPUT", "object": "LayoutButton INPUT",
"rect": [530, 493, 32, 32], "rect": [530, 493, 32, 32],
"reason": "full" "reason": "subtree"
} }
] ]
} }
...@@ -68,19 +73,23 @@ ...@@ -68,19 +73,23 @@
}, },
{ {
"object": "LayoutButton INPUT", "object": "LayoutButton INPUT",
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutSlider INPUT", "object": "LayoutSlider INPUT",
"reason": "full" "reason": "subtree"
}, },
{ {
"object": "LayoutFlexibleBox DIV", "object": "LayoutFlexibleBox DIV",
"reason": "forced by layout" "reason": "subtree"
},
{
"object": "LayoutBlockFlow DIV id='track'",
"reason": "subtree"
}, },
{ {
"object": "LayoutBlockFlow DIV id='thumb'", "object": "LayoutBlockFlow DIV id='thumb'",
"reason": "full" "reason": "subtree"
} }
] ]
} }
......
{
"bounds": [800, 600],
"children": [
{
"bounds": [800, 600],
"contentsOpaque": true,
"drawsContent": true,
"children": [
{
"position": [8, 8],
"bounds": [700, 525]
},
{
"shouldFlattenTransform": false,
"children": [
{
"position": [8, 8],
"bounds": [700, 525],
"drawsContent": true
},
{
"position": [8, 8],
"bounds": [700, 520],
"drawsContent": true,
"repaintRects": [
[628, 492, 24, 25],
[570, 492, 89, 25],
[570, 492, 89, 25],
[570, 492, 24, 25],
[535, 489, 35, 31]
],
"paintInvalidationClients": [
"LayoutButton INPUT",
"LayoutSlider INPUT",
"LayoutFlexibleBox DIV",
"LayoutBlockFlow DIV id='thumb'"
]
}
]
}
]
}
]
}
{
"bounds": [800, 600],
"children": [
{
"bounds": [800, 600],
"contentsOpaque": true,
"drawsContent": true,
"children": [
{
"position": [8, 8],
"bounds": [700, 525]
},
{
"shouldFlattenTransform": false,
"children": [
{
"position": [8, 8],
"bounds": [700, 525],
"drawsContent": true
},
{
"position": [8, 8],
"bounds": [700, 520],
"drawsContent": true,
"repaintRects": [
[599, 492, 24, 25],
[570, 492, 89, 25],
[570, 492, 89, 25],
[570, 492, 24, 25],
[535, 489, 35, 31]
],
"paintInvalidationClients": [
"LayoutButton INPUT",
"LayoutSlider INPUT",
"LayoutFlexibleBox DIV",
"LayoutBlockFlow DIV id='thumb'"
]
}
]
}
]
}
]
}
...@@ -825,7 +825,7 @@ void MediaControls::invalidate(Element* element) ...@@ -825,7 +825,7 @@ void MediaControls::invalidate(Element* element)
return; return;
if (LayoutObject* layoutObject = element->layoutObject()) if (LayoutObject* layoutObject = element->layoutObject())
layoutObject->setShouldDoFullPaintInvalidation(); layoutObject->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
} }
void MediaControls::networkStateChanged() void MediaControls::networkStateChanged()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment