awsm_web/webgl/
query.rs

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}