-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
script: Unify script-based "update the rendering" and throttle it to 60 FPS #38431
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
95809ce
to
b857773
Compare
🔨 Triggering try run (#16695594746) for Linux (WPT) |
Marked as draft because I want to add more documentation to the code before landing this. |
Test results for linux-wpt from try job (#16695594746): Flaky unexpected result (22)
Stable unexpected results that are known to be intermittent (23)
Stable unexpected results (3)
|
|
This PR introduces script driven "update the rendering", right? We need to think what would that mean for #37776. |
Sorry, I meant to write "less work." The ScriptThread already does its own "update the rendering" calls when it doesn't expect to receive ticks from the renderer (when it isn't producing display lists). In addition, the ScriptThread currently runs "update the rendering" whenever receiving an IPC message, but without running rAFs. This change makes it so that the ScriptThread runs "update the rendering" in a spec-compliant way (running rAFs), but driven by a timer and only when it detects that it's necessary. I think it brings the ScriptThread-driven "update the rendering" closer to the specification. |
b857773
to
48e14be
Compare
🔨 Triggering try run (#16703627347) for Linux (WPT) |
Test results for linux-wpt from try job (#16703627347): Flaky unexpected result (25)
Stable unexpected results that are known to be intermittent (22)
|
✨ Try run (#16703627347) succeeded. |
Ah, thanks for explanation. I see the bigger picture now. |
48e14be
to
cbf0858
Compare
🔨 Triggering try run (#16707542911) for Linux (WPT) |
Test results for linux-wpt from try job (#16707542911): Flaky unexpected result (25)
Stable unexpected results that are known to be intermittent (21)
|
✨ Try run (#16707542911) succeeded. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the way this is clearing up. This PR also improves situation with #38327, there is still FPS drop, but less, so it might not be observed with not enough bunnies.
if self.font_context.web_fonts_still_loading() != 0 { | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thought: Would it make sense to use fonts.waiting_to_fullfill_promise
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this makes sense, though I would prefer to do it in a followup as I'm afraid of introducing too many more behavior changes in this one PR.
window.requestAnimationFrame(() => { | ||
window.requestAnimationFrame(test.step_func_done(function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, why do we need 2 rAFs to make this work. That does not seem right.
On related note, why isn't this tests upstreamed to WPT? I do not see anything servo specific.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this needs two frames because the resize needs to be processed according to the specification in "update the rendering":
- Forced layout: The
<iframe>
element resizes, but outside of "update the rendering." - First
requestAnimationFrame
callback, theDocument
inside the<iframe>
element is resized according to the<iframe>
resize during "update the rendering". - Second
requestAnimationFrame
callback: The corresponding media-dependent styles are applied after theDocument
is resized.
It's pretty common in WPT that these sort of tests wait for two animation frames before verifying behavior. Perhaps this could be improved, but maybe it's a bit outside the scope of this change. I think this test was passing accidentally before because all IPC messages were forcing "update the rendering" between rAF callbacks, which isn't spec behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works without any rAFs in both firefox and chromium:
window.onload = test.step_func(function() {
var frame = document.getElementById("myframe");
var frameDoc = frame.contentWindow.document;
var element = frameDoc.getElementById("testelement");
assert_equals(frame.contentWindow.getComputedStyle(element).backgroundColor, "rgb(255, 0, 0)");
frame.width = "300";
frameDoc.documentElement.offsetWidth; // Force layout
test.step_func_done(function () {
assert_equals(frame.contentWindow.getComputedStyle(element).backgroundColor, "rgb(0, 255, 0)");
})()
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect there is something wrong about the way we are processing updates here (either the restyle or the media query update) or else Firefox and Chromium have a more optimized implementation. In any case, I think this issue existed before my change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, we should open issue about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened #38446 for this.
5c370be
to
17748c6
Compare
@sagudev Thank you for the review! |
TIMEOUT [expected PASS] /resize-observer/iframe-same-origin.html Might be related to #38446 |
The issue here seems to be that when a ResizeObserver starts observing, we need to run "update the rendering" because it should deliver an event before a resize happens. It seems that we need to check to see if we've started observing in |
…60 FPS Instead of running "update the rendering" at every IPC message, only run it when a timeout has occured in script. In addition, avoid updating the rendering if a rendering update isn't necessary. This should greatly reduce the amount of processing that has to happen in script. Because we are running many fewer calls to "update the rendering" it is reasonable now to ensure that these always work the same way. In particular, we always run rAF and update the animation timeline when updating the ernder In addition, pull the following things out of reflow: - Code dealing with informing the Constellation that a Pipeline has become Idle when waiting for a screenshot. - Detecting when it is time to fulfill the `document.fonts.ready` promise. The latter means that reflow can never cause a garbage collection, making timing of reflows more consistent and simplifying many callsites that need to do script queries. Followup changes will seek to simplify the way that ScriptThread-driven animation timeouts happen even simpler. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Co-authored-by: Oriol Brufau <obrufau@igalia.com>
17748c6
to
8b8e081
Compare
🔨 Triggering try run (#16727928517) for Linux (WPT) |
Test results for linux-wpt from try job (#16727928517): Flaky unexpected result (29)
Stable unexpected results that are known to be intermittent (25)
|
✨ Try run (#16727928517) succeeded. |
…60 FPS (servo#38431) (wd) {"fail_fast": false, "matrix": [{"name": "Linux (WPT)", "workflow": "linux", "wpt": true, "profile": "release", "unit_tests": false, "build_libservo": false, "bencher": false, "build_args": "", "wpt_args": "./tests/wpt/tests/webdriver/tests/classic/ --product servodriver --headless --processes 1", "number_of_wpt_chunks": 2}]}
Instead of running "update the rendering" at every IPC message, only run
it when a timeout has occured in script. In addition, avoid updating the
rendering if a rendering update isn't necessary. This should greatly
reduce the amount of processing that has to happen in script.
Because we are running many fewer calls to "update the rendering" it is
reasonable now to ensure that these always work the same way. In
particular, we always run rAF and update the animation timeline when
updating the ernder
In addition, pull the following things out of reflow:
become Idle when waiting for a screenshot.
document.fonts.ready
promise.
The latter means that reflow can never cause a garbage collection,
making timing of reflows more consistent and simplifying many callsites
that need to do script queries.
Followup changes will seek to simplify the way that ScriptThread-driven
animation timeouts happen even simpler.
Testing: In general, this should not change testable behavior so much, though it
does seem to fix one test. The main improvement here should be that
the ScriptThread does less work.