mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
160 lines
5.2 KiB
Rust
160 lines
5.2 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* 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::{ErrorScopeId, WebGPUDevice, WebGPURequest};
|
|
use ipc_channel::ipc::IpcSender;
|
|
use msg::constellation_msg::PipelineId;
|
|
use serde::{Deserialize, Serialize};
|
|
use wgpu::{
|
|
hub::{GlobalIdentityHandlerFactory, IdentityHandler, IdentityHandlerFactory},
|
|
id::{
|
|
AdapterId, BindGroupId, BindGroupLayoutId, BufferId, CommandBufferId, ComputePipelineId,
|
|
DeviceId, PipelineLayoutId, RenderBundleId, RenderPipelineId, SamplerId, ShaderModuleId,
|
|
SurfaceId, SwapChainId, TextureId, TextureViewId, TypedId,
|
|
},
|
|
};
|
|
use wgt::Backend;
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
pub enum WebGPUOpResult {
|
|
ValidationError(String),
|
|
OutOfMemoryError,
|
|
Success,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
pub enum WebGPUMsg {
|
|
FreeAdapter(AdapterId),
|
|
FreeDevice(DeviceId),
|
|
FreeBuffer(BufferId),
|
|
FreeSwapChain(SwapChainId),
|
|
FreePipelineLayout(PipelineLayoutId),
|
|
FreeComputePipeline(ComputePipelineId),
|
|
FreeRenderPipeline(RenderPipelineId),
|
|
FreeBindGroup(BindGroupId),
|
|
FreeBindGroupLayout(BindGroupLayoutId),
|
|
FreeCommandBuffer(CommandBufferId),
|
|
FreeTexture(TextureId),
|
|
FreeTextureView(TextureViewId),
|
|
FreeSampler(SamplerId),
|
|
FreeSurface(SurfaceId),
|
|
FreeShaderModule(ShaderModuleId),
|
|
FreeRenderBundle(RenderBundleId),
|
|
WebGPUOpResult {
|
|
device: WebGPUDevice,
|
|
scope_id: Option<ErrorScopeId>,
|
|
pipeline_id: PipelineId,
|
|
result: WebGPUOpResult,
|
|
},
|
|
CleanDevice {
|
|
device: WebGPUDevice,
|
|
pipeline_id: PipelineId,
|
|
},
|
|
Exit,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct IdentityRecycler {
|
|
sender: IpcSender<WebGPUMsg>,
|
|
self_sender: IpcSender<(Option<ErrorScopeId>, WebGPURequest)>,
|
|
}
|
|
|
|
pub struct IdentityRecyclerFactory {
|
|
pub sender: IpcSender<WebGPUMsg>,
|
|
pub self_sender: IpcSender<(Option<ErrorScopeId>, 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) -> Self::Input {
|
|
log::debug!("process {} {:?}", $st, id);
|
|
//debug_assert_eq!(id.unzip().2, backend);
|
|
id
|
|
}
|
|
fn free(&self, id: $id) {
|
|
log::debug!("free {} {:?}", $st, id);
|
|
let msg = $($var)*(id);
|
|
if self.sender.send(msg.clone()).is_err() {
|
|
log::error!("Failed to send {:?}", msg);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
impl_identity_handler!(AdapterId, "adapter", WebGPUMsg::FreeAdapter);
|
|
impl_identity_handler!(SurfaceId, "surface", WebGPUMsg::FreeSurface);
|
|
impl_identity_handler!(SamplerId, "sampler", WebGPUMsg::FreeSampler);
|
|
impl_identity_handler!(TextureId, "texture", WebGPUMsg::FreeTexture);
|
|
impl_identity_handler!(TextureViewId, "texture_view", WebGPUMsg::FreeTextureView);
|
|
impl_identity_handler!(BufferId, "buffer", WebGPUMsg::FreeBuffer);
|
|
impl_identity_handler!(BindGroupId, "bind_group", WebGPUMsg::FreeBindGroup);
|
|
impl_identity_handler!(SwapChainId, "swap_chain", WebGPUMsg::FreeSwapChain);
|
|
impl_identity_handler!(ShaderModuleId, "shader_module", WebGPUMsg::FreeShaderModule);
|
|
impl_identity_handler!(RenderBundleId, "render_bundle", WebGPUMsg::FreeRenderBundle);
|
|
impl_identity_handler!(
|
|
RenderPipelineId,
|
|
"render_pipeline",
|
|
WebGPUMsg::FreeRenderPipeline
|
|
);
|
|
impl_identity_handler!(
|
|
ComputePipelineId,
|
|
"compute_pipeline",
|
|
WebGPUMsg::FreeComputePipeline
|
|
);
|
|
impl_identity_handler!(
|
|
CommandBufferId,
|
|
"command_buffer",
|
|
WebGPUMsg::FreeCommandBuffer
|
|
);
|
|
impl_identity_handler!(
|
|
BindGroupLayoutId,
|
|
"bind_group_layout",
|
|
WebGPUMsg::FreeBindGroupLayout
|
|
);
|
|
impl_identity_handler!(
|
|
PipelineLayoutId,
|
|
"pipeline_layout",
|
|
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);
|
|
if self.sender.send(WebGPUMsg::FreeDevice(id)).is_err() {
|
|
log::error!("Failed to send FreeDevice({:?}) to script", id);
|
|
}
|
|
if self
|
|
.self_sender
|
|
.send((None, WebGPURequest::FreeDevice(id)))
|
|
.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,
|
|
IdentityRecycler: IdentityHandler<I>,
|
|
{
|
|
type Filter = IdentityRecycler;
|
|
fn spawn(&self, _min_index: u32) -> Self::Filter {
|
|
IdentityRecycler {
|
|
sender: self.sender.clone(),
|
|
self_sender: self.self_sender.clone(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl GlobalIdentityHandlerFactory for IdentityRecyclerFactory {}
|