Decouple GL resources from App::I

This commit is contained in:
2026-06-17 18:00:43 +02:00
parent 62984509ba
commit bc9ba75e49
3 changed files with 74 additions and 37 deletions

View File

@@ -0,0 +1,37 @@
#pragma once
#include "app.h"
#include <future>
#include <utility>
namespace pp::renderer::gl {
struct RenderRuntimeDispatch
{
AppRuntime* runtime = nullptr;
[[nodiscard]] bool is_render_thread() const noexcept
{
return runtime != nullptr && runtime->is_render_thread();
}
template<typename T>
std::future<void> render_task_async(T task, bool unique = false) const
{
return runtime->render_task_async(std::move(task), unique);
}
template<typename T>
void render_task(T task) const
{
runtime->render_task(std::move(task));
}
};
[[nodiscard]] inline RenderRuntimeDispatch render_runtime_dispatch() noexcept
{
return RenderRuntimeDispatch { &App::I->runtime() };
}
} // namespace pp::renderer::gl

View File

@@ -2,12 +2,12 @@
#include "log.h" #include "log.h"
#include "rtt.h" #include "rtt.h"
#include "util.h" #include "util.h"
#include "app.h"
#include "legacy_gl_framebuffer_dispatch.h" #include "legacy_gl_framebuffer_dispatch.h"
#include "legacy_gl_pixel_buffer_dispatch.h" #include "legacy_gl_pixel_buffer_dispatch.h"
#include "legacy_gl_renderbuffer_dispatch.h" #include "legacy_gl_renderbuffer_dispatch.h"
#include "legacy_gl_texture_dispatch.h" #include "legacy_gl_texture_dispatch.h"
#include "legacy_ui_gl_dispatch.h" #include "legacy_ui_gl_dispatch.h"
#include "renderer_gl/render_runtime_dispatch.h"
#include "renderer_gl/opengl_capabilities.h" #include "renderer_gl/opengl_capabilities.h"
#include <cstdint> #include <cstdint>
@@ -76,7 +76,7 @@ bool RTT::resize(int width, int height)
bool ret = false; bool ret = false;
RTT new_rtt; RTT new_rtt;
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
ret = new_rtt.create(width, height, -1, int_fmt, rboID != 0); ret = new_rtt.create(width, height, -1, int_fmt, rboID != 0);
if (!ret) if (!ret)
@@ -121,7 +121,7 @@ void RTT::destroy()
{ {
if (!valid()) if (!valid())
return; return;
App::I->render_task_async([rboID=rboID, texID=texID, fboID=fboID] pp::renderer::gl::render_runtime_dispatch().render_task_async([rboID=rboID, texID=texID, fboID=fboID]
{ {
if (rboID) if (rboID)
{ {
@@ -159,7 +159,7 @@ void RTT::copy(const RTT & source)
{ {
if (!valid() || !source.valid()) if (!valid() || !source.valid())
return; return;
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
const auto status = pp::renderer::gl::blit_opengl_framebuffer( const auto status = pp::renderer::gl::blit_opengl_framebuffer(
pp::renderer::gl::OpenGlFramebufferBlit { pp::renderer::gl::OpenGlFramebufferBlit {
@@ -180,7 +180,7 @@ void RTT::copy(const RTT& source, const glm::vec4& rect)
{ {
if (!valid() || !source.valid()) if (!valid() || !source.valid())
return; return;
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
auto r = rect_intersection(rect, { 0, 0, w, h }); auto r = rect_intersection(rect, { 0, 0, w, h });
const auto status = pp::renderer::gl::blit_opengl_framebuffer( const auto status = pp::renderer::gl::blit_opengl_framebuffer(
@@ -237,7 +237,7 @@ bool RTT::create(int width, int height, int tex)
bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format, bool depth_buffer /*= false*/) bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format, bool depth_buffer /*= false*/)
{ {
std::uint32_t status = 0; std::uint32_t status = 0;
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
// Destroy any previously created object // Destroy any previously created object
destroy(); destroy();
@@ -326,7 +326,7 @@ bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format,
void RTT::bindFramebuffer() void RTT::bindFramebuffer()
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
#ifdef _DEBUG #ifdef _DEBUG
if (bound) if (bound)
{ {
@@ -351,7 +351,7 @@ void RTT::bindFramebuffer()
void RTT::unbindFramebuffer() void RTT::unbindFramebuffer()
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
if (!bound) if (!bound)
return; return;
const auto status = pp::renderer::gl::restore_opengl_framebuffer_binding( const auto status = pp::renderer::gl::restore_opengl_framebuffer_binding(
@@ -372,7 +372,7 @@ void RTT::unbindFramebuffer()
void RTT::clear(glm::vec4 color) void RTT::clear(glm::vec4 color)
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
const auto status = pp::renderer::gl::clear_opengl_render_target( const auto status = pp::renderer::gl::clear_opengl_render_target(
pp::renderer::gl::OpenGlDefaultClear { pp::renderer::gl::OpenGlDefaultClear {
.color = { color.r, color.g, color.b, color.a }, .color = { color.r, color.g, color.b, color.a },
@@ -389,7 +389,7 @@ void RTT::clear(glm::vec4 color)
void RTT::clear_mask(glm::bool4 mask, glm::vec4 color) void RTT::clear_mask(glm::bool4 mask, glm::vec4 color)
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
const auto status = pp::renderer::gl::clear_opengl_color_buffer_with_write_mask( const auto status = pp::renderer::gl::clear_opengl_color_buffer_with_write_mask(
pp::renderer::gl::OpenGlColorMaskedClear { pp::renderer::gl::OpenGlColorMaskedClear {
.mask = { .mask = {
@@ -438,7 +438,7 @@ bool RTT::readPixelsRgba8(int x, int y, int width, int height, void* buffer) con
return false; return false;
bool ret = true; bool ret = true;
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
const auto readback = pp::renderer::gl::rgba8_readback_format(); const auto readback = pp::renderer::gl::rgba8_readback_format();
const auto status = pp::renderer::gl::readback_opengl_framebuffer( const auto status = pp::renderer::gl::readback_opengl_framebuffer(
@@ -489,7 +489,7 @@ uint8_t* RTT::readTextureData(uint8_t* buffer) const noexcept
return nullptr; return nullptr;
if (!buffer) if (!buffer)
buffer = createBuffer(); buffer = createBuffer();
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
const auto readback = pp::renderer::gl::rgba8_readback_format(); const auto readback = pp::renderer::gl::rgba8_readback_format();
const auto status = pp::renderer::gl::readback_opengl_framebuffer( const auto status = pp::renderer::gl::readback_opengl_framebuffer(
@@ -513,7 +513,7 @@ float* RTT::readTextureDataFloat(float* buffer) const noexcept
return nullptr; return nullptr;
if (!buffer) if (!buffer)
buffer = createBufferFloat(); buffer = createBufferFloat();
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
const auto readback = pp::renderer::gl::rgba32f_readback_format(); const auto readback = pp::renderer::gl::rgba32f_readback_format();
const auto status = pp::renderer::gl::readback_opengl_framebuffer( const auto status = pp::renderer::gl::readback_opengl_framebuffer(
@@ -552,7 +552,7 @@ float * RTT::createBufferFloat() const noexcept
void RTT::bindTexture() void RTT::bindTexture()
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
pp::legacy::gl_texture::bind_texture_2d( pp::legacy::gl_texture::bind_texture_2d(
static_cast<std::uint32_t>(texID), static_cast<std::uint32_t>(texID),
"RTT::bindTexture()"); "RTT::bindTexture()");
@@ -560,7 +560,7 @@ void RTT::bindTexture()
void RTT::unbindTexture() void RTT::unbindTexture()
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
pp::legacy::gl_texture::bind_texture_2d( pp::legacy::gl_texture::bind_texture_2d(
0U, 0U,
"RTT::unbindTexture()"); "RTT::unbindTexture()");
@@ -616,7 +616,7 @@ PBO::~PBO() noexcept
bool PBO::create() noexcept bool PBO::create() noexcept
{ {
App::I->render_task([this] { pp::renderer::gl::render_runtime_dispatch().render_task([this] {
const auto result = pp::renderer::gl::allocate_opengl_pixel_buffer( const auto result = pp::renderer::gl::allocate_opengl_pixel_buffer(
pp::legacy::gl_pixel_buffer::pixel_buffer_allocation_dispatch()); pp::legacy::gl_pixel_buffer::pixel_buffer_allocation_dispatch());
if (!result.ok()) { if (!result.ok()) {
@@ -631,7 +631,7 @@ bool PBO::create() noexcept
bool PBO::create(RTT& rtt) noexcept bool PBO::create(RTT& rtt) noexcept
{ {
App::I->render_task([this, &rtt] { pp::renderer::gl::render_runtime_dispatch().render_task([this, &rtt] {
width = rtt.getWidth(); width = rtt.getWidth();
height = rtt.getHeight(); height = rtt.getHeight();
rtt.bindFramebuffer(); rtt.bindFramebuffer();
@@ -655,7 +655,7 @@ void PBO::destroy() noexcept
{ {
if (buffer_id) if (buffer_id)
{ {
App::I->render_task_async([id=buffer_id] { pp::renderer::gl::render_runtime_dispatch().render_task_async([id=buffer_id] {
const auto status = pp::renderer::gl::delete_opengl_pixel_buffer( const auto status = pp::renderer::gl::delete_opengl_pixel_buffer(
id, id,
pp::legacy::gl_pixel_buffer::pixel_buffer_delete_dispatch()); pp::legacy::gl_pixel_buffer::pixel_buffer_delete_dispatch());
@@ -673,7 +673,7 @@ void PBO::destroy() noexcept
glm::uint8_t* PBO::map() noexcept glm::uint8_t* PBO::map() noexcept
{ {
App::I->render_task([this] { pp::renderer::gl::render_runtime_dispatch().render_task([this] {
const auto result = pp::renderer::gl::map_opengl_pixel_buffer( const auto result = pp::renderer::gl::map_opengl_pixel_buffer(
buffer_id, buffer_id,
width, width,
@@ -692,7 +692,7 @@ glm::uint8_t* PBO::map() noexcept
void PBO::unmap() noexcept void PBO::unmap() noexcept
{ {
App::I->render_task([this] { pp::renderer::gl::render_runtime_dispatch().render_task([this] {
const auto status = pp::renderer::gl::unmap_opengl_pixel_buffer( const auto status = pp::renderer::gl::unmap_opengl_pixel_buffer(
buffer_id, buffer_id,
pp::legacy::gl_pixel_buffer::pixel_buffer_unmap_dispatch()); pp::legacy::gl_pixel_buffer::pixel_buffer_unmap_dispatch());

View File

@@ -2,10 +2,10 @@
#include "log.h" #include "log.h"
#include "texture.h" #include "texture.h"
#include "util.h" #include "util.h"
#include "app.h"
#include "legacy_gl_framebuffer_dispatch.h" #include "legacy_gl_framebuffer_dispatch.h"
#include "legacy_gl_sampler_dispatch.h" #include "legacy_gl_sampler_dispatch.h"
#include "legacy_gl_texture_dispatch.h" #include "legacy_gl_texture_dispatch.h"
#include "renderer_gl/render_runtime_dispatch.h"
#include "renderer_gl/opengl_capabilities.h" #include "renderer_gl/opengl_capabilities.h"
#include <cstdint> #include <cstdint>
@@ -41,7 +41,7 @@ void TextureCube::operator=(TextureCube&& other) noexcept
bool TextureCube::create(int resolution) noexcept bool TextureCube::create(int resolution) noexcept
{ {
App::I->render_task([this, resolution] pp::renderer::gl::render_runtime_dispatch().render_task([this, resolution]
{ {
destroy(); destroy();
m_resolution = resolution; m_resolution = resolution;
@@ -67,7 +67,7 @@ void TextureCube::destroy() noexcept
{ {
if (m_cubetex_id) if (m_cubetex_id)
{ {
App::I->render_task([f=m_faces, id=m_cubetex_id] pp::renderer::gl::render_runtime_dispatch().render_task([f=m_faces, id=m_cubetex_id]
{ {
std::array<std::uint32_t, 7> texture_ids {}; std::array<std::uint32_t, 7> texture_ids {};
for (std::size_t i = 0U; i < f.size(); ++i) for (std::size_t i = 0U; i < f.size(); ++i)
@@ -85,7 +85,7 @@ void TextureCube::destroy() noexcept
void TextureCube::bind() const noexcept void TextureCube::bind() const noexcept
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
pp::legacy::gl_texture::bind_texture_cube( pp::legacy::gl_texture::bind_texture_cube(
static_cast<std::uint32_t>(m_cubetex_id), static_cast<std::uint32_t>(m_cubetex_id),
"TextureCube::bind()"); "TextureCube::bind()");
@@ -139,7 +139,7 @@ Image Texture2D::get_image() const noexcept
{ {
Image ret; Image ret;
ret.create(m_width, m_height); ret.create(m_width, m_height);
App::I->render_task([&] pp::renderer::gl::render_runtime_dispatch().render_task([&]
{ {
const auto readback = pp::renderer::gl::readback_opengl_texture_2d( const auto readback = pp::renderer::gl::readback_opengl_texture_2d(
pp::renderer::gl::OpenGlTexture2DReadback { pp::renderer::gl::OpenGlTexture2DReadback {
@@ -205,7 +205,7 @@ bool Texture2D::create(int width, int height, GLint internal_format)
bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data) bool Texture2D::create(int width, int height, GLint internal_format, GLint format, const uint8_t* data)
{ {
App::I->render_task([=] pp::renderer::gl::render_runtime_dispatch().render_task([=]
{ {
destroy(); destroy();
const auto component_type = pp::renderer::gl::texture_upload_type_for_internal_format( const auto component_type = pp::renderer::gl::texture_upload_type_for_internal_format(
@@ -248,7 +248,7 @@ bool Texture2D::create(const Image& img)
void Texture2D::create_mipmaps() void Texture2D::create_mipmaps()
{ {
App::I->render_task([this] pp::renderer::gl::render_runtime_dispatch().render_task([this]
{ {
if (!pp::legacy::gl_texture::generate_texture_2d_mipmaps( if (!pp::legacy::gl_texture::generate_texture_2d_mipmaps(
static_cast<std::uint32_t>(m_tex), static_cast<std::uint32_t>(m_tex),
@@ -300,7 +300,7 @@ void Texture2D::destroy()
{ {
if (m_tex) if (m_tex)
{ {
App::I->render_task_async([id = m_tex] pp::renderer::gl::render_runtime_dispatch().render_task_async([id = m_tex]
{ {
pp::legacy::gl_texture::delete_texture_2d( pp::legacy::gl_texture::delete_texture_2d(
static_cast<std::uint32_t>(id), static_cast<std::uint32_t>(id),
@@ -312,7 +312,7 @@ void Texture2D::destroy()
void Texture2D::bind() const void Texture2D::bind() const
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
pp::legacy::gl_texture::bind_texture_2d( pp::legacy::gl_texture::bind_texture_2d(
static_cast<std::uint32_t>(m_tex), static_cast<std::uint32_t>(m_tex),
"Texture2D::bind()"); "Texture2D::bind()");
@@ -320,7 +320,7 @@ void Texture2D::bind() const
void Texture2D::unbind() const void Texture2D::unbind() const
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
pp::legacy::gl_texture::bind_texture_2d( pp::legacy::gl_texture::bind_texture_2d(
0U, 0U,
"Texture2D::unbind()"); "Texture2D::unbind()");
@@ -328,7 +328,7 @@ void Texture2D::unbind() const
void Texture2D::update(const uint8_t* data) void Texture2D::update(const uint8_t* data)
{ {
App::I->render_task([this, data] pp::renderer::gl::render_runtime_dispatch().render_task([this, data]
{ {
pp::legacy::gl_texture::update_texture_2d( pp::legacy::gl_texture::update_texture_2d(
pp::renderer::gl::OpenGlTexture2DUpdate { pp::renderer::gl::OpenGlTexture2DUpdate {
@@ -356,7 +356,7 @@ Texture2D::~Texture2D()
bool Sampler::create(GLint filter, GLint wrap) bool Sampler::create(GLint filter, GLint wrap)
{ {
bool ret = false; bool ret = false;
App::I->render_task([this, &ret, filter, wrap] pp::renderer::gl::render_runtime_dispatch().render_task([this, &ret, filter, wrap]
{ {
const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap( const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap(
static_cast<std::uint32_t>(filter), static_cast<std::uint32_t>(filter),
@@ -389,7 +389,7 @@ bool Sampler::create(GLint filter)
void Sampler::set(GLint filter, GLint wrap) void Sampler::set(GLint filter, GLint wrap)
{ {
App::I->render_task([=] pp::renderer::gl::render_runtime_dispatch().render_task([=]
{ {
const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap( const auto parameters = pp::renderer::gl::sampler_parameters_for_filter_wrap(
static_cast<std::uint32_t>(filter), static_cast<std::uint32_t>(filter),
@@ -415,7 +415,7 @@ void Sampler::set(GLint filter)
void Sampler::set_filter(GLint filter_min, GLint filter_mag) void Sampler::set_filter(GLint filter_min, GLint filter_mag)
{ {
App::I->render_task([=] pp::renderer::gl::render_runtime_dispatch().render_task([=]
{ {
const auto parameters = pp::renderer::gl::sampler_filter_parameters( const auto parameters = pp::renderer::gl::sampler_filter_parameters(
static_cast<std::uint32_t>(filter_min), static_cast<std::uint32_t>(filter_min),
@@ -428,7 +428,7 @@ void Sampler::set_filter(GLint filter_min, GLint filter_mag)
} }
void Sampler::set_border(glm::vec4 rgba) void Sampler::set_border(glm::vec4 rgba)
{ {
App::I->render_task([this, rgba] pp::renderer::gl::render_runtime_dispatch().render_task([this, rgba]
{ {
pp::legacy::gl_sampler::set_sampler_border_color( pp::legacy::gl_sampler::set_sampler_border_color(
static_cast<std::uint32_t>(id), static_cast<std::uint32_t>(id),
@@ -439,7 +439,7 @@ void Sampler::set_border(glm::vec4 rgba)
} }
void Sampler::bind(int unit) const void Sampler::bind(int unit) const
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
current_unit = unit; current_unit = unit;
pp::legacy::gl_sampler::bind_sampler( pp::legacy::gl_sampler::bind_sampler(
static_cast<std::uint32_t>(unit), static_cast<std::uint32_t>(unit),
@@ -448,7 +448,7 @@ void Sampler::bind(int unit) const
} }
void Sampler::unbind() void Sampler::unbind()
{ {
assert(App::I->is_render_thread()); assert(pp::renderer::gl::render_runtime_dispatch().is_render_thread());
pp::legacy::gl_sampler::bind_sampler( pp::legacy::gl_sampler::bind_sampler(
static_cast<std::uint32_t>(current_unit), static_cast<std::uint32_t>(current_unit),
0U, 0U,