script/dom/webgpu/
gpusampler.rs1use dom_struct::dom_struct;
6use webgpu_traits::{WebGPU, WebGPUDevice, WebGPURequest, WebGPUSampler};
7use wgpu_core::resource::SamplerDescriptor;
8
9use crate::conversions::Convert;
10use crate::dom::bindings::cell::DomRefCell;
11use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
12 GPUSamplerDescriptor, GPUSamplerMethods,
13};
14use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
15use crate::dom::bindings::root::DomRoot;
16use crate::dom::bindings::str::USVString;
17use crate::dom::globalscope::GlobalScope;
18use crate::dom::webgpu::gpudevice::GPUDevice;
19use crate::script_runtime::CanGc;
20
21#[dom_struct]
22pub(crate) struct GPUSampler {
23 reflector_: Reflector,
24 #[ignore_malloc_size_of = "defined in webgpu"]
25 #[no_trace]
26 channel: WebGPU,
27 label: DomRefCell<USVString>,
28 #[no_trace]
29 device: WebGPUDevice,
30 compare_enable: bool,
31 #[no_trace]
32 sampler: WebGPUSampler,
33}
34
35impl GPUSampler {
36 fn new_inherited(
37 channel: WebGPU,
38 device: WebGPUDevice,
39 compare_enable: bool,
40 sampler: WebGPUSampler,
41 label: USVString,
42 ) -> Self {
43 Self {
44 reflector_: Reflector::new(),
45 channel,
46 label: DomRefCell::new(label),
47 device,
48 sampler,
49 compare_enable,
50 }
51 }
52
53 pub(crate) fn new(
54 global: &GlobalScope,
55 channel: WebGPU,
56 device: WebGPUDevice,
57 compare_enable: bool,
58 sampler: WebGPUSampler,
59 label: USVString,
60 can_gc: CanGc,
61 ) -> DomRoot<Self> {
62 reflect_dom_object(
63 Box::new(GPUSampler::new_inherited(
64 channel,
65 device,
66 compare_enable,
67 sampler,
68 label,
69 )),
70 global,
71 can_gc,
72 )
73 }
74}
75
76impl GPUSampler {
77 pub(crate) fn id(&self) -> WebGPUSampler {
78 self.sampler
79 }
80
81 pub(crate) fn create(
83 device: &GPUDevice,
84 descriptor: &GPUSamplerDescriptor,
85 can_gc: CanGc,
86 ) -> DomRoot<GPUSampler> {
87 let sampler_id = device.global().wgpu_id_hub().create_sampler_id();
88 let compare_enable = descriptor.compare.is_some();
89 let desc = SamplerDescriptor {
90 label: (&descriptor.parent).convert(),
91 address_modes: [
92 descriptor.addressModeU.convert(),
93 descriptor.addressModeV.convert(),
94 descriptor.addressModeW.convert(),
95 ],
96 mag_filter: descriptor.magFilter.convert(),
97 min_filter: descriptor.minFilter.convert(),
98 mipmap_filter: descriptor.mipmapFilter.convert(),
99 lod_min_clamp: *descriptor.lodMinClamp,
100 lod_max_clamp: *descriptor.lodMaxClamp,
101 compare: descriptor.compare.map(Convert::convert),
102 anisotropy_clamp: 1,
103 border_color: None,
104 };
105
106 device
107 .channel()
108 .0
109 .send(WebGPURequest::CreateSampler {
110 device_id: device.id().0,
111 sampler_id,
112 descriptor: desc,
113 })
114 .expect("Failed to create WebGPU sampler");
115
116 let sampler = WebGPUSampler(sampler_id);
117
118 GPUSampler::new(
119 &device.global(),
120 device.channel().clone(),
121 device.id(),
122 compare_enable,
123 sampler,
124 descriptor.parent.label.clone(),
125 can_gc,
126 )
127 }
128}
129
130impl GPUSamplerMethods<crate::DomTypeHolder> for GPUSampler {
131 fn Label(&self) -> USVString {
133 self.label.borrow().clone()
134 }
135
136 fn SetLabel(&self, value: USVString) {
138 *self.label.borrow_mut() = value;
139 }
140}
141
142impl Drop for GPUSampler {
143 fn drop(&mut self) {
144 if let Err(e) = self
145 .channel
146 .0
147 .send(WebGPURequest::DropSampler(self.sampler.0))
148 {
149 warn!("Failed to send DropSampler ({:?}) ({})", self.sampler.0, e);
150 }
151 }
152}