Extract stroke commit history mutation helpers
This commit is contained in:
@@ -182,6 +182,10 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
routes the remaining service wiring through `make_canvas_stroke_commit_request(...)`;
|
routes the remaining service wiring through `make_canvas_stroke_commit_request(...)`;
|
||||||
the retained path still owns the concrete history mutation and layer dirty
|
the retained path still owns the concrete history mutation and layer dirty
|
||||||
box updates.
|
box updates.
|
||||||
|
- 2026-06-13: DEBT-0036 was narrowed again. `Canvas::stroke_commit()` now
|
||||||
|
routes action bookkeeping and dirty-box capture/mutation through helper
|
||||||
|
functions; the retained callback builder now only forwards concrete canvas
|
||||||
|
state.
|
||||||
- 2026-06-13: DEBT-0036 was narrowed again. `Canvas::stroke_commit()` now
|
- 2026-06-13: DEBT-0036 was narrowed again. `Canvas::stroke_commit()` now
|
||||||
builds its retained callback table through
|
builds its retained callback table through
|
||||||
`make_legacy_canvas_stroke_commit_callbacks(...)`; the legacy executor still
|
`make_legacy_canvas_stroke_commit_callbacks(...)`; the legacy executor still
|
||||||
|
|||||||
@@ -1839,7 +1839,7 @@ ctest --preset desktop-fast --build-config Debug -R "pp_paint_renderer_stroke_ex
|
|||||||
|
|
||||||
### STR-040 - Extract Stroke Commit Local History And Dirty Mutation
|
### STR-040 - Extract Stroke Commit Local History And Dirty Mutation
|
||||||
|
|
||||||
Status: Ready
|
Status: Done
|
||||||
Score: +1 renderer boundary and OpenGL parity
|
Score: +1 renderer boundary and OpenGL parity
|
||||||
Debt: `DEBT-0036`
|
Debt: `DEBT-0036`
|
||||||
Scope: `src/canvas.cpp`, `tests/paint_renderer/stroke_execution_tests.cpp`
|
Scope: `src/canvas.cpp`, `tests/paint_renderer/stroke_execution_tests.cpp`
|
||||||
@@ -1850,6 +1850,8 @@ Move the remaining local history and dirty-mutation work inside
|
|||||||
`make_canvas_stroke_commit_callbacks()` into a retained helper so the callback
|
`make_canvas_stroke_commit_callbacks()` into a retained helper so the callback
|
||||||
builder only forwards concrete canvas state.
|
builder only forwards concrete canvas state.
|
||||||
|
|
||||||
|
Closeout: `aa53a5f9`
|
||||||
|
|
||||||
Done Checks:
|
Done Checks:
|
||||||
|
|
||||||
- `make_canvas_stroke_commit_callbacks()` no longer owns the history/dirty
|
- `make_canvas_stroke_commit_callbacks()` no longer owns the history/dirty
|
||||||
|
|||||||
@@ -606,48 +606,13 @@ static auto make_canvas_stroke_commit_callbacks(
|
|||||||
canvas.apply_canvas_clear_color(cc);
|
canvas.apply_canvas_clear_color(cc);
|
||||||
set_active_texture_unit(0);
|
set_active_texture_unit(0);
|
||||||
},
|
},
|
||||||
[&]() {
|
[&]() { stamp_canvas_stroke_commit_action(canvas, action); },
|
||||||
action->m_layer_idx = canvas.m_current_layer_idx;
|
|
||||||
action->m_frame_idx = canvas.layer().m_frame_index;
|
|
||||||
action->m_canvas = &canvas;
|
|
||||||
ActionManager::add(action);
|
|
||||||
},
|
|
||||||
[&]() {
|
[&]() {
|
||||||
canvas.stroke_commit_timelapse();
|
canvas.stroke_commit_timelapse();
|
||||||
},
|
},
|
||||||
[&](int i) {
|
[&](int i) { capture_canvas_stroke_commit_layer_state(canvas, action, i); },
|
||||||
canvas.m_layers[canvas.m_current_layer_idx]->rtt(i).bindFramebuffer();
|
[&](int i) { apply_canvas_stroke_commit_dirty_mutation(canvas, i); },
|
||||||
},
|
[&](int i) { copy_canvas_stroke_commit_layer_image(canvas, i); },
|
||||||
[&](int i) {
|
|
||||||
glm::vec2 box_sz = zw(canvas.m_dirty_box[i]) - xy(canvas.m_dirty_box[i]);
|
|
||||||
action->m_image[i] = std::make_unique<uint8_t[]>(
|
|
||||||
static_cast<std::size_t>(box_sz.x * box_sz.y * 4));
|
|
||||||
canvas.m_layers[canvas.m_current_layer_idx]->rtt(i).readPixelsRgba8(
|
|
||||||
static_cast<int>(canvas.m_dirty_box[i].x),
|
|
||||||
static_cast<int>(canvas.m_dirty_box[i].y),
|
|
||||||
static_cast<int>(box_sz.x),
|
|
||||||
static_cast<int>(box_sz.y),
|
|
||||||
action->m_image[i].get());
|
|
||||||
|
|
||||||
action->m_box[i] = canvas.m_dirty_box[i];
|
|
||||||
action->m_old_box[i] = canvas.m_layers[canvas.m_current_layer_idx]->box(i);
|
|
||||||
action->m_old_dirty[i] = canvas.m_layers[canvas.m_current_layer_idx]->face(i);
|
|
||||||
},
|
|
||||||
[&](int i) {
|
|
||||||
if (!canvas.m_layers[canvas.m_current_layer_idx]->m_alpha_locked) {
|
|
||||||
auto& lbox = canvas.m_layers[canvas.m_current_layer_idx]->box(i);
|
|
||||||
lbox = glm::vec4(
|
|
||||||
glm::min(xy(canvas.m_dirty_box[i]), xy(lbox)),
|
|
||||||
glm::max(zw(canvas.m_dirty_box[i]), zw(lbox)));
|
|
||||||
}
|
|
||||||
canvas.m_layers[canvas.m_current_layer_idx]->face(i) = true;
|
|
||||||
},
|
|
||||||
[&](int i) {
|
|
||||||
set_active_texture_unit(0);
|
|
||||||
canvas.m_tex2[i].bind();
|
|
||||||
copy_framebuffer_to_texture_2d(0, 0, 0, 0, canvas.m_width, canvas.m_height);
|
|
||||||
canvas.m_tex2[i].unbind();
|
|
||||||
},
|
|
||||||
[&](int i) {
|
[&](int i) {
|
||||||
bind_commit_inputs(i);
|
bind_commit_inputs(i);
|
||||||
},
|
},
|
||||||
@@ -848,6 +813,61 @@ static auto make_canvas_stroke_commit_request(
|
|||||||
return pp::panopainter::make_legacy_canvas_stroke_commit_request(faces, sequence, commit_callbacks);
|
return pp::panopainter::make_legacy_canvas_stroke_commit_request(faces, sequence, commit_callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stamp_canvas_stroke_commit_action(
|
||||||
|
Canvas& canvas,
|
||||||
|
ActionStroke* action)
|
||||||
|
{
|
||||||
|
action->m_layer_idx = canvas.m_current_layer_idx;
|
||||||
|
action->m_frame_idx = canvas.layer().m_frame_index;
|
||||||
|
action->m_canvas = &canvas;
|
||||||
|
ActionManager::add(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void capture_canvas_stroke_commit_layer_state(
|
||||||
|
Canvas& canvas,
|
||||||
|
ActionStroke* action,
|
||||||
|
int i)
|
||||||
|
{
|
||||||
|
canvas.m_layers[canvas.m_current_layer_idx]->rtt(i).bindFramebuffer();
|
||||||
|
|
||||||
|
glm::vec2 box_sz = zw(canvas.m_dirty_box[i]) - xy(canvas.m_dirty_box[i]);
|
||||||
|
action->m_image[i] = std::make_unique<uint8_t[]>(
|
||||||
|
static_cast<std::size_t>(box_sz.x * box_sz.y * 4));
|
||||||
|
canvas.m_layers[canvas.m_current_layer_idx]->rtt(i).readPixelsRgba8(
|
||||||
|
static_cast<int>(canvas.m_dirty_box[i].x),
|
||||||
|
static_cast<int>(canvas.m_dirty_box[i].y),
|
||||||
|
static_cast<int>(box_sz.x),
|
||||||
|
static_cast<int>(box_sz.y),
|
||||||
|
action->m_image[i].get());
|
||||||
|
|
||||||
|
action->m_box[i] = canvas.m_dirty_box[i];
|
||||||
|
action->m_old_box[i] = canvas.m_layers[canvas.m_current_layer_idx]->box(i);
|
||||||
|
action->m_old_dirty[i] = canvas.m_layers[canvas.m_current_layer_idx]->face(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void apply_canvas_stroke_commit_dirty_mutation(
|
||||||
|
Canvas& canvas,
|
||||||
|
int i)
|
||||||
|
{
|
||||||
|
if (!canvas.m_layers[canvas.m_current_layer_idx]->m_alpha_locked) {
|
||||||
|
auto& lbox = canvas.m_layers[canvas.m_current_layer_idx]->box(i);
|
||||||
|
lbox = glm::vec4(
|
||||||
|
glm::min(xy(canvas.m_dirty_box[i]), xy(lbox)),
|
||||||
|
glm::max(zw(canvas.m_dirty_box[i]), zw(lbox)));
|
||||||
|
}
|
||||||
|
canvas.m_layers[canvas.m_current_layer_idx]->face(i) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_canvas_stroke_commit_layer_image(
|
||||||
|
Canvas& canvas,
|
||||||
|
int i)
|
||||||
|
{
|
||||||
|
set_active_texture_unit(0);
|
||||||
|
canvas.m_tex2[i].bind();
|
||||||
|
copy_framebuffer_to_texture_2d(0, 0, 0, 0, canvas.m_width, canvas.m_height);
|
||||||
|
canvas.m_tex2[i].unbind();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Canvas::StrokeFrame> Canvas::stroke_draw_compute(Stroke& stroke) const
|
std::vector<Canvas::StrokeFrame> Canvas::stroke_draw_compute(Stroke& stroke) const
|
||||||
{
|
{
|
||||||
auto samples = stroke.compute_samples();
|
auto samples = stroke.compute_samples();
|
||||||
|
|||||||
Reference in New Issue
Block a user