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::interfaces::PromiseHelpers;
17use script_bindings::reflector::{DomGlobalGeneric, Reflector, reflect_dom_object_with_wrap};
18use webgpu_traits::{SamplerDescriptor, WebGPU, WebGPUDevice, WebGPURequest, WebGPUSampler};
19
20use crate::JSTraceable;
21use crate::dom::bindings::root::DomRoot;
22use crate::dom::bindings::str::USVString;
23use crate::gpuconvert::WebGPUConvert;
24use crate::traits::{Equivalence, WebGPUGlobalTrait, WebGPUPromise};
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 cx,
87 Box::new(GPUSampler::new_inherited(
88 channel,
89 device,
90 compare_enable,
91 sampler,
92 label,
93 )),
94 global,
95 GPUSamplerWrap::<D>,
96 )
97 }
98}
99
100impl<D> GPUSampler<D>
101where
102 D: Equivalence,
103 <D::Promise as PromiseHelpers<D>>::StackRoot: WebGPUPromise<D>,
104{
105 pub(crate) fn id(&self) -> WebGPUSampler {
106 self.dropppable.sampler
107 }
108
109 pub(crate) fn create(
111 cx: &mut JSContext,
112 device: &D::GPUDevice,
113 descriptor: &GPUSamplerDescriptor,
114 ) -> DomRoot<GPUSampler<D>> {
115 let sampler_id = device
116 .global_from_reflector()
117 .global_wgpu_id_hub()
118 .create_sampler_id();
119 let compare_enable = descriptor.compare.is_some();
120 let desc = SamplerDescriptor {
121 label: (&descriptor.parent).convert(),
122 address_modes: [
123 descriptor.addressModeU.convert(),
124 descriptor.addressModeV.convert(),
125 descriptor.addressModeW.convert(),
126 ],
127 mag_filter: descriptor.magFilter.convert(),
128 min_filter: descriptor.minFilter.convert(),
129 mipmap_filter: descriptor.mipmapFilter.convert(),
130 lod_min_clamp: *descriptor.lodMinClamp,
131 lod_max_clamp: *descriptor.lodMaxClamp,
132 compare: descriptor.compare.map(WebGPUConvert::convert),
133 anisotropy_clamp: 1,
134 border_color: None,
135 };
136
137 device
138 .channel()
139 .0
140 .send(WebGPURequest::CreateSampler {
141 device_id: device.id().0,
142 sampler_id,
143 descriptor: desc,
144 })
145 .expect("Failed to create WebGPU sampler");
146
147 let sampler = WebGPUSampler(sampler_id);
148
149 GPUSampler::new(
150 cx,
151 &*device.global_from_reflector(),
152 device.channel(),
153 device.id(),
154 compare_enable,
155 sampler,
156 descriptor.parent.label.clone(),
157 )
158 }
159}
160
161impl<D: DomTypes> GPUSamplerMethods<D> for GPUSampler<D> {
162 fn Label(&self) -> USVString {
164 self.label.borrow().clone()
165 }
166
167 fn SetLabel(&self, no_gc: &NoGC, value: USVString) {
169 *self.label.safe_borrow_mut(no_gc) = value;
170 }
171}