mirror of
https://github.com/servo/servo.git
synced 2025-07-25 16:20:36 +01:00
Ensure GPUDevice cleanup in GlobalScope
This commit is contained in:
parent
37d606621d
commit
785497af63
4 changed files with 52 additions and 3 deletions
|
@ -2954,6 +2954,10 @@ impl GlobalScope {
|
||||||
.insert(device.id(), Dom::from_ref(device));
|
.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) {
|
pub fn handle_wgpu_msg(&self, device: WebGPUDevice, scope: u64, result: WebGPUOpResult) {
|
||||||
let result = match result {
|
let result = match result {
|
||||||
WebGPUOpResult::Success => Ok(()),
|
WebGPUOpResult::Success => Ok(()),
|
||||||
|
|
|
@ -2069,6 +2069,13 @@ impl ScriptThread {
|
||||||
let global = self.documents.borrow().find_global(pipeline_id).unwrap();
|
let global = self.documents.borrow().find_global(pipeline_id).unwrap();
|
||||||
global.handle_wgpu_msg(device, scope_id, result);
|
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);
|
||||||
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* 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 ipc_channel::ipc::IpcSender;
|
||||||
use msg::constellation_msg::PipelineId;
|
use msg::constellation_msg::PipelineId;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -47,23 +47,29 @@ pub enum WebGPUMsg {
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
result: WebGPUOpResult,
|
result: WebGPUOpResult,
|
||||||
},
|
},
|
||||||
|
CleanDevice {
|
||||||
|
device: WebGPUDevice,
|
||||||
|
pipeline_id: PipelineId,
|
||||||
|
},
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct IdentityRecycler {
|
pub struct IdentityRecycler {
|
||||||
sender: IpcSender<WebGPUMsg>,
|
sender: IpcSender<WebGPUMsg>,
|
||||||
|
self_sender: IpcSender<WebGPURequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IdentityRecyclerFactory {
|
pub struct IdentityRecyclerFactory {
|
||||||
pub sender: IpcSender<WebGPUMsg>,
|
pub sender: IpcSender<WebGPUMsg>,
|
||||||
|
pub self_sender: IpcSender<WebGPURequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_identity_handler {
|
macro_rules! impl_identity_handler {
|
||||||
($id:ty, $st:tt, $($var:tt)*) => {
|
($id:ty, $st:tt, $($var:tt)*) => {
|
||||||
impl IdentityHandler<$id> for IdentityRecycler {
|
impl IdentityHandler<$id> for IdentityRecycler {
|
||||||
type Input = $id;
|
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);
|
log::debug!("process {} {:?}", $st, id);
|
||||||
//debug_assert_eq!(id.unzip().2, backend);
|
//debug_assert_eq!(id.unzip().2, backend);
|
||||||
id
|
id
|
||||||
|
@ -80,7 +86,6 @@ macro_rules! impl_identity_handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_identity_handler!(AdapterId, "adapter", WebGPUMsg::FreeAdapter);
|
impl_identity_handler!(AdapterId, "adapter", WebGPUMsg::FreeAdapter);
|
||||||
impl_identity_handler!(DeviceId, "device", WebGPUMsg::FreeDevice);
|
|
||||||
impl_identity_handler!(SurfaceId, "surface", WebGPUMsg::FreeSurface);
|
impl_identity_handler!(SurfaceId, "surface", WebGPUMsg::FreeSurface);
|
||||||
impl_identity_handler!(SamplerId, "sampler", WebGPUMsg::FreeSampler);
|
impl_identity_handler!(SamplerId, "sampler", WebGPUMsg::FreeSampler);
|
||||||
impl_identity_handler!(TextureId, "texture", WebGPUMsg::FreeTexture);
|
impl_identity_handler!(TextureId, "texture", WebGPUMsg::FreeTexture);
|
||||||
|
@ -116,6 +121,26 @@ impl_identity_handler!(
|
||||||
WebGPUMsg::FreePipelineLayout
|
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
|
impl<I: TypedId + Clone + std::fmt::Debug> IdentityHandlerFactory<I> for IdentityRecyclerFactory
|
||||||
where
|
where
|
||||||
I: TypedId + Clone + std::fmt::Debug,
|
I: TypedId + Clone + std::fmt::Debug,
|
||||||
|
@ -125,6 +150,7 @@ where
|
||||||
fn spawn(&self, _min_index: u32) -> Self::Filter {
|
fn spawn(&self, _min_index: u32) -> Self::Filter {
|
||||||
IdentityRecycler {
|
IdentityRecycler {
|
||||||
sender: self.sender.clone(),
|
sender: self.sender.clone(),
|
||||||
|
self_sender: self.self_sender.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,7 @@ pub enum WebGPURequest {
|
||||||
},
|
},
|
||||||
DestroyTexture(id::TextureId),
|
DestroyTexture(id::TextureId),
|
||||||
Exit(IpcSender<()>),
|
Exit(IpcSender<()>),
|
||||||
|
FreeDevice(id::DeviceId),
|
||||||
RequestAdapter {
|
RequestAdapter {
|
||||||
sender: IpcSender<WebGPUResponseResult>,
|
sender: IpcSender<WebGPUResponseResult>,
|
||||||
options: RequestAdapterOptions,
|
options: RequestAdapterOptions,
|
||||||
|
@ -344,6 +345,7 @@ impl<'a> WGPU<'a> {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let factory = IdentityRecyclerFactory {
|
let factory = IdentityRecyclerFactory {
|
||||||
sender: script_sender.clone(),
|
sender: script_sender.clone(),
|
||||||
|
self_sender: sender.clone(),
|
||||||
};
|
};
|
||||||
WGPU {
|
WGPU {
|
||||||
receiver,
|
receiver,
|
||||||
|
@ -774,6 +776,16 @@ impl<'a> WGPU<'a> {
|
||||||
}
|
}
|
||||||
return;
|
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 {
|
WebGPURequest::RequestAdapter {
|
||||||
sender,
|
sender,
|
||||||
options,
|
options,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue