diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 0fa1d86..9a3b015 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -169,6 +169,10 @@ agent or engineer to remove them without reconstructing context from chat. now routes the dual-pass live body through `execute_stroke_draw_immediate_dual_pass(...)`; the retained path still owns the concrete frame mutation, shader setup, and preview copy behavior. +- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::draw_stroke_immediate()` + now routes the pass-sequence request assembly through + `make_stroke_draw_immediate_pass_sequence_request(...)`; the retained path + still owns the concrete preview copy behavior and final-state restoration. - 2026-06-13: DEBT-0036 was narrowed again. `Canvas::draw_merge()` now routes the remaining per-layer branch orchestration through `execute_legacy_canvas_draw_merge_layer_composite(...)`; the retained path diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index 74fd903..c59e080 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -1775,6 +1775,37 @@ ctest --preset desktop-fast --build-config Debug -R "pp_paint_renderer_composito cmake --build --preset windows-msvc-default --config Debug --target PanoPainter ``` +### STR-038 - Extract Preview Pass Sequence Request Assembly + +Status: Done +Score: no score movement +Debt: `DEBT-0036` +Scope: `src/node_stroke_preview.cpp`, `tests/paint_renderer/compositor_tests.cpp` + +Goal: + +Move the remaining `NodeStrokePreview::draw_stroke_immediate()` pass-sequence +request assembly into a retained helper so the callsite keeps only the +sequence wrapper and final state restoration. + +Closeout: `3672f9a5` + +Done Checks: + +- `NodeStrokePreview::draw_stroke_immediate()` no longer owns the pass-sequence + request object inline. +- Regression coverage proves the helper preserves dual/main sequence ordering + and copy behavior. +- `docs/modernization/debt.md` records the reduced preview pass-sequence + surface. + +Validation: + +```powershell +ctest --preset desktop-fast --build-config Debug -R "pp_paint_renderer_compositor|pp_paint_renderer_stroke_execution" --output-onfailure +cmake --build --preset windows-msvc-default --config Debug --target PanoPainter +``` + ### STR-010 - Extract Remaining Draw Merge Composite Orchestration ### STR-016 - Extract Draw Merge Layer Composite Execution diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index 09300a5..0585aea 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -741,63 +741,13 @@ void NodeStrokePreview::draw_stroke_immediate() pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader); const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_pass_sequence( - pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest { - .dual_pass_enabled = material.dual_pass.enabled, - .prepare_dual_pass = [&] { - pp::panopainter::setup_legacy_stroke_dual_shader(material.dual_pass.uses_pattern); - bind_stroke_preview_dual_pass_textures(*dual_brush); - }, - .execute_dual_pass = [&] { - execute_stroke_draw_immediate_dual_pass( - *b, - pass_orchestration, - dual_brush, - copy_stroke_destination, - zoom, - size); - }, - .capture_background = [&] { - execute_stroke_preview_background_capture_pass( - size, - pass_orchestration.background_colorize, - m_tex_background, - [&] { - m_plane.draw_fill(); - }); - }, - .prepare_main_pass = [&] {}, - .execute_main_pass = [&] { - [[maybe_unused]] const bool main_live_ok = - pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass( - make_stroke_draw_immediate_main_live_pass_request( - *b, - pass_orchestration, - copy_stroke_destination, - zoom, - size)); - }, - .finish_main_pass = [&] {}, - .execute_final_composite = [&] { - execute_stroke_preview_final_composite_and_copy( - StrokePreviewCompositePassInputs { - .resolution = size, - .pattern_scale = patt_scale, - .brush = *b, - .composite_pass = material.composite_pass, - .background_texture = m_tex_background, - .stroke_texture = m_tex, - .dual_texture = m_tex_dual, - .linear_sampler = m_sampler_linear, - .repeat_sampler = m_sampler_linear_repeat, - .draw_composite = [&] { - m_plane.draw_fill(); - }, - }, - m_tex_preview, - size); - }, - .copy_preview_result = [&] {}, - }); + make_stroke_draw_immediate_pass_sequence_request( + *b, + pass_orchestration, + dual_brush, + copy_stroke_destination, + zoom, + size)); assert(sequence_ok); m_rtt.unbindFramebuffer(); @@ -912,6 +862,75 @@ void NodeStrokePreview::execute_stroke_draw_immediate_dual_pass( }); } +pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest +NodeStrokePreview::make_stroke_draw_immediate_pass_sequence_request( + const Brush& brush, + const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration, + std::shared_ptr dual_brush, + bool copy_stroke_destination, + float zoom, + const glm::vec2& size) +{ + const auto& material = pass_orchestration.material; + return pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest { + .dual_pass_enabled = material.dual_pass.enabled, + .prepare_dual_pass = [&] { + pp::panopainter::setup_legacy_stroke_dual_shader(material.dual_pass.uses_pattern); + bind_stroke_preview_dual_pass_textures(*dual_brush); + }, + .execute_dual_pass = [&] { + execute_stroke_draw_immediate_dual_pass( + brush, + pass_orchestration, + dual_brush, + copy_stroke_destination, + zoom, + size); + }, + .capture_background = [&] { + execute_stroke_preview_background_capture_pass( + size, + pass_orchestration.background_colorize, + m_tex_background, + [&] { + m_plane.draw_fill(); + }); + }, + .prepare_main_pass = [&] {}, + .execute_main_pass = [&] { + [[maybe_unused]] const bool main_live_ok = + pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass( + make_stroke_draw_immediate_main_live_pass_request( + brush, + pass_orchestration, + copy_stroke_destination, + zoom, + size)); + }, + .finish_main_pass = [&] {}, + .execute_final_composite = [&] { + execute_stroke_preview_final_composite_and_copy( + StrokePreviewCompositePassInputs { + .resolution = size, + .pattern_scale = brush.m_pattern_scale, + .brush = brush, + .composite_pass = material.composite_pass, + .background_texture = m_tex_background, + .stroke_texture = m_tex, + .dual_texture = m_tex_dual, + .linear_sampler = m_sampler_linear, + .repeat_sampler = m_sampler_linear_repeat, + .draw_composite = [&] { + m_plane.draw_fill(); + }, + }, + m_tex_preview, + size); + }, + .copy_preview_result = [&] {}, + }; +} + Image NodeStrokePreview::render_to_image() { std::lock_guard _lock(s_render_mutex); diff --git a/src/node_stroke_preview.h b/src/node_stroke_preview.h index 2e6967d..f159b55 100644 --- a/src/node_stroke_preview.h +++ b/src/node_stroke_preview.h @@ -66,6 +66,13 @@ public: bool copy_stroke_destination, float zoom, const glm::vec2& size); + pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest make_stroke_draw_immediate_pass_sequence_request( + const Brush& brush, + const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration, + std::shared_ptr dual_brush, + bool copy_stroke_destination, + float zoom, + const glm::vec2& size); void draw_stroke(); void draw_stroke_immediate(); Image render_to_image();