script_webgpu/
gpuqueryset.rs1use std::marker::PhantomData;
5
6use dom_struct::dom_struct;
7use js::context::{JSContext, NoGC};
8use log::warn;
9use malloc_size_of_derive::MallocSizeOf;
10use script_bindings::DomTypes;
11use script_bindings::cell::DomRefCell;
12use script_bindings::codegen::GenericBindings::WebGPUBinding::{
13 GPUDeviceMethods, GPUQuerySetDescriptor, GPUQuerySetMethods, GPUQuerySetWrap, GPUQueryType,
14};
15use script_bindings::error::{Error, Fallible};
16use script_bindings::reflector::{DomGlobalGeneric, Reflector, reflect_dom_object_with_wrap};
17use script_bindings::root::DomRoot;
18use webgpu_traits::{WebGPU, WebGPUQuerySet, WebGPURequest};
19
20use crate::JSTraceable;
21use crate::dom::bindings::str::USVString;
22use crate::gpuconvert::WebGPUConvert;
23use crate::traits::{Equivalence, GPUDeviceTrait, WebGPUGlobalTrait};
24
25#[derive(MallocSizeOf)]
26struct DroppableGPUQuerySet {
27 channel: WebGPU,
28 query_set: WebGPUQuerySet,
29}
30
31impl Drop for DroppableGPUQuerySet {
32 fn drop(&mut self) {
33 if let Err(error) = self
34 .channel
35 .0
36 .send(WebGPURequest::DropQuerySet(self.query_set.0))
37 {
38 warn!(
39 "Failed to send WebGPURequest::DropQuerySet({:?}) ({error})",
40 self.query_set.0
41 );
42 }
43 }
44}
45
46#[dom_struct]
47pub struct GPUQuerySet<D: DomTypes> {
48 reflector_: Reflector,
49 #[no_trace]
50 droppable: DroppableGPUQuerySet,
51 label: DomRefCell<USVString>,
52 r#type: GPUQueryType,
53 count: u32,
54 #[no_trace = "PhantomData does not exist"]
55 phantom: PhantomData<D>,
56}
57
58impl<D> GPUQuerySet<D>
59where
60 D: Equivalence,
61 D::GPUDevice: GPUDeviceTrait<D>,
62 D::GlobalScope: WebGPUGlobalTrait,
63{
64 pub(crate) fn new_inherited(
65 label: USVString,
66 channel: WebGPU,
67 query_set: WebGPUQuerySet,
68 r#type: GPUQueryType,
69 count: u32,
70 ) -> Self {
71 GPUQuerySet {
72 reflector_: Reflector::new(),
73 label: DomRefCell::new(label),
74 droppable: DroppableGPUQuerySet { channel, query_set },
75 r#type,
76 count,
77 phantom: PhantomData,
78 }
79 }
80
81 pub(crate) fn new(
82 cx: &mut JSContext,
83 global: &D::GlobalScope,
84 label: USVString,
85 channel: WebGPU,
86 query_set: WebGPUQuerySet,
87 r#type: GPUQueryType,
88 count: u32,
89 ) -> DomRoot<Self> {
90 reflect_dom_object_with_wrap::<D, _, _>(
91 Box::new(GPUQuerySet::new_inherited(
92 label, channel, query_set, r#type, count,
93 )),
94 global,
95 cx,
96 GPUQuerySetWrap::<D>,
97 )
98 }
99
100 pub fn create(
102 cx: &mut JSContext,
103 device: &D::GPUDevice,
104 descriptor: &GPUQuerySetDescriptor,
105 ) -> Fallible<DomRoot<Self>> {
106 if descriptor.type_ == GPUQueryType::Timestamp &&
108 !device
109 .Features()
110 .wgpu_features()
111 .contains(wgpu_types::Features::TIMESTAMP_QUERY)
112 {
113 return Err(Error::Type(
115 c"The device does not support timestamp queries".to_owned(),
116 ));
117 }
118 let query_set_id = device
120 .global_from_reflector()
121 .global_wgpu_id_hub()
122 .create_query_set_id();
123 let channel = device.channel();
125 if let Err(error) = channel.0.send(WebGPURequest::CreateQuerySet {
126 device_id: device.id().0,
127 query_set_id,
128 descriptor: descriptor.convert(),
129 }) {
130 warn!("Failed to send WebGPURequest::CreateQuerySet: {error}");
131 }
132 Ok(Self::new(
134 cx,
135 &device.global_from_reflector(),
136 descriptor.parent.label.clone(),
137 channel,
138 WebGPUQuerySet(query_set_id),
139 descriptor.type_,
141 descriptor.count,
143 ))
144 }
145
146 pub(crate) fn id(&self) -> WebGPUQuerySet {
147 self.droppable.query_set
148 }
149}
150
151impl<D> GPUQuerySetMethods<D> for GPUQuerySet<D>
152where
153 D: Equivalence,
154 D::GPUDevice: GPUDeviceTrait<D>,
155 D::GlobalScope: WebGPUGlobalTrait,
156{
157 fn Destroy(&self) {
159 if let Err(error) = self
161 .droppable
162 .channel
163 .0
164 .send(WebGPURequest::DestroyQuerySet(self.id().0))
165 {
166 warn!(
167 "Failed to send WebGPURequest::DestroyQuerySet({:?}) ({error})",
168 self.id().0
169 );
170 }
171 }
172
173 fn Label(&self) -> USVString {
175 self.label.borrow().clone()
176 }
177
178 fn SetLabel(&self, no_gc: &NoGC, value: USVString) {
180 *self.label.safe_borrow_mut(no_gc) = value;
181 }
182
183 fn Type(&self) -> GPUQueryType {
185 self.r#type
186 }
187
188 fn Count(&self) -> u32 {
190 self.count
191 }
192}