Route canvas clear state through GL backend

This commit is contained in:
2026-06-04 23:13:21 +02:00
parent b8c7cd6e99
commit 9190e9053a
5 changed files with 128 additions and 54 deletions

View File

@@ -7,6 +7,7 @@
#include "paint_renderer/compositor.h"
#include "renderer_gl/opengl_capabilities.h"
#include "util.h"
#include <array>
#include <thread>
#include <algorithm>
#include <cstdint>
@@ -111,16 +112,6 @@ GLenum unsigned_byte_component_type()
return static_cast<GLenum>(pp::renderer::gl::unsigned_byte_component_type());
}
GLenum viewport_query()
{
return static_cast<GLenum>(pp::renderer::gl::viewport_query());
}
GLenum color_clear_value_query()
{
return static_cast<GLenum>(pp::renderer::gl::color_clear_value_query());
}
GLenum depth_test_state()
{
return static_cast<GLenum>(pp::renderer::gl::depth_test_state());
@@ -213,6 +204,26 @@ void set_opengl_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std
glViewport(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
}
void set_opengl_clear_color(float r, float g, float b, float a) noexcept
{
glClearColor(r, g, b, a);
}
void get_opengl_integer(std::uint32_t name, std::int32_t* values) noexcept
{
GLint raw_values[4] {};
glGetIntegerv(static_cast<GLenum>(name), raw_values);
values[0] = static_cast<std::int32_t>(raw_values[0]);
values[1] = static_cast<std::int32_t>(raw_values[1]);
values[2] = static_cast<std::int32_t>(raw_values[2]);
values[3] = static_cast<std::int32_t>(raw_values[3]);
}
void get_opengl_float(std::uint32_t name, float* values) noexcept
{
glGetFloatv(static_cast<GLenum>(name), values);
}
void set_opengl_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) noexcept
{
glScissor(static_cast<GLint>(x), static_cast<GLint>(y), static_cast<GLsizei>(width), static_cast<GLsizei>(height));
@@ -234,6 +245,41 @@ void apply_canvas_viewport(std::int32_t x, std::int32_t y, std::int32_t width, s
LOG("Canvas viewport dispatch failed because: %s", status.message);
}
pp::renderer::gl::OpenGlViewportRect query_canvas_viewport()
{
const auto result = pp::renderer::gl::query_opengl_viewport(
pp::renderer::gl::OpenGlViewportQueryDispatch {
.get_integer = get_opengl_integer,
});
if (!result.ok()) {
LOG("Canvas viewport query dispatch failed because: %s", result.status().message);
}
return result.value();
}
std::array<float, 4> query_canvas_clear_color()
{
const auto result = pp::renderer::gl::query_opengl_clear_color(
pp::renderer::gl::OpenGlClearColorQueryDispatch {
.get_float = get_opengl_float,
});
if (!result.ok()) {
LOG("Canvas clear-color query dispatch failed because: %s", result.status().message);
}
return result.value();
}
void apply_canvas_clear_color(std::array<float, 4> color)
{
const auto status = pp::renderer::gl::apply_opengl_clear_color(
color,
pp::renderer::gl::OpenGlClearColorDispatch {
.clear_color = set_opengl_clear_color,
});
if (!status.ok())
LOG("Canvas clear-color dispatch failed because: %s", status.message);
}
void apply_canvas_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height)
{
const auto status = pp::renderer::gl::apply_opengl_scissor_rect(
@@ -500,7 +546,11 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
apply_canvas_capability(scissor_test_state(), true);
apply_canvas_capability(blend_state(), false);
apply_canvas_scissor(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
apply_canvas_scissor(
static_cast<std::int32_t>(bb_min.x),
static_cast<std::int32_t>(bb_min.y),
static_cast<std::int32_t>(bb_sz.x),
static_cast<std::int32_t>(bb_sz.y));
auto layer_index = m_current_layer_idx;
for (int plane_index = 0; plane_index < 6; plane_index++)
@@ -777,10 +827,8 @@ void Canvas::stroke_draw()
m_dirty = true;
std::array<bool, 6> merge_faces;
GLint vp[4];
GLfloat cc[4];
glGetIntegerv(viewport_query(), vp);
glGetFloatv(color_clear_value_query(), cc);
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
const auto& brush = m_current_stroke->m_brush;
const auto& dual_brush = m_dual_stroke->m_brush;
@@ -975,8 +1023,8 @@ void Canvas::stroke_draw()
m_sampler_nearest.unbind();
m_sampler_stencil.unbind();
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
if (m_commit_delayed)
{
@@ -1086,10 +1134,8 @@ void Canvas::stroke_commit()
App::I->redraw = true;
// save viewport and clear color states
GLint vp[4];
GLfloat cc[4];
glGetIntegerv(viewport_query(), vp);
glGetFloatv(color_clear_value_query(), cc);
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
auto blend = glIsEnabled(blend_state());
// allocate action to add to history
@@ -1259,8 +1305,8 @@ void Canvas::stroke_commit()
// restore viewport and clear color states
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
set_active_texture_unit(0);
// save history
@@ -2962,10 +3008,8 @@ Image Canvas::thumbnail_generate(int w, int h)
App::I->render_task([this, w, h, &image]
{
// save viewport and clear color states
GLint vp[4];
GLfloat cc[4];
glGetIntegerv(viewport_query(), vp);
glGetFloatv(color_clear_value_query(), cc);
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
auto blend = glIsEnabled(blend_state());
// prepare common states
@@ -3057,8 +3101,8 @@ Image Canvas::thumbnail_generate(int w, int h)
// restore viewport and clear color states
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
set_active_texture_unit(0);
});
@@ -3097,10 +3141,8 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
App::I->render_task([&]
{
// save viewport and clear color states
GLint vp[4];
GLfloat cc[4];
glGetIntegerv(viewport_query(), vp);
glGetFloatv(color_clear_value_query(), cc);
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
auto blend = glIsEnabled(blend_state());
// prepare common states
@@ -3129,8 +3171,8 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
// restore viewport and clear color states
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
set_active_texture_unit(0);
});
}
@@ -3140,10 +3182,8 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
App::I->render_task([&]
{
// save viewport and clear color states
GLint vp[4];
GLfloat cc[4];
glGetIntegerv(viewport_query(), vp);
glGetFloatv(color_clear_value_query(), cc);
const auto vp = query_canvas_viewport();
const auto cc = query_canvas_clear_color();
auto blend = glIsEnabled(blend_state());
// prepare common states
@@ -3235,8 +3275,8 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
// restore viewport and clear color states
blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false);
apply_canvas_viewport(vp[0], vp[1], vp[2], vp[3]);
glClearColor(cc[0], cc[1], cc[2], cc[3]);
apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height);
apply_canvas_clear_color(cc);
set_active_texture_unit(0);
});
}