diff options
author | Samson <16504129+sagudev@users.noreply.github.com> | 2024-06-20 07:56:59 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 05:56:59 +0000 |
commit | bf99cf7f30e9c7ea0e879068773155ce18dfd0c0 (patch) | |
tree | 93d3160f3548c529cc27fc49dec73d71ec3661af /components/script | |
parent | 256c55eb8125bb9ec2bcfa78fd0e000c54a48666 (diff) | |
download | servo-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.conf | 1 | ||||
-rw-r--r-- | components/script/dom/globalscope.rs | 32 | ||||
-rw-r--r-- | components/script/dom/gpudevice.rs | 7 | ||||
-rw-r--r-- | components/script/script_thread.rs | 11 |
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) => { |