Share retained stroke face sample dispatch
This commit is contained in:
@@ -33,6 +33,11 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
final plane draw ordering through `execute_legacy_canvas_stroke_mix_pass(...)`;
|
final plane draw ordering through `execute_legacy_canvas_stroke_mix_pass(...)`;
|
||||||
mixer framebuffer/state setup and per-plane shader material/MVP preparation
|
mixer framebuffer/state setup and per-plane shader material/MVP preparation
|
||||||
remain retained in `Canvas`.
|
remain retained in `Canvas`.
|
||||||
|
- 2026-06-13: DEBT-0036 was narrowed again. `Canvas::stroke_draw_samples()`
|
||||||
|
now routes face-indexed destination bind/copy/unbind and brush upload/draw
|
||||||
|
through `execute_legacy_canvas_stroke_face_sample_polygon(...)`; the
|
||||||
|
retained sample executor owns the face-aware dispatch contract while
|
||||||
|
`Canvas` keeps only concrete GL object callbacks.
|
||||||
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_mix()`
|
- 2026-06-13: DEBT-0036 was narrowed again. `NodeStrokePreview::stroke_draw_mix()`
|
||||||
now routes mixer framebuffer bind/unbind, viewport/scissor/blend state,
|
now routes mixer framebuffer bind/unbind, viewport/scissor/blend state,
|
||||||
texture-slot binding, and final plane draw through one local helper;
|
texture-slot binding, and final plane draw through one local helper;
|
||||||
|
|||||||
@@ -3133,6 +3133,10 @@ Results:
|
|||||||
retained sampler/texture-slot binding, and final plane draw ordering, while
|
retained sampler/texture-slot binding, and final plane draw ordering, while
|
||||||
mixer framebuffer/state setup and per-plane shader material/MVP preparation
|
mixer framebuffer/state setup and per-plane shader material/MVP preparation
|
||||||
remain in the legacy Canvas path.
|
remain in the legacy Canvas path.
|
||||||
|
- `Canvas::stroke_draw_samples()` now shares
|
||||||
|
`execute_legacy_canvas_stroke_face_sample_polygon(...)` for face-indexed
|
||||||
|
destination bind/copy/unbind and brush upload/draw dispatch, while concrete
|
||||||
|
GL object callbacks remain in the legacy Canvas path.
|
||||||
- `NodeStrokePreview::stroke_draw_mix()` now shares one local helper for mixer
|
- `NodeStrokePreview::stroke_draw_mix()` now shares one local helper for mixer
|
||||||
framebuffer bind/unbind, viewport/scissor/blend state, texture-slot
|
framebuffer bind/unbind, viewport/scissor/blend state, texture-slot
|
||||||
binding, and final plane draw, while material planning and shader uniform
|
binding, and final plane draw, while material planning and shader uniform
|
||||||
|
|||||||
@@ -509,6 +509,13 @@ Done Checks:
|
|||||||
|
|
||||||
Progress Notes:
|
Progress Notes:
|
||||||
|
|
||||||
|
- 2026-06-13: `Canvas::stroke_draw_samples()` now routes face-indexed
|
||||||
|
destination bind/copy/unbind and brush upload/draw through
|
||||||
|
`execute_legacy_canvas_stroke_face_sample_polygon(...)`; the retained sample
|
||||||
|
executor now owns the face-aware dispatch contract while `Canvas` keeps only
|
||||||
|
the concrete GL object callbacks. Next slice should target any remaining
|
||||||
|
final temporary-texture composite setup without reopening landed sample,
|
||||||
|
mix, sampler, dirty, face, or pad helpers.
|
||||||
- 2026-06-13: `pp_paint_renderer_stroke_execution_tests` now also covers
|
- 2026-06-13: `pp_paint_renderer_stroke_execution_tests` now also covers
|
||||||
direct retained frame-sample callback ordering plus
|
direct retained frame-sample callback ordering plus
|
||||||
`execute_legacy_canvas_stroke_frame_samples_with_dirty_tracking(...)`
|
`execute_legacy_canvas_stroke_frame_samples_with_dirty_tracking(...)`
|
||||||
|
|||||||
@@ -565,17 +565,33 @@ glm::vec4 Canvas::stroke_draw_samples(
|
|||||||
std::vector<vertex_t>& P,
|
std::vector<vertex_t>& P,
|
||||||
bool copy_stroke_destination)
|
bool copy_stroke_destination)
|
||||||
{
|
{
|
||||||
const auto result = pp::panopainter::execute_legacy_canvas_stroke_sample_polygon(
|
constexpr std::array destination_texture_binding {
|
||||||
pp::panopainter::LegacyStrokeSamplePolygonExecutionRequest {
|
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||||
|
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination,
|
||||||
|
.slot = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const auto result = pp::panopainter::execute_legacy_canvas_stroke_face_sample_polygon(
|
||||||
|
pp::panopainter::LegacyStrokeFaceSamplePolygonExecutionRequest {
|
||||||
.context = "Canvas::stroke_draw_samples",
|
.context = "Canvas::stroke_draw_samples",
|
||||||
.target_size = { m_width, m_height },
|
.target_size = { m_width, m_height },
|
||||||
.polygon_vertices = P,
|
.polygon_vertices = P,
|
||||||
|
.face_index = i,
|
||||||
.copy_stroke_destination = copy_stroke_destination,
|
.copy_stroke_destination = copy_stroke_destination,
|
||||||
.bind_destination_texture = [&] {
|
.bind_destination_texture = [&](int face_index) {
|
||||||
set_active_texture_unit(1);
|
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||||
m_tex[i].bind(); // bg, copy of framebuffer (copied before drawing)
|
destination_texture_binding,
|
||||||
|
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch {
|
||||||
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
|
set_active_texture_unit(texture_slot);
|
||||||
|
},
|
||||||
|
.bind_stroke_destination = [&] {
|
||||||
|
m_tex[face_index].bind(); // bg, copy of framebuffer (copied before drawing)
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
.copy_framebuffer_to_destination_texture = [](
|
.copy_framebuffer_to_destination_texture = [](
|
||||||
|
int,
|
||||||
int src_x,
|
int src_x,
|
||||||
int src_y,
|
int src_y,
|
||||||
int dst_x,
|
int dst_x,
|
||||||
@@ -584,16 +600,24 @@ glm::vec4 Canvas::stroke_draw_samples(
|
|||||||
int height) {
|
int height) {
|
||||||
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
||||||
},
|
},
|
||||||
.unbind_destination_texture = [&] {
|
.unbind_destination_texture = [&](int face_index) {
|
||||||
set_active_texture_unit(1);
|
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||||
m_tex[i].unbind();
|
destination_texture_binding,
|
||||||
|
pp::panopainter::LegacyCanvasStrokeTextureInputDispatch {
|
||||||
|
.activate_texture_unit = [&](int texture_slot) {
|
||||||
|
set_active_texture_unit(texture_slot);
|
||||||
|
},
|
||||||
|
.unbind_stroke_destination = [&] {
|
||||||
|
m_tex[face_index].unbind();
|
||||||
|
},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
.upload_brush_vertices = [&](std::span<const vertex_t> vertices) {
|
.upload_brush_vertices = [&](int, std::span<const vertex_t> vertices) {
|
||||||
m_brush_shape.update_vertices(
|
m_brush_shape.update_vertices(
|
||||||
const_cast<vertex_t*>(vertices.data()),
|
const_cast<vertex_t*>(vertices.data()),
|
||||||
static_cast<int>(vertices.size()));
|
static_cast<int>(vertices.size()));
|
||||||
},
|
},
|
||||||
.draw_brush_shape = [&] {
|
.draw_brush_shape = [&](int) {
|
||||||
m_brush_shape.draw_fill();
|
m_brush_shape.draw_fill();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -49,6 +49,19 @@ struct LegacyStrokeSamplePolygonExecutionRequest {
|
|||||||
std::function<void()> draw_brush_shape;
|
std::function<void()> draw_brush_shape;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct LegacyStrokeFaceSamplePolygonExecutionRequest {
|
||||||
|
std::string_view context;
|
||||||
|
glm::vec2 target_size {};
|
||||||
|
std::span<const vertex_t> polygon_vertices;
|
||||||
|
int face_index = 0;
|
||||||
|
bool copy_stroke_destination = false;
|
||||||
|
std::function<void(int)> bind_destination_texture;
|
||||||
|
std::function<void(int, int, int, int, int, int, int)> copy_framebuffer_to_destination_texture;
|
||||||
|
std::function<void(int)> unbind_destination_texture;
|
||||||
|
std::function<void(int, std::span<const vertex_t>)> upload_brush_vertices;
|
||||||
|
std::function<void(int)> draw_brush_shape;
|
||||||
|
};
|
||||||
|
|
||||||
enum class LegacyCanvasStrokeTextureInput {
|
enum class LegacyCanvasStrokeTextureInput {
|
||||||
brush_tip,
|
brush_tip,
|
||||||
stroke_destination,
|
stroke_destination,
|
||||||
@@ -952,6 +965,52 @@ template <typename ExecuteSample, typename BeginFace, typename PrepareDirtyReque
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline LegacyStrokeSampleExecutionResult execute_legacy_canvas_stroke_face_sample_polygon(
|
||||||
|
const LegacyStrokeFaceSamplePolygonExecutionRequest& request)
|
||||||
|
{
|
||||||
|
if (!request.upload_brush_vertices || !request.draw_brush_shape) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.copy_stroke_destination &&
|
||||||
|
(!request.bind_destination_texture ||
|
||||||
|
!request.copy_framebuffer_to_destination_texture ||
|
||||||
|
!request.unbind_destination_texture)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return execute_legacy_canvas_stroke_sample_polygon(
|
||||||
|
LegacyStrokeSamplePolygonExecutionRequest {
|
||||||
|
.context = request.context,
|
||||||
|
.target_size = request.target_size,
|
||||||
|
.polygon_vertices = request.polygon_vertices,
|
||||||
|
.copy_stroke_destination = request.copy_stroke_destination,
|
||||||
|
.bind_destination_texture = [&] {
|
||||||
|
request.bind_destination_texture(request.face_index);
|
||||||
|
},
|
||||||
|
.copy_framebuffer_to_destination_texture =
|
||||||
|
[&](int src_x, int src_y, int dst_x, int dst_y, int width, int height) {
|
||||||
|
request.copy_framebuffer_to_destination_texture(
|
||||||
|
request.face_index,
|
||||||
|
src_x,
|
||||||
|
src_y,
|
||||||
|
dst_x,
|
||||||
|
dst_y,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
},
|
||||||
|
.unbind_destination_texture = [&] {
|
||||||
|
request.unbind_destination_texture(request.face_index);
|
||||||
|
},
|
||||||
|
.upload_brush_vertices = [&](std::span<const vertex_t> vertices) {
|
||||||
|
request.upload_brush_vertices(request.face_index, vertices);
|
||||||
|
},
|
||||||
|
.draw_brush_shape = [&] {
|
||||||
|
request.draw_brush_shape(request.face_index);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline LegacyCanvasStrokeMixPassResult execute_legacy_canvas_stroke_mix_pass(
|
[[nodiscard]] inline LegacyCanvasStrokeMixPassResult execute_legacy_canvas_stroke_mix_pass(
|
||||||
const LegacyCanvasStrokeMixPassRequest& request)
|
const LegacyCanvasStrokeMixPassRequest& request)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user