script/dom/webgpu/
gpubindgrouplayout.rs1use std::borrow::Cow;
6
7use dom_struct::dom_struct;
8use webgpu_traits::{WebGPU, WebGPUBindGroupLayout, WebGPURequest};
9use wgpu_core::binding_model::BindGroupLayoutDescriptor;
10
11use crate::conversions::Convert;
12use crate::dom::bindings::cell::DomRefCell;
13use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
14 GPUBindGroupLayoutDescriptor, GPUBindGroupLayoutMethods,
15};
16use crate::dom::bindings::error::Fallible;
17use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
18use crate::dom::bindings::root::DomRoot;
19use crate::dom::bindings::str::USVString;
20use crate::dom::globalscope::GlobalScope;
21use crate::dom::webgpu::gpuconvert::convert_bind_group_layout_entry;
22use crate::dom::webgpu::gpudevice::GPUDevice;
23use crate::script_runtime::CanGc;
24
25#[derive(JSTraceable, MallocSizeOf)]
26struct DroppableGPUBindGroupLayout {
27 #[no_trace]
28 channel: WebGPU,
29 #[no_trace]
30 bind_group_layout: WebGPUBindGroupLayout,
31}
32
33impl Drop for DroppableGPUBindGroupLayout {
34 fn drop(&mut self) {
35 if let Err(e) = self
36 .channel
37 .0
38 .send(WebGPURequest::DropBindGroupLayout(self.bind_group_layout.0))
39 {
40 warn!(
41 "Failed to send WebGPURequest::DropBindGroupLayout({:?}) ({})",
42 self.bind_group_layout.0, e
43 );
44 };
45 }
46}
47
48#[dom_struct]
49pub(crate) struct GPUBindGroupLayout {
50 reflector_: Reflector,
51 label: DomRefCell<USVString>,
52 droppable: DroppableGPUBindGroupLayout,
53}
54
55impl GPUBindGroupLayout {
56 fn new_inherited(
57 channel: WebGPU,
58 bind_group_layout: WebGPUBindGroupLayout,
59 label: USVString,
60 ) -> Self {
61 Self {
62 reflector_: Reflector::new(),
63 label: DomRefCell::new(label),
64 droppable: DroppableGPUBindGroupLayout {
65 channel,
66 bind_group_layout,
67 },
68 }
69 }
70
71 pub(crate) fn new(
72 global: &GlobalScope,
73 channel: WebGPU,
74 bind_group_layout: WebGPUBindGroupLayout,
75 label: USVString,
76 can_gc: CanGc,
77 ) -> DomRoot<Self> {
78 reflect_dom_object(
79 Box::new(GPUBindGroupLayout::new_inherited(
80 channel,
81 bind_group_layout,
82 label,
83 )),
84 global,
85 can_gc,
86 )
87 }
88}
89
90impl GPUBindGroupLayout {
91 pub(crate) fn id(&self) -> WebGPUBindGroupLayout {
92 self.droppable.bind_group_layout
93 }
94
95 pub(crate) fn create(
97 device: &GPUDevice,
98 descriptor: &GPUBindGroupLayoutDescriptor,
99 can_gc: CanGc,
100 ) -> Fallible<DomRoot<GPUBindGroupLayout>> {
101 let entries = descriptor
102 .entries
103 .iter()
104 .map(|bgle| convert_bind_group_layout_entry(bgle, device))
105 .collect::<Fallible<Result<Vec<_>, _>>>()?;
106
107 let desc = match entries {
108 Ok(entries) => Some(BindGroupLayoutDescriptor {
109 label: (&descriptor.parent).convert(),
110 entries: Cow::Owned(entries),
111 }),
112 Err(error) => {
113 device.dispatch_error(error);
114 None
115 },
116 };
117
118 let bind_group_layout_id = device.global().wgpu_id_hub().create_bind_group_layout_id();
119 device
120 .channel()
121 .0
122 .send(WebGPURequest::CreateBindGroupLayout {
123 device_id: device.id().0,
124 bind_group_layout_id,
125 descriptor: desc,
126 })
127 .expect("Failed to create WebGPU BindGroupLayout");
128
129 let bgl = WebGPUBindGroupLayout(bind_group_layout_id);
130
131 Ok(GPUBindGroupLayout::new(
132 &device.global(),
133 device.channel().clone(),
134 bgl,
135 descriptor.parent.label.clone(),
136 can_gc,
137 ))
138 }
139}
140
141impl GPUBindGroupLayoutMethods<crate::DomTypeHolder> for GPUBindGroupLayout {
142 fn Label(&self) -> USVString {
144 self.label.borrow().clone()
145 }
146
147 fn SetLabel(&self, value: USVString) {
149 *self.label.borrow_mut() = value;
150 }
151}