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