diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 37647ed..a5861ef 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -214,6 +214,10 @@ Known local toolchain state: brush/stencil/mix sampler filters and wraps, and image channel-count texture formats for cube-strip imports. Clamp-to-border sampler wrap is now part of the backend capability catalog and test coverage. + Early canvas draw helpers also consume backend-owned pick readback + format/type, stroke mixer depth/scissor/blend state, saved viewport and + clear-state queries, active texture units, fallback 2D texture unbind + targets, and stroke background copy targets. - `windows-msvc-vcpkg-headless` validates manifest install/configure/build/test for the current headless component matrix; see DEBT-0007 for remaining app and platform triplet migration. diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 96958db..8345a0d 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -758,6 +758,10 @@ Results: filters and wraps, and cube-strip import channel formats through the renderer GL backend mapping. The clamp-to-border sampler wrap is now cataloged and tested in `pp_renderer_gl`. +- Early canvas draw helpers now route pick readbacks, stroke mixer depth/scissor + and blend state, saved viewport/clear-state queries, active texture units, + fallback 2D texture unbinds, and stroke background copy targets through the + renderer GL backend mapping. - Known remaining warnings: legacy project/vendor diagnostics, Visual Studio vcpkg-manifest warning, `LNK4099` missing libyuv PDBs, and `LNK4098` runtime library conflict from retained vendor binaries. diff --git a/src/canvas.cpp b/src/canvas.cpp index acd1c5c..6486bd0 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -48,6 +48,31 @@ GLenum unsigned_byte_component_type() return static_cast(pp::renderer::gl::unsigned_byte_component_type()); } +GLenum viewport_query() +{ + return static_cast(pp::renderer::gl::viewport_query()); +} + +GLenum color_clear_value_query() +{ + return static_cast(pp::renderer::gl::color_clear_value_query()); +} + +GLenum depth_test_state() +{ + return static_cast(pp::renderer::gl::depth_test_state()); +} + +GLenum scissor_test_state() +{ + return static_cast(pp::renderer::gl::scissor_test_state()); +} + +GLenum blend_state() +{ + return static_cast(pp::renderer::gl::blend_state()); +} + GLint texture_filter_linear() { return static_cast(pp::renderer::gl::linear_texture_filter()); @@ -78,6 +103,16 @@ pp::renderer::gl::OpenGlPixelFormat texture_format_for_image_channels(int channe return pp::renderer::gl::texture_format_for_channel_count(static_cast(channel_count)); } +void set_active_texture_unit(std::uint32_t unit_index) +{ + glActiveTexture(pp::renderer::gl::active_texture_unit(unit_index)); +} + +void unbind_texture_2d() +{ + glBindTexture(texture_2d_target(), 0); +} + } @@ -151,7 +186,14 @@ void Canvas::pick_update(int plane) m_layers_merge.rtt(i).bindFramebuffer(); if (!m_pick_data[plane]) m_pick_data[plane] = std::make_unique(m_width * m_height); - glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_pick_data[plane].get()); + glReadPixels( + 0, + 0, + m_width, + m_height, + rgba_pixel_format(), + unsigned_byte_component_type(), + m_pick_data[plane].get()); m_layers_merge.rtt(i).unbindFramebuffer(); }); @@ -225,9 +267,9 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) m_mixer.bindFramebuffer(); glViewport(0, 0, m_mixer.getWidth(), m_mixer.getHeight()); - glDisable(GL_DEPTH_TEST); - glEnable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); + glDisable(depth_test_state()); + glEnable(scissor_test_state()); + glDisable(blend_state()); glScissor(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y); @@ -265,17 +307,17 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) ShaderManager::u_int(kShaderUniform::UsePattern, false); ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); - glActiveTexture(GL_TEXTURE0); + set_active_texture_unit(0); m_layers[layer_index]->rtt(plane_index).bindTexture(); - glActiveTexture(GL_TEXTURE1); + set_active_texture_unit(1); m_tmp[plane_index].bindTexture(); - glActiveTexture(GL_TEXTURE2); + set_active_texture_unit(2); m_smask.rtt(plane_index).bindTexture(); m_node->m_face_plane.draw_fill(); m_smask.rtt(plane_index).unbindTexture(); - glActiveTexture(GL_TEXTURE1); + set_active_texture_unit(1); m_tmp[plane_index].unbindTexture(); - glActiveTexture(GL_TEXTURE0); + set_active_texture_unit(0); m_layers[layer_index]->rtt(plane_index).unbindTexture(); } m_sampler.unbind(); @@ -363,7 +405,7 @@ glm::vec4 Canvas::stroke_draw_samples(int i, std::vector& P) { if (!ShaderManager::ext_framebuffer_fetch) { - glActiveTexture(GL_TEXTURE1); + set_active_texture_unit(1); m_tex[i].bind(); // bg, copy of framebuffer (copied before drawing) } @@ -381,7 +423,7 @@ glm::vec4 Canvas::stroke_draw_samples(int i, std::vector& P) glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz) + pad * 2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(m_width, m_height) - tex_pos)); if (!ShaderManager::ext_framebuffer_fetch) { - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, tex_pos.x, tex_pos.y, + glCopyTexSubImage2D(texture_2d_target(), 0, tex_pos.x, tex_pos.y, tex_pos.x, tex_pos.y, tex_sz.x, tex_sz.y); } @@ -409,7 +451,7 @@ glm::vec4 Canvas::stroke_draw_samples(int i, std::vector& P) if (!ShaderManager::ext_framebuffer_fetch) { - glActiveTexture(GL_TEXTURE1); + set_active_texture_unit(1); m_tex[i].unbind(); } @@ -506,8 +548,8 @@ void Canvas::stroke_draw() GLint vp[4]; GLfloat cc[4]; - glGetIntegerv(GL_VIEWPORT, vp); - glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); + glGetIntegerv(viewport_query(), vp); + glGetFloatv(color_clear_value_query(), cc); const auto& brush = m_current_stroke->m_brush; const auto& dual_brush = m_dual_stroke->m_brush; @@ -525,7 +567,7 @@ void Canvas::stroke_draw() if (brush->m_pattern_flipx) patt_scale.x *= -1.f; if (brush->m_pattern_flipy) patt_scale.y *= -1.f; - glDisable(GL_BLEND); + glDisable(blend_state()); ShaderManager::use(kShader::Stroke); ShaderManager::u_int(kShaderUniform::Tex, 0); // brush if (!ShaderManager::ext_framebuffer_fetch) @@ -550,13 +592,13 @@ void Canvas::stroke_draw() // DRAW MAIN BRUSH - glActiveTexture(GL_TEXTURE0); + set_active_texture_unit(0); brush->m_tip_texture->bind(); - glActiveTexture(GL_TEXTURE2); + set_active_texture_unit(2); brush->m_pattern_texture ? brush->m_pattern_texture->bind() : - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); + unbind_texture_2d(); + set_active_texture_unit(3); m_mixer.bindTexture(); auto frames = stroke_draw_compute(*m_current_stroke); @@ -597,9 +639,9 @@ void Canvas::stroke_draw() } } - glActiveTexture(GL_TEXTURE3); + set_active_texture_unit(3); m_mixer.unbindTexture(); - glActiveTexture(GL_TEXTURE0); + set_active_texture_unit(0); brush->m_tip_texture->unbind(); // pad stroke @@ -615,7 +657,7 @@ void Canvas::stroke_draw() ShaderManager::u_vec4(kShaderUniform::Col, pad_color); if (!ShaderManager::ext_framebuffer_fetch) { - glActiveTexture(GL_TEXTURE1); + set_active_texture_unit(1); ShaderManager::u_int(kShaderUniform::TexBG, 1); } for (int i = 0; i < 6; i++) @@ -649,14 +691,14 @@ void Canvas::stroke_draw() glm::vec2 sz = glm::min(m_size, zw(b) + pad) - o; m_tex[i].bind(); if (sz.x > 0 && sz.y > 0) - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, o.x, o.y, o.x, o.y, sz.x, sz.y); + glCopyTexSubImage2D(texture_2d_target(), 0, o.x, o.y, o.x, o.y, sz.x, sz.y); } m_brush_shape.draw_fill(); m_tmp[i].unbindFramebuffer(); } if (!ShaderManager::ext_framebuffer_fetch) { - glBindTexture(GL_TEXTURE_2D, 0); + unbind_texture_2d(); } // DRAW DUAL BRUSH @@ -669,10 +711,10 @@ void Canvas::stroke_draw() ShaderManager::u_float(kShaderUniform::Wet, 0); ShaderManager::u_float(kShaderUniform::Noise, 0); - glActiveTexture(GL_TEXTURE0); + set_active_texture_unit(0); dual_brush->m_tip_texture ? dual_brush->m_tip_texture->bind() : - glBindTexture(GL_TEXTURE_2D, 0); + unbind_texture_2d(); auto frames_dual = stroke_draw_compute(*m_dual_stroke); for (auto& f : frames_dual) {