script_webgpu/
gpubindgroup.rs1use std::borrow::Cow;
6
7use dom_struct::dom_struct;
8use js::context::{JSContext, NoGC};
9use jstraceable_derive::JSTraceable;
10use log::warn;
11use malloc_size_of_derive::MallocSizeOf;
12use script_bindings::DomTypes;
13use script_bindings::cell::DomRefCell;
14use script_bindings::codegen::GenericBindings::WebGPUBinding::{
15 GPUBindGroupDescriptor, GPUBindGroupMethods, GPUBindGroupWrap,
16};
17use script_bindings::interfaces::PromiseHelpers;
18use script_bindings::reflector::{DomGlobalGeneric, Reflector, reflect_dom_object_with_wrap};
19use webgpu_traits::{BindGroupDescriptor, WebGPU, WebGPUBindGroup, WebGPUDevice, WebGPURequest};
20
21use crate::dom::bindings::root::{Dom, DomRoot};
22use crate::dom::bindings::str::USVString;
23use crate::gpubindgrouplayout::GPUBindGroupLayout;
24use crate::gpuconvert::{WebGPUConvert, convert_bind_group_entry};
25use crate::traits::{Equivalence, WebGPUGlobalTrait, WebGPUPromise};
26
27#[derive(JSTraceable, MallocSizeOf)]
28struct DroppableGPUBindGroup {
29 #[no_trace]
30 channel: WebGPU,
31 #[no_trace]
32 bind_group: WebGPUBindGroup,
33}
34
35impl Drop for DroppableGPUBindGroup {
36 fn drop(&mut self) {
37 if let Err(e) = self
38 .channel
39 .0
40 .send(WebGPURequest::DropBindGroup(self.bind_group.0))
41 {
42 warn!(
43 "Failed to send WebGPURequest::DropBindGroup({:?}) ({})",
44 self.bind_group.0, e
45 );
46 };
47 }
48}
49
50#[dom_struct]
51pub struct GPUBindGroup<D: DomTypes> {
52 reflector_: Reflector,
53 label: DomRefCell<USVString>,
54 #[no_trace]
55 device: WebGPUDevice,
56 layout: Dom<GPUBindGroupLayout<D>>,
57 droppable: DroppableGPUBindGroup,
58}
59
60impl<D: Equivalence> GPUBindGroup<D> {
61 fn new_inherited(
62 channel: WebGPU,
63 bind_group: WebGPUBindGroup,
64 device: WebGPUDevice,
65 layout: &GPUBindGroupLayout<D>,
66 label: USVString,
67 ) -> Self {
68 Self {
69 reflector_: Reflector::new(),
70 label: DomRefCell::new(label),
71 device,
72 layout: Dom::from_ref(layout),
73 droppable: DroppableGPUBindGroup {
74 channel,
75 bind_group,
76 },
77 }
78 }
79
80 pub(crate) fn new(
81 cx: &mut JSContext,
82 global: &D::GlobalScope,
83 channel: WebGPU,
84 bind_group: WebGPUBindGroup,
85 device: WebGPUDevice,
86 layout: &GPUBindGroupLayout<D>,
87 label: USVString,
88 ) -> DomRoot<Self> {
89 reflect_dom_object_with_wrap::<D, _, _>(
90 Box::new(GPUBindGroup::new_inherited(
91 channel, bind_group, device, layout, label,
92 )),
93 global,
94 cx,
95 GPUBindGroupWrap::<D>,
96 )
97 }
98}
99
100impl<D> GPUBindGroup<D>
101where
102 D: Equivalence,
103 <D::Promise as PromiseHelpers<D>>::StackRoot: WebGPUPromise<D>,
104{
105 pub(crate) fn id(&self) -> &WebGPUBindGroup {
106 &self.droppable.bind_group
107 }
108
109 pub(crate) fn create(
111 cx: &mut JSContext,
112 device: &D::GPUDevice,
113 descriptor: &GPUBindGroupDescriptor<D>,
114 ) -> DomRoot<GPUBindGroup<D>> {
115 let entries = descriptor
116 .entries
117 .iter()
118 .map(|bind| convert_bind_group_entry(cx, bind))
119 .collect::<Vec<_>>();
120
121 let desc = BindGroupDescriptor {
122 label: (&descriptor.parent).convert(),
123 layout: descriptor.layout.id().0,
124 entries: Cow::Owned(entries),
125 };
126
127 let bind_group_id = <D::GPUDevice as DomGlobalGeneric<D>>::global_from_reflector(device)
128 .global_wgpu_id_hub()
129 .create_bind_group_id();
130 device
131 .channel()
132 .0
133 .send(WebGPURequest::CreateBindGroup {
134 device_id: device.id().0,
135 bind_group_id,
136 descriptor: desc,
137 })
138 .expect("Failed to create WebGPU BindGroup");
139
140 let bind_group = WebGPUBindGroup(bind_group_id);
141
142 let global = <D::GPUDevice as DomGlobalGeneric<D>>::global_from_reflector(device);
143 GPUBindGroup::new(
144 cx,
145 &*global,
146 device.channel(),
147 bind_group,
148 device.id(),
149 &descriptor.layout,
150 descriptor.parent.label.clone(),
151 )
152 }
153}
154
155impl<D: DomTypes> GPUBindGroupMethods<D> for GPUBindGroup<D> {
156 fn Label(&self) -> USVString {
158 self.label.borrow().clone()
159 }
160
161 fn SetLabel(&self, no_gc: &NoGC, value: USVString) {
163 *self.label.safe_borrow_mut(no_gc) = value;
164 }
165}