diff options
-rw-r--r-- | components/script/dom/globalscope.rs | 4 | ||||
-rw-r--r-- | components/script/script_thread.rs | 7 | ||||
-rw-r--r-- | components/webgpu/identity.rs | 32 | ||||
-rw-r--r-- | components/webgpu/lib.rs | 12 |
4 files changed, 52 insertions, 3 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 7b2d7ec25a0..5db5942fe0d 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2954,6 +2954,10 @@ impl GlobalScope { .insert(device.id(), Dom::from_ref(device)); } + pub fn remove_gpu_device(&self, device: WebGPUDevice) { + let _ = self.gpu_devices.borrow_mut().remove(&device); + } + pub fn handle_wgpu_msg(&self, device: WebGPUDevice, scope: u64, result: WebGPUOpResult) { let result = match result { WebGPUOpResult::Success => Ok(()), diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 02685506151..c07c43b04f2 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -2069,6 +2069,13 @@ impl ScriptThread { let global = self.documents.borrow().find_global(pipeline_id).unwrap(); global.handle_wgpu_msg(device, scope_id, result); }, + WebGPUMsg::CleanDevice { + pipeline_id, + device, + } => { + let global = self.documents.borrow().find_global(pipeline_id).unwrap(); + global.remove_gpu_device(device); + }, _ => {}, } } diff --git a/components/webgpu/identity.rs b/components/webgpu/identity.rs index a7fce80a82f..8a76868a2df 100644 --- a/components/webgpu/identity.rs +++ b/components/webgpu/identity.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::WebGPUDevice; +use crate::{WebGPUDevice, WebGPURequest}; use ipc_channel::ipc::IpcSender; use msg::constellation_msg::PipelineId; use serde::{Deserialize, Serialize}; @@ -47,23 +47,29 @@ pub enum WebGPUMsg { pipeline_id: PipelineId, result: WebGPUOpResult, }, + CleanDevice { + device: WebGPUDevice, + pipeline_id: PipelineId, + }, Exit, } #[derive(Debug)] pub struct IdentityRecycler { sender: IpcSender<WebGPUMsg>, + self_sender: IpcSender<WebGPURequest>, } pub struct IdentityRecyclerFactory { pub sender: IpcSender<WebGPUMsg>, + pub self_sender: IpcSender<WebGPURequest>, } macro_rules! impl_identity_handler { ($id:ty, $st:tt, $($var:tt)*) => { impl IdentityHandler<$id> for IdentityRecycler { type Input = $id; - fn process(&self, id: $id, _backend: Backend) -> $id { + fn process(&self, id: $id, _backend: Backend) -> Self::Input { log::debug!("process {} {:?}", $st, id); //debug_assert_eq!(id.unzip().2, backend); id @@ -80,7 +86,6 @@ macro_rules! impl_identity_handler { } impl_identity_handler!(AdapterId, "adapter", WebGPUMsg::FreeAdapter); -impl_identity_handler!(DeviceId, "device", WebGPUMsg::FreeDevice); impl_identity_handler!(SurfaceId, "surface", WebGPUMsg::FreeSurface); impl_identity_handler!(SamplerId, "sampler", WebGPUMsg::FreeSampler); impl_identity_handler!(TextureId, "texture", WebGPUMsg::FreeTexture); @@ -116,6 +121,26 @@ impl_identity_handler!( WebGPUMsg::FreePipelineLayout ); +impl IdentityHandler<DeviceId> for IdentityRecycler { + type Input = DeviceId; + fn process(&self, id: DeviceId, _backend: Backend) -> Self::Input { + log::debug!("process device {:?}", id); + //debug_assert_eq!(id.unzip().2, backend); + id + } + fn free(&self, id: DeviceId) { + log::debug!("free device {:?}", id); + let msg = WebGPUMsg::FreeDevice(id); + if self.sender.send(msg).is_err() { + log::error!("Failed to send FreeDevice({:?}) to script", id); + } + let msg_to_self = WebGPURequest::FreeDevice(id); + if self.self_sender.send(msg_to_self).is_err() { + log::error!("Failed to send FreeDevice({:?}) to server", id); + } + } +} + impl<I: TypedId + Clone + std::fmt::Debug> IdentityHandlerFactory<I> for IdentityRecyclerFactory where I: TypedId + Clone + std::fmt::Debug, @@ -125,6 +150,7 @@ where fn spawn(&self, _min_index: u32) -> Self::Filter { IdentityRecycler { sender: self.sender.clone(), + self_sender: self.self_sender.clone(), } } } diff --git a/components/webgpu/lib.rs b/components/webgpu/lib.rs index b7f33c26f56..dc7306fbcf0 100644 --- a/components/webgpu/lib.rs +++ b/components/webgpu/lib.rs @@ -177,6 +177,7 @@ pub enum WebGPURequest { }, DestroyTexture(id::TextureId), Exit(IpcSender<()>), + FreeDevice(id::DeviceId), RequestAdapter { sender: IpcSender<WebGPUResponseResult>, options: RequestAdapterOptions, @@ -344,6 +345,7 @@ impl<'a> WGPU<'a> { ) -> Self { let factory = IdentityRecyclerFactory { sender: script_sender.clone(), + self_sender: sender.clone(), }; WGPU { receiver, @@ -774,6 +776,16 @@ impl<'a> WGPU<'a> { } return; }, + WebGPURequest::FreeDevice(device_id) => { + let device = WebGPUDevice(device_id); + let pipeline_id = self.devices.remove(&device).unwrap(); + if let Err(e) = self.script_sender.send(WebGPUMsg::CleanDevice { + device, + pipeline_id, + }) { + warn!("Unable to send CleanDevice({:?}) ({:?})", device_id, e); + } + }, WebGPURequest::RequestAdapter { sender, options, |