aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorSamson <16504129+sagudev@users.noreply.github.com>2024-06-20 07:56:59 +0200
committerGitHub <noreply@github.com>2024-06-20 05:56:59 +0000
commitbf99cf7f30e9c7ea0e879068773155ce18dfd0c0 (patch)
tree93d3160f3548c529cc27fc49dec73d71ec3661af /components/script
parent256c55eb8125bb9ec2bcfa78fd0e000c54a48666 (diff)
downloadservo-bf99cf7f30e9c7ea0e879068773155ce18dfd0c0.tar.gz
servo-bf99cf7f30e9c7ea0e879068773155ce18dfd0c0.zip
Proper GPUDevice cleanup (#32520)
* Make device cleanup right * Use weakref for GPUDevice in globalscope * No need to destroy device on drop * DeviceReason early return * make remove_gpu_device to be the only way to remove device
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/codegen/Bindings.conf1
-rw-r--r--components/script/dom/globalscope.rs32
-rw-r--r--components/script/dom/gpudevice.rs7
-rw-r--r--components/script/script_thread.rs11
4 files changed, 35 insertions, 16 deletions
diff --git a/components/script/dom/bindings/codegen/Bindings.conf b/components/script/dom/bindings/codegen/Bindings.conf
index c7b4cbace88..6e10ffc6a3e 100644
--- a/components/script/dom/bindings/codegen/Bindings.conf
+++ b/components/script/dom/bindings/codegen/Bindings.conf
@@ -169,6 +169,7 @@ DOMInterfaces = {
},
'GPUDevice': {
+ 'weakReferenceable': True, # for usage in GlobalScope https://github.com/servo/servo/issues/32519
'inRealms': ['PopErrorScope', 'CreateComputePipelineAsync', 'CreateRenderPipelineAsync'],
}
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index ca4f5e7cd76..27138a15d84 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -322,7 +322,7 @@ pub struct GlobalScope {
gpu_id_hub: Arc<Mutex<Identities>>,
/// WebGPU devices
- gpu_devices: DomRefCell<HashMapTracedValues<WebGPUDevice, Dom<GPUDevice>>>,
+ gpu_devices: DomRefCell<HashMapTracedValues<WebGPUDevice, WeakRef<GPUDevice>>>,
// https://w3c.github.io/performance-timeline/#supportedentrytypes-attribute
#[ignore_malloc_size_of = "mozjs"]
@@ -3091,7 +3091,16 @@ impl GlobalScope {
pub fn add_gpu_device(&self, device: &GPUDevice) {
self.gpu_devices
.borrow_mut()
- .insert(device.id(), Dom::from_ref(device));
+ .insert(device.id(), WeakRef::new(device));
+ }
+
+ pub fn remove_gpu_device(&self, device: WebGPUDevice) {
+ let device = self
+ .gpu_devices
+ .borrow_mut()
+ .remove(&device)
+ .expect("GPUDevice should still be in devices hashmap");
+ assert!(device.root().is_none())
}
pub fn gpu_device_lost(&self, device: WebGPUDevice, reason: DeviceLostReason, msg: String) {
@@ -3100,15 +3109,24 @@ impl GlobalScope {
DeviceLostReason::Destroyed => GPUDeviceLostReason::Destroyed,
};
let _ac = enter_realm(&*self);
- self.gpu_devices
+ if let Some(device) = self
+ .gpu_devices
.borrow_mut()
- .remove(&device)
- .expect("GPUDevice should still exists")
- .lose(reason, msg);
+ .get_mut(&device)
+ .expect("GPUDevice should still be in devices hashmap")
+ .root()
+ {
+ device.lose(reason, msg);
+ }
}
pub fn handle_uncaptured_gpu_error(&self, device: WebGPUDevice, error: webgpu::Error) {
- if let Some(gpu_device) = self.gpu_devices.borrow().get(&device) {
+ if let Some(gpu_device) = self
+ .gpu_devices
+ .borrow()
+ .get(&device)
+ .and_then(|device| device.root())
+ {
gpu_device.fire_uncaptured_error(error);
} else {
warn!("Recived error for lost GPUDevice!")
diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs
index 9e7c8c76b09..da1432e99b6 100644
--- a/components/script/dom/gpudevice.rs
+++ b/components/script/dom/gpudevice.rs
@@ -1034,13 +1034,6 @@ impl Drop for GPUDevice {
if let Err(e) = self
.channel
.0
- .send(WebGPURequest::DestroyDevice(self.device.0))
- {
- warn!("Failed to send DestroyDevice ({:?}) ({})", self.device.0, e);
- }
- if let Err(e) = self
- .channel
- .0
.send(WebGPURequest::DropDevice(self.device.0))
{
warn!("Failed to send DropDevice ({:?}) ({})", self.device.0, e);
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 1d3fb58766a..6fe8f8f4ead 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -92,7 +92,7 @@ use style::dom::OpaqueNode;
use style::thread_state::{self, ThreadState};
use time::precise_time_ns;
use url::Position;
-use webgpu::WebGPUMsg;
+use webgpu::{WebGPUDevice, WebGPUMsg};
use webrender_api::DocumentId;
use webrender_traits::WebRenderScriptApi;
@@ -2423,7 +2423,14 @@ impl ScriptThread {
fn handle_msg_from_webgpu_server(&self, msg: WebGPUMsg) {
match msg {
WebGPUMsg::FreeAdapter(id) => self.gpu_id_hub.lock().kill_adapter_id(id),
- WebGPUMsg::FreeDevice(id) => self.gpu_id_hub.lock().kill_device_id(id),
+ WebGPUMsg::FreeDevice {
+ device_id,
+ pipeline_id,
+ } => {
+ self.gpu_id_hub.lock().kill_device_id(device_id);
+ let global = self.documents.borrow().find_global(pipeline_id).unwrap();
+ global.remove_gpu_device(WebGPUDevice(device_id));
+ },
WebGPUMsg::FreeBuffer(id) => self.gpu_id_hub.lock().kill_buffer_id(id),
WebGPUMsg::FreePipelineLayout(id) => self.gpu_id_hub.lock().kill_pipeline_layout_id(id),
WebGPUMsg::FreeComputePipeline(id) => {