diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index d9dce4e..55d8313 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -82,6 +82,10 @@ agent or engineer to remove them without reconstructing context from chat. now calls the retained mix-pass executor directly instead of a local wrapper shell helper; the live path still owns the concrete mixer framebuffer setup and GL capability toggles. +- 2026-06-13: `LATER-003` was narrowed again. `Canvas::stroke_draw_mix()` + now routes the remaining mixer framebuffer/capability shell through a local + helper, leaving the call site with only mix-pass planning and helper + invocation. - 2026-06-13: `DEBT-0036` was narrowed again. `NodeStrokePreview::draw_stroke_immediate()` now routes final composite execution and preview copy-back through a retained local wrapper, leaving the call site with only sequence wiring. diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index 1a90969..4c7b490 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -626,6 +626,9 @@ Progress Notes: - 2026-06-13: `Canvas::stroke_draw_mix()` now calls the retained mix-pass executor directly instead of a local wrapper shell helper; the live path still owns the concrete mixer framebuffer setup and GL capability toggles. +- 2026-06-13: `Canvas::stroke_draw_mix()` now routes the remaining mixer + framebuffer/capability shell through a local helper, leaving the call site + with only mix-pass planning and helper invocation. - 2026-06-13: `Canvas::stroke_draw_samples()` now reuses a retained destination texture dispatch helper for the live sample path; `Canvas` still owns the concrete face textures and callback execution. diff --git a/src/canvas.cpp b/src/canvas.cpp index 9abe052..fd04535 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -386,43 +386,63 @@ void Canvas::stroke_cancel() m_current_stroke = nullptr; m_show_tmp = false; } -void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) +static void execute_canvas_stroke_mix_pass( + Canvas& canvas, + const glm::vec2& bb_min, + const glm::vec2& bb_sz, + const std::array& plane_transform, + const std::vector>& layers, + std::size_t layer_index, + const Stroke* current_stroke) { - gl_state gl; - gl.save(); - const auto layer_index = m_current_layer_idx; - auto& current_layer = *m_layers[layer_index]; - std::array plane_transform {}; - std::copy(std::begin(m_plane_transform), std::end(m_plane_transform), plane_transform.begin()); + auto& current_layer = *layers[layer_index]; const auto mix_planes = pp::panopainter::plan_legacy_canvas_stroke_mix_pass_planes( current_layer.m_visible, current_layer.m_opacity, - glm::scale(glm::vec3(1, -1, 1)) * m_proj * m_mv, + glm::scale(glm::vec3(1, -1, 1)) * canvas.m_proj * canvas.m_mv, plane_transform, [&](int plane_index) { return current_layer.face(plane_index); }); - const auto& b = m_current_stroke->m_brush; + const auto& b = current_stroke->m_brush; const auto mix_shell = pp::panopainter::make_legacy_canvas_stroke_mix_pass_shell( [&] { - m_mixer.bindFramebuffer(); - apply_canvas_viewport(0, 0, m_mixer.getWidth(), m_mixer.getHeight()); - apply_canvas_capability(depth_test_state(), false); - apply_canvas_capability(scissor_test_state(), true); - apply_canvas_capability(blend_state(), false); - apply_canvas_scissor( + canvas.m_mixer.bindFramebuffer(); + canvas.apply_canvas_viewport(0, 0, canvas.m_mixer.getWidth(), canvas.m_mixer.getHeight()); + canvas.apply_canvas_capability(canvas.depth_test_state(), false); + canvas.apply_canvas_capability(canvas.scissor_test_state(), true); + canvas.apply_canvas_capability(canvas.blend_state(), false); + canvas.apply_canvas_scissor( static_cast(bb_min.x), static_cast(bb_min.y), static_cast(bb_sz.x), static_cast(bb_sz.y)); }, [&] { - m_mixer.unbindFramebuffer(); + canvas.m_mixer.unbindFramebuffer(); }); [[maybe_unused]] const auto mix_result = pp::panopainter::execute_legacy_canvas_stroke_mix_pass_shell( mix_shell.setup.begin, mix_shell.setup.end, mix_shell.request); + (void)mix_planes; + (void)b; +} + +void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) +{ + gl_state gl; + gl.save(); + std::array plane_transform {}; + std::copy(std::begin(m_plane_transform), std::end(m_plane_transform), plane_transform.begin()); + execute_canvas_stroke_mix_pass( + *this, + bb_min, + bb_sz, + plane_transform, + m_layers, + m_current_layer_idx, + m_current_stroke); gl.restore(); }