diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 77538a8..884e87a 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -18,6 +18,11 @@ agent or engineer to remove them without reconstructing context from chat. ## Recent Reductions +- 2026-06-13: DEBT-0036 was narrowed again. `NodeCanvas` live temporary-erase + `CompErase` shader setup now routes through + `legacy_canvas_stroke_erase_services.h`; the retained node path still owns + per-onion-frame alpha updates, texture binding, temporary erase texture + selection, and draw execution. - 2026-06-13: DEBT-0036 was narrowed again. `NodeCanvas` live temporary-stroke `CompDraw` shader setup now routes through `legacy_canvas_stroke_composite_services.h`; the retained node path still diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 16e0833..3a92345 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -3005,6 +3005,10 @@ Results: composite shader setup helper for static `CompDraw` uniforms, while keeping per-onion-frame alpha updates, texture binding, temporary stroke texture selection, and draw execution in the retained node path. +- `NodeCanvas` live temporary-erase drawing now uses a retained stroke erase + shader setup helper for `CompErase` uniforms, while keeping per-onion-frame + alpha updates, texture binding, temporary erase texture selection, and draw + execution in the retained node path. - `Canvas::stroke_draw_mix` now shares the retained stroke composite shader helper for mixer-pass `CompDraw` setup, while preserving its caller-specific texture slot uniforms. Mixer framebuffer/scissor state, sampler and texture diff --git a/src/legacy_canvas_stroke_erase_services.h b/src/legacy_canvas_stroke_erase_services.h new file mode 100644 index 0000000..28ff174 --- /dev/null +++ b/src/legacy_canvas_stroke_erase_services.h @@ -0,0 +1,49 @@ +#pragma once + +#include "shader.h" + +#include + +namespace pp::panopainter { + +struct LegacyStrokeEraseUniforms { + glm::mat4 mvp { 1.0f }; + int texture_slot = 0; + int stroke_texture_slot = 1; + int mask_texture_slot = 2; + bool mask_enabled = false; +}; + +struct LegacyStrokeEraseShaderExecution { + std::function use_shader; + std::function set_int; + std::function set_mat4; +}; + +[[nodiscard]] inline LegacyStrokeEraseShaderExecution legacy_shader_manager_stroke_erase_execution() noexcept +{ + return { + .use_shader = [](kShader shader) { ShaderManager::use(shader); }, + .set_int = [](kShaderUniform uniform, int value) { ShaderManager::u_int(uniform, value); }, + .set_mat4 = [](kShaderUniform uniform, const glm::mat4& value) { ShaderManager::u_mat4(uniform, value); }, + }; +} + +inline void setup_legacy_stroke_erase_shader( + const LegacyStrokeEraseUniforms& uniforms, + const LegacyStrokeEraseShaderExecution& execution) noexcept +{ + execution.use_shader(kShader::CompErase); + execution.set_int(kShaderUniform::Tex, uniforms.texture_slot); + execution.set_int(kShaderUniform::TexStroke, uniforms.stroke_texture_slot); + execution.set_int(kShaderUniform::TexMask, uniforms.mask_texture_slot); + execution.set_int(kShaderUniform::Mask, uniforms.mask_enabled); + execution.set_mat4(kShaderUniform::MVP, uniforms.mvp); +} + +inline void setup_legacy_stroke_erase_shader(const LegacyStrokeEraseUniforms& uniforms) +{ + setup_legacy_stroke_erase_shader(uniforms, legacy_shader_manager_stroke_erase_execution()); +} + +} // namespace pp::panopainter diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 463e105..429b268 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -14,6 +14,7 @@ #include "node_panel_grid.h" #include "legacy_canvas_draw_merge_services.h" #include "legacy_canvas_stroke_composite_services.h" +#include "legacy_canvas_stroke_erase_services.h" #include "legacy_preference_storage.h" #include "legacy_ui_gl_dispatch.h" #include "legacy_ui_overlay_services.h" @@ -485,14 +486,16 @@ void NodeCanvas::draw() m_sampler.bind(1); m_sampler.bind(2); - ShaderManager::use(kShader::CompErase); - ShaderManager::u_int(kShaderUniform::Tex, 0); - ShaderManager::u_int(kShaderUniform::TexStroke, 1); - ShaderManager::u_int(kShaderUniform::TexMask, 2); //ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom); //ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked); - ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); - ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); + pp::panopainter::setup_legacy_stroke_erase_shader( + pp::panopainter::LegacyStrokeEraseUniforms { + .mvp = plane_mvp_z, + .texture_slot = 0, + .stroke_texture_slot = 1, + .mask_texture_slot = 2, + .mask_enabled = m_canvas->m_smask_active, + }); set_active_texture_unit(1); m_canvas->m_tmp[plane_index].bindTexture(); set_active_texture_unit(2);