Extract stroke preview final composite helper
This commit is contained in:
@@ -18,6 +18,10 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
|
||||
## Recent Reductions
|
||||
|
||||
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview` final
|
||||
composite sampler/input binding and slot intent now route through one local
|
||||
preview helper; mixer execution, per-sample stroke callbacks, framebuffer
|
||||
copies, and final OpenGL draw ownership remain retained in the preview node.
|
||||
- 2026-06-13: DEBT-0036 was narrowed again. `Canvas::stroke_draw` pad-pass
|
||||
destination bind/copy/unbind ordering now routes through
|
||||
`legacy_canvas_stroke_execution_services.h`; shader setup, pad color
|
||||
|
||||
@@ -3097,6 +3097,10 @@ Results:
|
||||
shares the retained stroke execution helper callback surface, while shader
|
||||
setup, pad color selection, framebuffer ownership, and final OpenGL draw
|
||||
remain in the legacy Canvas path.
|
||||
- `NodeStrokePreview` final composite sampler/input binding and texture-slot
|
||||
intent now share one local retained helper, while mixer execution,
|
||||
per-sample stroke callbacks, framebuffer copies, and final OpenGL draw
|
||||
ownership remain in the preview node.
|
||||
- `Canvas::stroke_draw` pad-region planning now shares the retained stroke
|
||||
execution helper wrapping `pp_paint_renderer`, while pad color selection,
|
||||
dirty-face iteration, framebuffer copies, quad upload, and draw execution
|
||||
|
||||
@@ -96,6 +96,78 @@ void apply_stroke_preview_capability(std::uint32_t state, bool enabled)
|
||||
pp::legacy::ui_gl::set_capability(state, enabled, "NodeStrokePreview");
|
||||
}
|
||||
|
||||
namespace stroke_preview_composite_slots {
|
||||
constexpr std::uint32_t kBackground = 0U;
|
||||
constexpr std::uint32_t kStroke = 1U;
|
||||
constexpr std::uint32_t kDual = 3U;
|
||||
constexpr std::uint32_t kPattern = 4U;
|
||||
}
|
||||
|
||||
struct StrokePreviewCompositePassInputs {
|
||||
glm::vec2 resolution;
|
||||
glm::vec2 pattern_scale;
|
||||
const Brush& brush;
|
||||
const pp::paint_renderer::CanvasStrokeCompositePassPlan& composite_pass;
|
||||
Texture2D& background_texture;
|
||||
Texture2D& stroke_texture;
|
||||
Texture2D& dual_texture;
|
||||
Sampler& linear_sampler;
|
||||
Sampler& repeat_sampler;
|
||||
std::function<void()> draw_composite;
|
||||
};
|
||||
|
||||
void execute_stroke_preview_final_composite_pass(const StrokePreviewCompositePassInputs& inputs)
|
||||
{
|
||||
pp::panopainter::execute_legacy_stroke_preview_final_composite(
|
||||
[&] {
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
pp::panopainter::LegacyStrokeCompositeUniforms {
|
||||
.resolution = inputs.resolution,
|
||||
.pattern = {
|
||||
.scale = inputs.pattern_scale,
|
||||
.invert = static_cast<float>(inputs.brush.m_pattern_invert),
|
||||
.brightness = inputs.brush.m_pattern_brightness,
|
||||
.contrast = inputs.brush.m_pattern_contrast,
|
||||
.depth = inputs.brush.m_pattern_depth,
|
||||
.blend_mode = inputs.composite_pass.pattern_blend_mode,
|
||||
.offset = glm::vec2(inputs.brush.m_pattern_rand_offset ? 0.5f : 0.0f),
|
||||
},
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
.layer_alpha = 1.0f,
|
||||
.alpha_lock = false,
|
||||
.mask_enabled = false,
|
||||
.use_fragcoord = false,
|
||||
.blend_mode = inputs.brush.m_blend_mode,
|
||||
.use_dual = inputs.composite_pass.use_dual,
|
||||
.dual_blend_mode = inputs.composite_pass.dual_blend_mode,
|
||||
.dual_alpha = inputs.composite_pass.dual_alpha,
|
||||
.use_pattern = inputs.composite_pass.use_pattern,
|
||||
});
|
||||
},
|
||||
[&] {
|
||||
inputs.linear_sampler.bind(stroke_preview_composite_slots::kBackground);
|
||||
inputs.linear_sampler.bind(stroke_preview_composite_slots::kStroke);
|
||||
inputs.linear_sampler.bind(2U);
|
||||
inputs.linear_sampler.bind(stroke_preview_composite_slots::kDual);
|
||||
inputs.repeat_sampler.bind(stroke_preview_composite_slots::kPattern);
|
||||
},
|
||||
[&] {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
||||
inputs.background_texture.bind();
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
||||
inputs.stroke_texture.bind();
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kDual);
|
||||
inputs.dual_texture.bind();
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kPattern);
|
||||
inputs.brush.m_pattern_texture ?
|
||||
inputs.brush.m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
},
|
||||
[&] {
|
||||
inputs.draw_composite();
|
||||
});
|
||||
}
|
||||
|
||||
template <typename Frames, typename BeforeFrame, typename DrawSample>
|
||||
void execute_stroke_preview_frames(
|
||||
Frames& frames,
|
||||
@@ -585,53 +657,20 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
|
||||
// COMPOSITE
|
||||
|
||||
pp::panopainter::execute_legacy_stroke_preview_final_composite(
|
||||
[&] {
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
pp::panopainter::LegacyStrokeCompositeUniforms {
|
||||
.resolution = size,
|
||||
.pattern = {
|
||||
.scale = patt_scale,
|
||||
.invert = static_cast<float>(b->m_pattern_invert),
|
||||
.brightness = b->m_pattern_brightness,
|
||||
.contrast = b->m_pattern_contrast,
|
||||
.depth = b->m_pattern_depth,
|
||||
.blend_mode = material.composite_pass.pattern_blend_mode,
|
||||
.offset = glm::vec2(b->m_pattern_rand_offset ? 0.5f : 0.0f),
|
||||
},
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
.layer_alpha = 1.0f,
|
||||
.alpha_lock = false,
|
||||
.mask_enabled = false,
|
||||
.use_fragcoord = false,
|
||||
.blend_mode = b->m_blend_mode,
|
||||
.use_dual = material.composite_pass.use_dual,
|
||||
.dual_blend_mode = material.composite_pass.dual_blend_mode,
|
||||
.dual_alpha = material.composite_pass.dual_alpha,
|
||||
.use_pattern = material.composite_pass.use_pattern,
|
||||
});
|
||||
},
|
||||
[&] {
|
||||
m_sampler_linear.bind(0);
|
||||
m_sampler_linear.bind(1);
|
||||
m_sampler_linear.bind(2);
|
||||
m_sampler_linear.bind(3);
|
||||
m_sampler_linear_repeat.bind(4);
|
||||
},
|
||||
[&] {
|
||||
set_active_texture_unit(0U);
|
||||
m_tex_background.bind();
|
||||
set_active_texture_unit(1U);
|
||||
m_tex.bind();
|
||||
set_active_texture_unit(3U);
|
||||
m_tex_dual.bind();
|
||||
set_active_texture_unit(4U);
|
||||
b->m_pattern_texture ?
|
||||
b->m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
},
|
||||
[&] {
|
||||
m_plane.draw_fill();
|
||||
execute_stroke_preview_final_composite_pass(
|
||||
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();
|
||||
},
|
||||
});
|
||||
|
||||
// copy the result to the actual preview
|
||||
|
||||
Reference in New Issue
Block a user