1use super::{enums::GlParameter, WebGlRenderer, GlQueryKind, GlQueryResult, GlQueryName};
2use crate::errors::Error;
3use wasm_bindgen::{prelude::JsValue, JsCast};
4use web_sys::{WebGl2RenderingContext, WebGlRenderingContext, WebGlQuery};
5
6pub trait PartialWebGlGetParameter {
7 fn awsm_get_parameter_usize(&self, query: GlParameter) -> Result<usize, Error>;
8 fn awsm_get_parameter_vf32(&self, query: GlParameter) -> Result<Vec<f32>, Error>;
9}
10
11macro_rules! impl_context {
12 ($($type:ty { $($defs:tt)* })+) => {
13 $(impl PartialWebGlGetParameter for $type {
14 fn awsm_get_parameter_usize(&self, query:GlParameter) -> Result<usize, Error> {
15 self.get_parameter(query as u32)
16 .and_then(|value| {
17 value
18 .as_f64()
19 .map(|val| val as usize)
20 .ok_or(JsValue::null())
21 })
22 .map_err(|err| err.into())
23 }
24
25 fn awsm_get_parameter_vf32(&self, query:GlParameter) -> Result<Vec<f32>, Error> {
26 self.get_parameter(query as u32)
27 .map(|value| {
28 let value:js_sys::Float32Array = value.into();
29 value.to_vec()
30 })
31 .map_err(|err| err.into())
32 }
33
34 $($defs)*
35 })+
36 };
37}
38
39impl_context! {
40 WebGlRenderingContext{}
41 WebGl2RenderingContext{}
42}
43
44impl WebGlRenderer<WebGl2RenderingContext> {
45 pub fn create_query(&self) -> Result<WebGlQuery, Error> {
46 self.gl.create_query().ok_or(Error::from("Unable to create query"))
47 }
48
49 pub fn begin_query(&self, kind: GlQueryKind, query: &WebGlQuery) {
50 self.gl.begin_query(kind as u32, query);
51 }
52
53 pub fn end_query(&self, kind: GlQueryKind) {
54 self.gl.end_query(kind as u32);
55 }
56
57 pub fn delete_query(&self, query: WebGlQuery) {
58 self.gl.delete_query(Some(&query));
59 }
60
61 pub fn current_query(&self, kind: GlQueryKind) -> Option<WebGlQuery> {
62 let value = self.gl.get_query(kind as u32, GlQueryName::Current as u32);
63
64 if value.is_null() {
65 None
66 } else {
67 Some(value.unchecked_into())
68 }
69 }
70
71 pub fn query_available(&self, query: &WebGlQuery) -> Result<bool, Error> {
72 let value = self.gl.get_query_parameter(query, GlQueryResult::Available as u32);
73 let value = value.as_bool().ok_or(Error::from("Unable to get query result"))?;
74 Ok(value)
75 }
76
77 pub fn query_result(&self, query: &WebGlQuery) -> Result<u32, Error> {
78 let value = self.gl.get_query_parameter(query, GlQueryResult::Value as u32);
79 let value = value.as_f64().ok_or(Error::from("Unable to get query result"))?;
80 Ok(value as u32)
81 }
82}