From 51458ad0e7c163f137e2c6ec4bec22b043792824 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 13 Jun 2026 11:17:16 +0200 Subject: [PATCH] Share retained erase temporary composite helper --- docs/modernization/debt.md | 5 +++ docs/modernization/roadmap.md | 4 +++ docs/modernization/tasks.md | 8 +++++ src/canvas.cpp | 62 ++++++++++++++++++++--------------- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 3237b8f..7b359a8 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. `Canvas::draw_merge()` erase live + temporary-stroke composite now routes retained setup, sampler bind, texture + bind, draw, and texture unbind ordering through + `execute_legacy_canvas_stroke_temporary_composite(...)`; broader final + composite ownership remains in the legacy Canvas path. - 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_mix()` now routes retained mix-pass shader setup plus framebuffer/state/input/draw ordering through `execute_legacy_node_stroke_preview_mix_pass(...)`; the diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index fa510ef..3056a15 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -3141,6 +3141,10 @@ Results: `execute_legacy_canvas_stroke_temporary_composite(...)` for setup, sampler bind, texture bind, draw, and texture unbind ordering, while erase-path and broader final composite ownership remain in the legacy Canvas path. +- `Canvas::draw_merge()` erase live temporary-stroke composite now also shares + `execute_legacy_canvas_stroke_temporary_composite(...)`, leaving only the + concrete GL object callbacks and broader final composite ownership in the + legacy Canvas path. - `NodeStrokePreview::draw_stroke_immediate()` now shares `execute_legacy_node_stroke_preview_pass_sequence(...)` for dual-pass/background/main-pass/final-composite/copy-back ordering, while the diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index 50f83c2..83f18af 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -509,6 +509,14 @@ Done Checks: Progress Notes: +- 2026-06-13: `Canvas::draw_merge()` erase live temporary-stroke composite now + routes retained setup, sampler bind, texture bind, draw, and texture unbind + ordering through `execute_legacy_canvas_stroke_temporary_composite(...)`; + both live temporary composite branches now share the same retained execution + helper while `Canvas` keeps only concrete GL object callbacks and broader + final composite ownership. Next slice should target the remaining final + composite seam without reopening landed sample, mix, dirty, or framebuffer + helpers. - 2026-06-13: `NodeStrokePreview::stroke_draw_mix()` now routes retained mix-pass shader setup plus framebuffer/state/input/draw ordering through `execute_legacy_node_stroke_preview_mix_pass(...)`, with compositor coverage diff --git a/src/canvas.cpp b/src/canvas.cpp index f410b10..cac217a 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -1408,33 +1408,43 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SI if (m_current_stroke && m_current_mode == kCanvasMode::Erase && m_show_tmp && m_current_layer_idx == layer_index) { - m_sampler.bind(0); - m_sampler.bind(1); - m_sampler.bind(2); - - //ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_box) / zoom); - //ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index]->m_alpha_locked); - pp::panopainter::setup_legacy_stroke_erase_shader( - pp::panopainter::LegacyStrokeEraseUniforms { - .mvp = ortho, - .texture_slot = 0, - .stroke_texture_slot = 1, - .mask_texture_slot = 2, - .alpha = m_layers[layer_index]->m_opacity, - .mask_enabled = m_smask_active, + pp::panopainter::execute_legacy_canvas_stroke_temporary_composite( + [&] { + //ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_box) / zoom); + //ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index]->m_alpha_locked); + pp::panopainter::setup_legacy_stroke_erase_shader( + pp::panopainter::LegacyStrokeEraseUniforms { + .mvp = ortho, + .texture_slot = 0, + .stroke_texture_slot = 1, + .mask_texture_slot = 2, + .alpha = m_layers[layer_index]->m_opacity, + .mask_enabled = m_smask_active, + }); + }, + [&] { + m_sampler.bind(0); + m_sampler.bind(1); + m_sampler.bind(2); + }, + [&] { + set_active_texture_unit(0); + m_layers[layer_index]->rtt(plane_index).bindTexture(); + set_active_texture_unit(1); + m_tmp[plane_index].bindTexture(); + set_active_texture_unit(2); + m_smask.rtt(plane_index).bindTexture(); + }, + [&] { + m_plane.draw_fill(); + }, + [&] { + m_smask.rtt(plane_index).unbindTexture(); + set_active_texture_unit(1); + m_tmp[plane_index].unbindTexture(); + set_active_texture_unit(0); + m_layers[layer_index]->rtt(plane_index).unbindTexture(); }); - set_active_texture_unit(0); - m_layers[layer_index]->rtt(plane_index).bindTexture(); - set_active_texture_unit(1); - m_tmp[plane_index].bindTexture(); - set_active_texture_unit(2); - m_smask.rtt(plane_index).bindTexture(); - m_plane.draw_fill(); - m_smask.rtt(plane_index).unbindTexture(); - set_active_texture_unit(1); - m_tmp[plane_index].unbindTexture(); - set_active_texture_unit(0); - m_layers[layer_index]->rtt(plane_index).unbindTexture(); } else if (m_current_stroke && m_show_tmp && m_current_layer_idx == layer_index) {