From ea1557f7eaf966a6074bf5da6c8fd9b0ca885860 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 13 Jun 2026 05:10:37 +0200 Subject: [PATCH] Route NodeCanvas blend setup through helper --- docs/modernization/debt.md | 6 +++++ docs/modernization/roadmap.md | 5 ++++ src/legacy_canvas_draw_merge_services.h | 31 +++++++++++++++++++++++++ src/node_canvas.cpp | 16 +++++++------ 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 17f88fc..582e95f 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -18,6 +18,12 @@ agent or engineer to remove them without reconstructing context from chat. ## Recent Reductions +- 2026-06-13: DEBT-0036 was narrowed again. `NodeCanvas` non-stroke + `TextureBlend` shader setup now routes through + `legacy_canvas_draw_merge_services.h`, including the optional destination + texture uniform only when blend destination copies are used. NodeCanvas still + owns panorama layer traversal, onion-frame drawing, blend destination copies, + sampler/texture binding, framebuffer lifetime, and draw ordering. - 2026-06-13: DEBT-0036 was narrowed again. `NodeCanvas` now reuses `legacy_canvas_draw_merge_services.h` for retained checkerboard grid shader setup and the final cached-layer texture redraw setup. NodeCanvas still owns diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 6a1f7e3..b1f7bf8 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -3000,6 +3000,11 @@ Results: setup helper for checkerboard grids and final cached-layer texture redraws; onion-frame traversal, blend copies, texture binding, and draw order remain retained in the node. +- `NodeCanvas` non-stroke layer blending now shares the retained draw-merge + shader setup helper for `TextureBlend` uniforms, preserving the optional + destination texture uniform when copy-based blending is active. Framebuffer + lifetime, destination copies, texture binding, and draw execution remain + local to the node. - Canvas thumbnail layer blending now uses the same canvas destination-feedback plan for framebuffer-fetch versus texture-copy decisions; the thumbnail draw itself still executes through retained OpenGL canvas code under DEBT-0036. diff --git a/src/legacy_canvas_draw_merge_services.h b/src/legacy_canvas_draw_merge_services.h index 6f20094..9b58785 100644 --- a/src/legacy_canvas_draw_merge_services.h +++ b/src/legacy_canvas_draw_merge_services.h @@ -16,9 +16,19 @@ struct LegacyCanvasDrawMergeTextureUniforms { int texture_slot = 0; }; +struct LegacyCanvasDrawMergeTextureBlendUniforms { + glm::mat4 mvp { 1.0f }; + int texture_slot = 0; + int destination_texture_slot = 2; + bool use_destination_texture = false; + int blend_mode = 0; + float alpha = 1.0f; +}; + struct LegacyCanvasDrawMergeShaderExecution { std::function use_shader; std::function set_int; + std::function set_float; std::function set_mat4; }; @@ -27,6 +37,7 @@ struct LegacyCanvasDrawMergeShaderExecution { return { .use_shader = [](kShader shader) { ShaderManager::use(shader); }, .set_int = [](kShaderUniform uniform, int value) { ShaderManager::u_int(uniform, value); }, + .set_float = [](kShaderUniform uniform, float value) { ShaderManager::u_float(uniform, value); }, .set_mat4 = [](kShaderUniform uniform, const glm::mat4& value) { ShaderManager::u_mat4(uniform, value); }, }; } @@ -61,4 +72,24 @@ inline void setup_legacy_canvas_draw_merge_texture_shader( setup_legacy_canvas_draw_merge_texture_shader(uniforms, legacy_shader_manager_draw_merge_execution()); } +inline void setup_legacy_canvas_draw_merge_texture_blend_shader( + const LegacyCanvasDrawMergeTextureBlendUniforms& uniforms, + const LegacyCanvasDrawMergeShaderExecution& execution) noexcept +{ + execution.use_shader(kShader::TextureBlend); + execution.set_int(kShaderUniform::Tex, uniforms.texture_slot); + if (uniforms.use_destination_texture) { + execution.set_int(kShaderUniform::TexBG, uniforms.destination_texture_slot); + } + execution.set_int(kShaderUniform::BlendMode, uniforms.blend_mode); + execution.set_float(kShaderUniform::Alpha, uniforms.alpha); + execution.set_mat4(kShaderUniform::MVP, uniforms.mvp); +} + +inline void setup_legacy_canvas_draw_merge_texture_blend_shader( + const LegacyCanvasDrawMergeTextureBlendUniforms& uniforms) +{ + setup_legacy_canvas_draw_merge_texture_blend_shader(uniforms, legacy_shader_manager_draw_merge_execution()); +} + } // namespace pp::panopainter diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 6a5cc97..d4ede77 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -606,13 +606,15 @@ void NodeCanvas::draw() m_sampler.bind(0); m_sampler.bind(2); - ShaderManager::use(kShader::TextureBlend); - ShaderManager::u_int(kShaderUniform::Tex, 0); - if (copy_blend_destination) - ShaderManager::u_int(kShaderUniform::TexBG, 2); - ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index]->m_blend_mode); - ShaderManager::u_float(kShaderUniform::Alpha, 1.f); - ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1)); + pp::panopainter::setup_legacy_canvas_draw_merge_texture_blend_shader( + pp::panopainter::LegacyCanvasDrawMergeTextureBlendUniforms { + .mvp = glm::ortho(-1, 1, -1, 1), + .texture_slot = 0, + .destination_texture_slot = 2, + .use_destination_texture = copy_blend_destination, + .blend_mode = m_canvas->m_layers[layer_index]->m_blend_mode, + .alpha = 1.f, + }); set_active_texture_unit(0); m_blender_rtt.bindTexture();