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