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