script/dom/webgpu/
gpuqueryset.rs1use dom_struct::dom_struct;
6use js::context::{JSContext, NoGC};
7use script_bindings::cell::DomRefCell;
8use script_bindings::codegen::GenericBindings::WebGPUBinding::{GPUDeviceMethods, GPUQueryType};
9use script_bindings::error::{Error, Fallible};
10use script_bindings::reflector::{Reflector, reflect_dom_object};
11use script_bindings::root::DomRoot;
12use script_webgpu::gpuconvert::WebGPUConvert;
13use script_webgpu::traits::GPUQuerySetTrait;
14use webgpu_traits::{WebGPU, WebGPUQuerySet, WebGPURequest};
15
16use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
17 GPUQuerySetDescriptor, GPUQuerySetMethods,
18};
19use crate::dom::bindings::reflector::DomGlobal as _;
20use crate::dom::bindings::str::USVString;
21use crate::dom::types::{GPUDevice, GlobalScope};
22
23#[derive(JSTraceable, MallocSizeOf)]
24struct DroppableGPUQuerySet {
25 #[no_trace]
26 channel: WebGPU,
27 #[no_trace]
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(crate) struct GPUQuerySet {
48 reflector_: Reflector,
49 droppable: DroppableGPUQuerySet,
50 label: DomRefCell<USVString>,
51 r#type: GPUQueryType,
52 count: u32,
53}
54
55impl GPUQuerySet {
56 pub(crate) fn new_inherited(
57 label: USVString,
58 channel: WebGPU,
59 query_set: WebGPUQuerySet,
60 r#type: GPUQueryType,
61 count: u32,
62 ) -> Self {
63 GPUQuerySet {
64 reflector_: Reflector::new(),
65 label: DomRefCell::new(label),
66 droppable: DroppableGPUQuerySet { channel, query_set },
67 r#type,
68 count,
69 }
70 }
71
72 pub(crate) fn new(
73 cx: &mut JSContext,
74 global: &GlobalScope,
75 label: USVString,
76 channel: WebGPU,
77 query_set: WebGPUQuerySet,
78 r#type: GPUQueryType,
79 count: u32,
80 ) -> DomRoot<Self> {
81 reflect_dom_object(
82 cx,
83 Box::new(GPUQuerySet::new_inherited(
84 label, channel, query_set, r#type, count,
85 )),
86 global,
87 )
88 }
89
90 pub(crate) fn create(
92 cx: &mut JSContext,
93 device: &GPUDevice,
94 descriptor: &GPUQuerySetDescriptor,
95 ) -> Fallible<DomRoot<Self>> {
96 if descriptor.type_ == GPUQueryType::Timestamp &&
98 !device
99 .Features()
100 .wgpu_features()
101 .contains(wgpu_types::Features::TIMESTAMP_QUERY)
102 {
103 return Err(Error::Type(
105 c"The device does not support timestamp queries".to_owned(),
106 ));
107 }
108 let query_set_id = device.global().wgpu_id_hub().create_query_set_id();
110 let channel = device.channel();
112 if let Err(error) = channel.0.send(WebGPURequest::CreateQuerySet {
113 device_id: device.id().0,
114 query_set_id,
115 descriptor: descriptor.convert(),
116 }) {
117 warn!("Failed to send WebGPURequest::CreateQuerySet: {error}");
118 }
119 Ok(Self::new(
121 cx,
122 &device.global(),
123 descriptor.parent.label.clone(),
124 channel,
125 WebGPUQuerySet(query_set_id),
126 descriptor.type_,
128 descriptor.count,
130 ))
131 }
132
133 pub(crate) fn id(&self) -> WebGPUQuerySet {
134 self.droppable.query_set
135 }
136}
137
138impl GPUQuerySetMethods<crate::DomTypeHolder> for GPUQuerySet {
139 fn Destroy(&self) {
141 if let Err(error) = self
143 .droppable
144 .channel
145 .0
146 .send(WebGPURequest::DestroyQuerySet(self.id().0))
147 {
148 warn!(
149 "Failed to send WebGPURequest::DestroyQuerySet({:?}) ({error})",
150 self.id().0
151 );
152 }
153 }
154
155 fn Label(&self) -> USVString {
157 self.label.borrow().clone()
158 }
159
160 fn SetLabel(&self, no_gc: &NoGC, value: USVString) {
162 *self.label.safe_borrow_mut(no_gc) = value;
163 }
164
165 fn Type(&self) -> GPUQueryType {
167 self.r#type
168 }
169
170 fn Count(&self) -> u32 {
172 self.count
173 }
174}
175
176impl GPUQuerySetTrait for GPUQuerySet {
177 fn id(&self) -> WebGPUQuerySet {
178 self.id()
179 }
180}