script/dom/webgpu/
gpubindgrouplayout.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, 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#[dom_struct]
26pub(crate) struct GPUBindGroupLayout {
27    reflector_: Reflector,
28    #[ignore_malloc_size_of = "channels are hard"]
29    #[no_trace]
30    channel: WebGPU,
31    label: DomRefCell<USVString>,
32    #[no_trace]
33    bind_group_layout: WebGPUBindGroupLayout,
34}
35
36impl GPUBindGroupLayout {
37    fn new_inherited(
38        channel: WebGPU,
39        bind_group_layout: WebGPUBindGroupLayout,
40        label: USVString,
41    ) -> Self {
42        Self {
43            reflector_: Reflector::new(),
44            channel,
45            label: DomRefCell::new(label),
46            bind_group_layout,
47        }
48    }
49
50    pub(crate) fn new(
51        global: &GlobalScope,
52        channel: WebGPU,
53        bind_group_layout: WebGPUBindGroupLayout,
54        label: USVString,
55        can_gc: CanGc,
56    ) -> DomRoot<Self> {
57        reflect_dom_object(
58            Box::new(GPUBindGroupLayout::new_inherited(
59                channel,
60                bind_group_layout,
61                label,
62            )),
63            global,
64            can_gc,
65        )
66    }
67}
68
69impl GPUBindGroupLayout {
70    pub(crate) fn id(&self) -> WebGPUBindGroupLayout {
71        self.bind_group_layout
72    }
73
74    /// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
75    pub(crate) fn create(
76        device: &GPUDevice,
77        descriptor: &GPUBindGroupLayoutDescriptor,
78        can_gc: CanGc,
79    ) -> Fallible<DomRoot<GPUBindGroupLayout>> {
80        let entries = descriptor
81            .entries
82            .iter()
83            .map(|bgle| convert_bind_group_layout_entry(bgle, device))
84            .collect::<Fallible<Result<Vec<_>, _>>>()?;
85
86        let desc = match entries {
87            Ok(entries) => Some(BindGroupLayoutDescriptor {
88                label: (&descriptor.parent).convert(),
89                entries: Cow::Owned(entries),
90            }),
91            Err(error) => {
92                device.dispatch_error(error);
93                None
94            },
95        };
96
97        let bind_group_layout_id = device.global().wgpu_id_hub().create_bind_group_layout_id();
98        device
99            .channel()
100            .0
101            .send(WebGPURequest::CreateBindGroupLayout {
102                device_id: device.id().0,
103                bind_group_layout_id,
104                descriptor: desc,
105            })
106            .expect("Failed to create WebGPU BindGroupLayout");
107
108        let bgl = WebGPUBindGroupLayout(bind_group_layout_id);
109
110        Ok(GPUBindGroupLayout::new(
111            &device.global(),
112            device.channel().clone(),
113            bgl,
114            descriptor.parent.label.clone(),
115            can_gc,
116        ))
117    }
118}
119
120impl Drop for GPUBindGroupLayout {
121    fn drop(&mut self) {
122        if let Err(e) = self
123            .channel
124            .0
125            .send(WebGPURequest::DropBindGroupLayout(self.bind_group_layout.0))
126        {
127            warn!(
128                "Failed to send WebGPURequest::DropBindGroupLayout({:?}) ({})",
129                self.bind_group_layout.0, e
130            );
131        };
132    }
133}
134
135impl GPUBindGroupLayoutMethods<crate::DomTypeHolder> for GPUBindGroupLayout {
136    /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
137    fn Label(&self) -> USVString {
138        self.label.borrow().clone()
139    }
140
141    /// <https://gpuweb.github.io/gpuweb/#dom-gpuobjectbase-label>
142    fn SetLabel(&self, value: USVString) {
143        *self.label.borrow_mut() = value;
144    }
145}