fyrox_graphics_gl/
query.rs1use crate::server::GlGraphicsServer;
22use fyrox_graphics::{
23 error::FrameworkError,
24 query::{GpuQueryTrait, QueryKind, QueryResult},
25};
26use glow::HasContext;
27use std::{cell::Cell, rc::Weak};
28
29#[derive(Debug)]
30pub struct GlQuery {
31 id: glow::Query,
32 pipeline_state: Weak<GlGraphicsServer>,
33 active_query: Cell<Option<QueryKind>>,
34}
35
36impl GlQuery {
37 pub fn new(server: &GlGraphicsServer) -> Result<Self, FrameworkError> {
38 let mut inner = server.state.borrow_mut();
39 let id = if let Some(existing) = inner.queries.pop() {
40 existing
41 } else {
42 unsafe { server.gl.create_query()? }
43 };
44 Ok(Self {
45 id,
46 pipeline_state: server.weak(),
47 active_query: Default::default(),
48 })
49 }
50}
51
52impl GpuQueryTrait for GlQuery {
53 fn begin(&self, kind: QueryKind) {
54 if let Some(pipeline_state) = self.pipeline_state.upgrade() {
55 unsafe {
56 pipeline_state.gl.begin_query(kind as u32, self.id);
57 }
58
59 self.active_query.set(Some(kind));
60 }
61 }
62
63 fn end(&self) {
64 if let Some(active_query) = self.active_query.get() {
65 if let Some(pipeline_state) = self.pipeline_state.upgrade() {
66 unsafe {
67 pipeline_state.gl.end_query(active_query as u32);
68 }
69 }
70 }
71 }
72
73 fn is_started(&self) -> bool {
74 self.active_query.get().is_some()
75 }
76
77 fn try_get_result(&self) -> Option<QueryResult> {
78 let pipeline_state = self.pipeline_state.upgrade()?;
79 let active_query = self.active_query.get()?;
80 unsafe {
81 let is_ready = pipeline_state
82 .gl
83 .get_query_parameter_u32(self.id, glow::QUERY_RESULT_AVAILABLE)
84 > 0;
85 if is_ready {
86 let query_result = pipeline_state
87 .gl
88 .get_query_parameter_u32(self.id, glow::QUERY_RESULT);
89 match active_query {
90 QueryKind::SamplesPassed => Some(QueryResult::SamplesPassed(query_result)),
91 QueryKind::AnySamplesPassed => {
92 Some(QueryResult::AnySamplesPassed(query_result > 0))
93 }
94 }
95 } else {
96 None
97 }
98 }
99 }
100}
101
102impl Drop for GlQuery {
103 fn drop(&mut self) {
104 if let Some(pipeline_state) = self.pipeline_state.upgrade() {
105 pipeline_state.state.borrow_mut().queries.push(self.id);
106 }
107 }
108}