diff --git a/libs/gfx/include/psemek/gfx/query.hpp b/libs/gfx/include/psemek/gfx/query.hpp index e40f426b..bd919575 100644 --- a/libs/gfx/include/psemek/gfx/query.hpp +++ b/libs/gfx/include/psemek/gfx/query.hpp @@ -1,86 +1,33 @@ #pragma once #include +#include #include namespace psemek::gfx { - struct query_array + struct query_pool { - query_array() = default; - query_array(std::size_t size); - ~query_array(); + struct scope + { + GLenum target; + + ~scope(); + }; + + scope begin(GLenum target, util::function callback); + + void poll(); std::size_t size() const { return ids_.size(); } - void resize(std::size_t size); - - GLuint operator[](std::size_t i) const; - - struct [[maybe_unused]] query_scope - { - GLenum type; - - query_scope(GLenum type) - : type{type} - {} - - query_scope(query_scope const &) = delete; - query_scope(query_scope &&) = delete; - - query_scope & operator = (query_scope const &) = delete; - query_scope & operator = (query_scope &&) = delete; - - ~query_scope() - { - gl::EndQuery(type); - } - }; - - query_scope begin(std::size_t i, GLenum type) const; + ~query_pool(); private: std::vector ids_; + std::vector> callbacks_; }; - inline query_array::query_array(std::size_t size) - : ids_(size) - { - gl::GenQueries(size, ids_.data()); - } - - inline query_array::~query_array() - { - gl::DeleteQueries(ids_.size(), ids_.data()); - ids_.clear(); - } - - inline void query_array::resize(std::size_t size) - { - if (size < ids_.size()) - { - gl::DeleteQueries(ids_.size() - size, ids_.data() + size); - ids_.resize(size); - } - else if (size > ids_.size()) - { - std::size_t old_size = ids_.size(); - ids_.resize(size); - gl::GenQueries(size - old_size, ids_.data() + old_size); - } - } - - inline GLuint query_array::operator[](std::size_t i) const - { - return ids_[i]; - } - - inline query_array::query_scope query_array::begin(std::size_t i, GLenum type) const - { - gl::BeginQuery(type, ids_[i]); - return query_scope{type}; - } - } diff --git a/libs/gfx/source/query.cpp b/libs/gfx/source/query.cpp new file mode 100644 index 00000000..b71f5967 --- /dev/null +++ b/libs/gfx/source/query.cpp @@ -0,0 +1,58 @@ +#include + +#include + +namespace psemek::gfx +{ + + query_pool::scope::~scope() + { + gl::EndQuery(target); + } + + query_pool::scope query_pool::begin(GLenum target, util::function callback) + { + std::optional index; + for (std::size_t i = 0; i < ids_.size(); ++i) + { + if (callbacks_[i]) continue; + index = i; + break; + } + + if (!index) + { + index = ids_.size(); + gl::GenQueries(1, &ids_.emplace_back()); + callbacks_.emplace_back(); + } + + callbacks_[*index] = std::move(callback); + gl::BeginQuery(target, ids_[*index]); + + return {target}; + } + + void query_pool::poll() + { + for (std::size_t i = 0; i < ids_.size(); ++i) + { + if (!callbacks_[i]) continue; + + GLint result; + gl::GetQueryObjectiv(ids_[i], gl::QUERY_RESULT_AVAILABLE, &result); + if (result == gl::TRUE) + { + gl::GetQueryObjectiv(ids_[i], gl::QUERY_RESULT, &result); + callbacks_[i](result); + callbacks_[i].reset(); + } + } + } + + query_pool::~query_pool() + { + gl::DeleteQueries(ids_.size(), ids_.data()); + } + +}