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_with_cx};
11use script_bindings::root::DomRoot;
12use webgpu_traits::{WebGPU, WebGPUQuerySet, WebGPURequest};
13
14use crate::conversions::Convert;
15use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
16 GPUQuerySetDescriptor, GPUQuerySetMethods,
17};
18use crate::dom::bindings::reflector::DomGlobal as _;
19use crate::dom::bindings::str::USVString;
20use crate::dom::types::{GPUDevice, GlobalScope};
21
22#[derive(JSTraceable, MallocSizeOf)]
23struct DroppableGPUQuerySet {
24 #[no_trace]
25 channel: WebGPU,
26 #[no_trace]
27 query_set: WebGPUQuerySet,
28}
29
30impl Drop for DroppableGPUQuerySet {
31 fn drop(&mut self) {
32 if let Err(error) = self
33 .channel
34 .0
35 .send(WebGPURequest::DropQuerySet(self.query_set.0))
36 {
37 warn!(
38 "Failed to send WebGPURequest::DropQuerySet({:?}) ({error})",
39 self.query_set.0
40 );
41 }
42 }
43}
44
45#[dom_struct]
46pub(crate) struct GPUQuerySet {
47 reflector_: Reflector,
48 droppable: DroppableGPUQuerySet,
49 label: DomRefCell<USVString>,
50 r#type: GPUQueryType,
51 count: u32,
52}
53
54impl GPUQuerySet {
55 pub(crate) fn new_inherited(
56 label: USVString,
57 channel: WebGPU,
58 query_set: WebGPUQuerySet,
59 r#type: GPUQueryType,
60 count: u32,
61 ) -> Self {
62 GPUQuerySet {
63 reflector_: Reflector::new(),
64 label: DomRefCell::new(label),
65 droppable: DroppableGPUQuerySet { channel, query_set },
66 r#type,
67 count,
68 }
69 }
70
71 pub(crate) fn new(
72 cx: &mut JSContext,
73 global: &GlobalScope,
74 label: USVString,
75 channel: WebGPU,
76 query_set: WebGPUQuerySet,
77 r#type: GPUQueryType,
78 count: u32,
79 ) -> DomRoot<Self> {
80 reflect_dom_object_with_cx(
81 Box::new(GPUQuerySet::new_inherited(
82 label, channel, query_set, r#type, count,
83 )),
84 global,
85 cx,
86 )
87 }
88
89 pub(crate) fn create(
91 cx: &mut JSContext,
92 device: &GPUDevice,
93 descriptor: &GPUQuerySetDescriptor,
94 ) -> Fallible<DomRoot<Self>> {
95 if descriptor.type_ == GPUQueryType::Timestamp &&
97 !device
98 .Features()
99 .wgpu_features()
100 .contains(wgpu_types::Features::TIMESTAMP_QUERY)
101 {
102 return Err(Error::Type(
104 c"The device does not support timestamp queries".to_owned(),
105 ));
106 }
107 let query_set_id = device.global().wgpu_id_hub().create_query_set_id();
109 let channel = device.channel();
111 if let Err(error) = channel.0.send(WebGPURequest::CreateQuerySet {
112 device_id: device.id().0,
113 query_set_id,
114 descriptor: descriptor.convert(),
115 }) {
116 warn!("Failed to send WebGPURequest::CreateQuerySet: {error}");
117 }
118 Ok(Self::new(
120 cx,
121 &device.global(),
122 descriptor.parent.label.clone(),
123 channel,
124 WebGPUQuerySet(query_set_id),
125 descriptor.type_,
127 descriptor.count,
129 ))
130 }
131
132 pub(crate) fn id(&self) -> WebGPUQuerySet {
133 self.droppable.query_set
134 }
135}
136
137impl GPUQuerySetMethods<crate::DomTypeHolder> for GPUQuerySet {
138 fn Destroy(&self) {
140 }
143
144 fn Label(&self) -> USVString {
146 self.label.borrow().clone()
147 }
148
149 fn SetLabel(&self, no_gc: &NoGC, value: USVString) {
151 *self.label.safe_borrow_mut(no_gc) = value;
152 }
153
154 fn Type(&self) -> GPUQueryType {
156 self.r#type
157 }
158
159 fn Count(&self) -> u32 {
161 self.count
162 }
163}