script/dom/webgpu/
gpubindgroup.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use 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    /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
81    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    /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
140    fn Label(&self) -> USVString {
141        self.label.borrow().clone()
142    }
143
144    /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
145    fn SetLabel(&self, value: USVString) {
146        *self.label.borrow_mut() = value;
147    }
148}