Bug 1781007 - Skip calling RestrictToRootDisplayPort in the case where the scroll container has empty displayport margins. r=tnikkel

Differential Revision: https://phabricator.services.mozilla.com/D189323
This commit is contained in:
Hiroyuki Ikezoe 2023-10-04 04:50:01 +00:00
Родитель 1f5d04fed3
Коммит bd13aa7916
5 изменённых файлов: 85 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8">
<title>No checkerboarding on no longer async scrollable container</title>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script src="/tests/SimpleTest/paint_listener.js"></script>
<style>
#outer {
position: absolute;
overflow: scroll;
width: 50vw;
height: 90vh;
border: 1px solid black;
}
#inner {
overflow-y: hidden;
width: 100%;
}
.spacer {
width: 60vw;
height: 5000px;
background-color: blue;
}
</style>
<div id="outer">
<div id="inner">
<div class="spacer"></div>
</div>
</div>
<script>
async function test() {
outer.style.width = "90vw";
await promiseApzFlushedRepaints();
const scrollEndPromise = promiseOneEvent(outer, "scrollend");
// Scroll the outer container to the bottom to see if checkerboarding happens
// or not.
outer.scrollBy({ top: 5000, behavior: "smooth" });
await scrollEndPromise;
const utils = SpecialPowers.getDOMWindowUtils(window);
assertNotCheckerboarded(utils, utils.getViewId(inner), "the inner scroll container");
assertNotCheckerboarded(utils, utils.getViewId(outer), "the outer scroll container");
}
waitUntilApzStable()
.then(test)
.then(subtestDone, subtestFailed);
</script>
</html>

Просмотреть файл

@ -37,6 +37,11 @@
["apz.y_stationary_size_multiplier", "0.0"],
];
var smooth_scroll_prefs = [
...prefs,
["general.smoothScroll", true],
];
var subtests = [
{ file: "helper_checkerboard_apzforcedisabled.html", prefs },
{ file: "helper_checkerboard_scrollinfo.html", prefs },
@ -45,6 +50,7 @@
{ file: "helper_checkerboard_zoom_during_load.html", "prefs": no_multiplier_prefs },
{ file: "helper_wide_crossorigin_iframe.html", prefs },
{ file: "helper_reset_zoom_bug1818967.html", prefs },
{ file: "helper_checkerboard.html", "prefs": smooth_scroll_prefs },
];
let platform = getPlatform();

Просмотреть файл

@ -402,6 +402,9 @@ static bool GetDisplayPortImpl(nsIContent* aContent, nsRect* aResult,
} else if (isDisplayportSuppressed ||
nsLayoutUtils::ShouldDisableApzForElement(aContent) ||
aContent->GetProperty(nsGkAtoms::MinimalDisplayPort)) {
// Note: the above conditions should be in sync with the conditions in
// WillUseEmptyDisplayPortMargins.
// Make a copy of the margins data but set the margins to empty.
// Do not create a new DisplayPortMargins object with
// DisplayPortMargins::Empty(), because that will record the visual
@ -956,4 +959,18 @@ Maybe<nsRect> DisplayPortUtils::GetRootDisplayportBase(PresShell* aPresShell) {
return Some(baseRect);
}
bool DisplayPortUtils::WillUseEmptyDisplayPortMargins(nsIContent* aContent) {
MOZ_ASSERT(HasDisplayPort(aContent));
nsIFrame* frame = aContent->GetPrimaryFrame();
if (!frame) {
return false;
}
// Note these conditions should be in sync with the conditions where we use
// empty margins to calculate display port in GetDisplayPortImpl
return aContent->GetProperty(nsGkAtoms::MinimalDisplayPort) ||
frame->PresShell()->IsDisplayportSuppressed() ||
nsLayoutUtils::ShouldDisableApzForElement(aContent);
}
} // namespace mozilla

Просмотреть файл

@ -298,6 +298,13 @@ class DisplayPortUtils {
* browser process.
*/
static Maybe<nsRect> GetRootDisplayportBase(PresShell* aPresShell);
/**
* Whether to tell the given element will use empty displayport marings.
* NOTE: This function should be called only for the element having any type
* of displayports.
*/
static bool WillUseEmptyDisplayPortMargins(nsIContent* aContent);
};
} // namespace mozilla

Просмотреть файл

@ -4520,7 +4520,8 @@ bool nsHTMLScrollFrame::DecideScrollableLayer(
// And don't call RestrictToRootDisplayPort if we would be trying to
// restrict to our own display port, which doesn't make sense (ie if we
// are a root scroll frame in a process root prescontext).
if (usingDisplayPort && (!mIsRoot || pc->GetParentPresContext())) {
if (usingDisplayPort && (!mIsRoot || pc->GetParentPresContext()) &&
!DisplayPortUtils::WillUseEmptyDisplayPortMargins(content)) {
displayportBase = RestrictToRootDisplayPort(displayportBase);
MOZ_LOG(sDisplayportLog, LogLevel::Verbose,
("Scroll id %" PRIu64 " has restricted base %s\n", viewID,