Replace query_array with a more useful query_poll

This commit is contained in:
Nikita Lisitsa 2022-04-21 23:16:45 +03:00
parent 86296209c8
commit 30b3536d72
2 changed files with 72 additions and 67 deletions

View file

@ -1,86 +1,33 @@
#pragma once
#include <psemek/gfx/gl.hpp>
#include <psemek/util/function.hpp>
#include <vector>
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<void(GLint)> 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<GLuint> ids_;
std::vector<util::function<void(GLint)>> 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};
}
}

58
libs/gfx/source/query.cpp Normal file
View file

@ -0,0 +1,58 @@
#include <psemek/gfx/query.hpp>
#include <optional>
namespace psemek::gfx
{
query_pool::scope::~scope()
{
gl::EndQuery(target);
}
query_pool::scope query_pool::begin(GLenum target, util::function<void(GLint)> callback)
{
std::optional<std::size_t> 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());
}
}