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