Harden retained stroke commit helper tests

This commit is contained in:
2026-06-13 10:25:51 +02:00
parent 65b24d9516
commit ddadaa0405

View File

@@ -8,6 +8,7 @@
#include <cmath>
#include <cstdint>
#include <span>
#include <string>
#include <string_view>
#include <vector>
@@ -1926,6 +1927,137 @@ void retained_stroke_commit_dilate_copy_uses_layer_scratch_slot(pp::tests::Harne
PP_EXPECT(h, copy_regions[0].height == 128);
}
void retained_stroke_commit_runner_preserves_per_face_step_order(pp::tests::Harness& h)
{
const auto sequence = plan_canvas_stroke_commit_sequence(
CanvasStrokeCommitRequest {
.erase_mode = false,
.alpha_locked = false,
.selection_mask_active = true,
.dual_stroke_enabled = true,
.pattern_enabled = true,
});
std::vector<std::string> events;
const auto record = [&](std::string_view event, int face_index = -1) {
if (face_index >= 0) {
events.push_back(std::string(event) + ":" + std::to_string(face_index));
} else {
events.push_back(std::string(event));
}
};
const auto result = pp::panopainter::execute_legacy_canvas_stroke_commit_sequence(
pp::panopainter::LegacyCanvasStrokeCommitRequest {
.context = "test",
.faces = {
pp::panopainter::LegacyCanvasStrokeCommitFace { .index = 0, .dirty = true },
pp::panopainter::LegacyCanvasStrokeCommitFace { .index = 1, .dirty = false },
pp::panopainter::LegacyCanvasStrokeCommitFace { .index = 2, .dirty = true },
},
.sequence = sequence,
.callbacks = {
.mark_commit_started = [&]() { record("start"); },
.capture_render_state = [&]() { record("capture"); },
.prepare_render_state = [&]() { record("prepare"); },
.restore_render_state = [&]() { record("restore"); },
.publish_history = [&]() { record("publish"); },
.capture_timelapse_frame = [&]() { record("timelapse"); },
.bind_layer_framebuffer = [&](int face_index) { record("bind-fbo", face_index); },
.capture_history_region = [&](int face_index) { record("history", face_index); },
.apply_layer_dirty_region = [&](int face_index) { record("dirty", face_index); },
.copy_layer_to_commit_destination = [&](int face_index) { record("copy-layer", face_index); },
.bind_commit_inputs = [&](int face_index) { record("bind-inputs", face_index); },
.execute_erase_composite = [&](int face_index) { record("erase", face_index); },
.execute_paint_composite = [&](int face_index) { record("paint", face_index); },
.copy_committed_to_dilate_source = [&](int face_index) { record("copy-committed", face_index); },
.execute_commit_dilate = [&](int face_index) { record("dilate", face_index); },
.unbind_layer_framebuffer = [&](int face_index) { record("unbind-fbo", face_index); },
},
});
const std::vector<std::string> expected {
"start",
"capture",
"prepare",
"bind-fbo:0",
"history:0",
"dirty:0",
"copy-layer:0",
"bind-inputs:0",
"paint:0",
"copy-committed:0",
"dilate:0",
"unbind-fbo:0",
"bind-fbo:2",
"history:2",
"dirty:2",
"copy-layer:2",
"bind-inputs:2",
"paint:2",
"copy-committed:2",
"dilate:2",
"unbind-fbo:2",
"restore",
"publish",
"timelapse",
};
PP_EXPECT(h, result.ok);
PP_EXPECT(h, result.committed_faces == 2);
PP_EXPECT(h, events == expected);
}
void retained_stroke_commit_copy_skips_missing_layer_scratch_or_invalid_extent(pp::tests::Harness& h)
{
pp::paint_renderer::CanvasStrokeCommitSequencePlan missing_scratch;
missing_scratch.texture_binding_count = 1U;
missing_scratch.texture_bindings[0] = pp::paint_renderer::CanvasStrokeCommitTextureBindingPlan {
.role = CanvasStrokeCommitTextureRole::stroke,
.slot = 4,
};
int setup_calls = 0;
int active_texture_calls = 0;
int bind_layer_scratch_calls = 0;
int copy_calls = 0;
pp::panopainter::copy_legacy_canvas_stroke_commit_to_dilate_source(
missing_scratch,
[&]() { ++setup_calls; },
[&](int) { ++active_texture_calls; },
[&]() { ++bind_layer_scratch_calls; },
[&](int, int, int, int, int, int) { ++copy_calls; },
pp::panopainter::LegacyCanvasStrokeCommitCopyExtent {
.width = 256,
.height = 128,
});
const auto valid_sequence = plan_canvas_stroke_commit_sequence(
CanvasStrokeCommitRequest {
.erase_mode = true,
.alpha_locked = true,
.selection_mask_active = false,
.dual_stroke_enabled = false,
.pattern_enabled = false,
});
pp::panopainter::copy_legacy_canvas_stroke_commit_to_dilate_source(
valid_sequence,
[&]() { ++setup_calls; },
[&](int) { ++active_texture_calls; },
[&]() { ++bind_layer_scratch_calls; },
[&](int, int, int, int, int, int) { ++copy_calls; },
pp::panopainter::LegacyCanvasStrokeCommitCopyExtent {
.width = 0,
.height = 128,
});
PP_EXPECT(h, setup_calls == 0);
PP_EXPECT(h, active_texture_calls == 0);
PP_EXPECT(h, bind_layer_scratch_calls == 0);
PP_EXPECT(h, copy_calls == 0);
}
void plans_stroke_preview_composite_for_simple_brush(pp::tests::Harness& h)
{
const auto plan = plan_stroke_preview_composite(StrokePreviewCompositeRequest {});
@@ -2486,6 +2618,12 @@ int main()
harness.run(
"retained_stroke_commit_dilate_copy_uses_layer_scratch_slot",
retained_stroke_commit_dilate_copy_uses_layer_scratch_slot);
harness.run(
"retained_stroke_commit_runner_preserves_per_face_step_order",
retained_stroke_commit_runner_preserves_per_face_step_order);
harness.run(
"retained_stroke_commit_copy_skips_missing_layer_scratch_or_invalid_extent",
retained_stroke_commit_copy_skips_missing_layer_scratch_or_invalid_extent);
harness.run("plans_stroke_preview_composite_for_simple_brush", plans_stroke_preview_composite_for_simple_brush);
harness.run("plans_stroke_preview_composite_with_mixer_input", plans_stroke_preview_composite_with_mixer_input);
harness.run("plans_stroke_preview_composite_with_dual_input", plans_stroke_preview_composite_with_dual_input);