aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/script/dom/globalscope.rs4
-rw-r--r--components/script/script_thread.rs7
-rw-r--r--components/webgpu/identity.rs32
-rw-r--r--components/webgpu/lib.rs12
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,