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