mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #23000 - jdm:invisible-webgl, r=nox
Make webgl behave better with session history
This prevents the compositor from animating pages that are not actually visible, so pages using webgl do not needlessly impact the performance of the rest of the browser. Additionally, this fixes a problem that was alluded to in [this code](b5228c098b/src/draw_buffer.rs (L282-L285)
), causing Servo to delete arbitrary resources when a GC occurred in content that used three.js.
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] These changes fix #22987 and fix #22977 and fix #20934 and fix #20953 and fix #20930 and fix #20950 and fix #20924
- [x] There are tests for these changes
<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/23000)
<!-- Reviewable:end -->
This commit is contained in:
commit
34a5a824b8
6 changed files with 145 additions and 0 deletions
|
@ -380,6 +380,10 @@ impl<VR: WebVRRenderHandler + 'static> WebGLThread<VR> {
|
|||
self.webrender_api.update_resources(txn.resource_updates)
|
||||
}
|
||||
|
||||
// We need to make the context current so its resources can be disposed of.
|
||||
let _ =
|
||||
Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id);
|
||||
|
||||
// Release GL context.
|
||||
self.contexts.remove(&context_id);
|
||||
|
||||
|
|
|
@ -2694,6 +2694,13 @@ where
|
|||
},
|
||||
};
|
||||
|
||||
if let Some(old_pipeline) = self.pipelines.get(&old_pipeline_id) {
|
||||
old_pipeline.notify_visibility(false);
|
||||
}
|
||||
if let Some(new_pipeline) = self.pipelines.get(&new_pipeline_id) {
|
||||
new_pipeline.notify_visibility(true);
|
||||
}
|
||||
|
||||
self.update_activity(old_pipeline_id);
|
||||
self.update_activity(new_pipeline_id);
|
||||
|
||||
|
@ -3413,6 +3420,10 @@ where
|
|||
self.notify_history_changed(change.top_level_browsing_context_id);
|
||||
},
|
||||
Some(old_pipeline_id) => {
|
||||
if let Some(pipeline) = self.pipelines.get(&old_pipeline_id) {
|
||||
pipeline.notify_visibility(false);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#unload-a-document
|
||||
self.unload_document(old_pipeline_id);
|
||||
// Deactivate the old pipeline, and activate the new one.
|
||||
|
|
|
@ -10614,6 +10614,16 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"mozilla/webgl/clearcolor_blue.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"mozilla/webgl/clearcolor_green.html": [
|
||||
[
|
||||
{}
|
||||
]
|
||||
],
|
||||
"mozilla/webgl/clearcolor_ref.html": [
|
||||
[
|
||||
{}
|
||||
|
@ -20120,6 +20130,14 @@
|
|||
"4760f382f0374985a334a5f6d0e0fe055670c61d",
|
||||
"reftest"
|
||||
],
|
||||
"mozilla/webgl/clearcolor_blue.html": [
|
||||
"d534babb2a664b7cb861f1cc253020e319f281e9",
|
||||
"support"
|
||||
],
|
||||
"mozilla/webgl/clearcolor_green.html": [
|
||||
"db11b31ab9839777d9d74cf7f2c46de00349c76e",
|
||||
"support"
|
||||
],
|
||||
"mozilla/webgl/clearcolor_ref.html": [
|
||||
"49cce2cc9009057742cb17e3fd452a986bd6c177",
|
||||
"support"
|
||||
|
@ -20144,6 +20162,10 @@
|
|||
"691535db4766536d66769408212cb13f3f64bef6",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/webgl/history.html": [
|
||||
"d470c229fbcca5a47d3370e8e58bae34882be491",
|
||||
"testharness"
|
||||
],
|
||||
"mozilla/webgl/img/rust-logo-256x256.png": [
|
||||
"63506dd85efce44f8433942a6f4e54d718a97046",
|
||||
"support"
|
||||
|
|
33
tests/wpt/mozilla/tests/mozilla/webgl/clearcolor_blue.html
Normal file
33
tests/wpt/mozilla/tests/mozilla/webgl/clearcolor_blue.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>WebGL ClearColor Test</title>
|
||||
</head>
|
||||
<style>
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
<body>
|
||||
<canvas id="canvas" width="640" height="480"></canvas>
|
||||
<!-- Dummy canvas that is only used to create a GL context that will be garbage collected -->
|
||||
<canvas id="canvas2" width="640" height="480"></canvas>
|
||||
<script type="text/javascript">
|
||||
|
||||
var gl = document.getElementById("canvas").getContext("webgl");
|
||||
var gl2 = document.getElementById("canvas2").getContext("webgl");
|
||||
gl2 = null;
|
||||
document.getElementById('canvas2').remove();
|
||||
|
||||
function draw() {
|
||||
gl.clearColor(0.0, 0.0, 1.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
33
tests/wpt/mozilla/tests/mozilla/webgl/clearcolor_green.html
Normal file
33
tests/wpt/mozilla/tests/mozilla/webgl/clearcolor_green.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>WebGL ClearColor Test</title>
|
||||
</head>
|
||||
<style>
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
</style>
|
||||
<body>
|
||||
<canvas id="canvas" width="640" height="480"></canvas>
|
||||
<!-- Dummy canvas that is only used to create a GL context that will be garbage collected -->
|
||||
<canvas id="canvas2" width="640" height="480"></canvas>
|
||||
<script type="text/javascript">
|
||||
|
||||
var gl = document.getElementById("canvas").getContext("webgl");
|
||||
var gl2 = document.getElementById("canvas2").getContext("webgl");
|
||||
gl2 = null;
|
||||
document.getElementById('canvas2').remove();
|
||||
|
||||
function draw() {
|
||||
gl.clearColor(0.0, 1.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
draw();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
42
tests/wpt/mozilla/tests/mozilla/webgl/history.html
Normal file
42
tests/wpt/mozilla/tests/mozilla/webgl/history.html
Normal file
|
@ -0,0 +1,42 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Traversing history with webgl content does not panic</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<iframe></iframe>
|
||||
<script>
|
||||
/*
|
||||
Load two pages that each create two GL contexts and draw in one of them.
|
||||
Traverse history and attempt to draw again; this has historically caused crashes.
|
||||
*/
|
||||
var first = "clearcolor_green.html";
|
||||
var second = "clearcolor_blue.html";
|
||||
|
||||
var iframe = document.querySelector('iframe');
|
||||
iframe.src = first;
|
||||
|
||||
var t = async_test();
|
||||
onload = t.step_func(function() {
|
||||
iframe.src = second;
|
||||
|
||||
iframe.onload = t.step_func(function() {
|
||||
assert_true(iframe.contentWindow.location.href.endsWith(second));
|
||||
iframe.contentWindow.history.back();
|
||||
|
||||
t.step_timeout(function() {
|
||||
assert_true(iframe.contentWindow.location.href.endsWith(first));
|
||||
// Try to use the previously-used GL context.
|
||||
iframe.contentWindow.draw();
|
||||
iframe.contentWindow.history.forward();
|
||||
|
||||
t.step_timeout(function() {
|
||||
assert_true(iframe.contentWindow.location.href.endsWith(second));
|
||||
// Try to use the previously-used GL context.
|
||||
iframe.contentWindow.draw();
|
||||
t.done();
|
||||
}, 1000);
|
||||
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue