From ed95b084f0837fa3748115f25b50957b93321d05 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 13 Jun 2026 11:45:40 +0200 Subject: [PATCH] Wire retained stroke polygon tests to poly2tri --- tests/CMakeLists.txt | 7 +- .../paint_renderer/stroke_execution_tests.cpp | 130 ++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 536e486..95010f3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -278,7 +278,12 @@ set_tests_properties(pp_paint_renderer_compositor_tests PROPERTIES LABELS "renderer;paint;desktop-fast") add_executable(pp_paint_renderer_stroke_execution_tests - paint_renderer/stroke_execution_tests.cpp) + paint_renderer/stroke_execution_tests.cpp + ../libs/poly2tri/poly2tri/common/shapes.cc + ../libs/poly2tri/poly2tri/sweep/advancing_front.cc + ../libs/poly2tri/poly2tri/sweep/cdt.cc + ../libs/poly2tri/poly2tri/sweep/sweep.cc + ../libs/poly2tri/poly2tri/sweep/sweep_context.cc) target_link_libraries(pp_paint_renderer_stroke_execution_tests PRIVATE pp_paint_renderer pp_test_harness) diff --git a/tests/paint_renderer/stroke_execution_tests.cpp b/tests/paint_renderer/stroke_execution_tests.cpp index 979a36a..d41ff1e 100644 --- a/tests/paint_renderer/stroke_execution_tests.cpp +++ b/tests/paint_renderer/stroke_execution_tests.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include "legacy_canvas_stroke_execution_services.h" #include "legacy_canvas_stroke_preview_services.h" #include "test_harness.h" @@ -34,6 +36,32 @@ using pp::panopainter::LegacyCanvasStrokeTextureInput; using pp::panopainter::LegacyStrokePreviewCopySize; using pp::panopainter::LegacyStrokeSampleExecutionRequest; +std::vector triangulate_simple(const std::vector& vertices) +{ + std::vector ret; + std::vector points(vertices.size()); + std::vector points_ptr(vertices.size()); + for (std::size_t i = 0; i < vertices.size(); ++i) + { + points[i] = { vertices[i].pos.x, vertices[i].pos.y }; + points_ptr[i] = &points[i]; + } + + auto cdt = std::make_unique(points_ptr); + cdt->Triangulate(); + const auto triangles = cdt->GetTriangles(); + for (auto* triangle : triangles) + { + for (int i = 0; i < 3; ++i) + { + const auto index = std::distance(points.data(), triangle->GetPoint(i)); + ret.push_back(vertices[static_cast(index)]); + } + } + + return ret; +} + namespace { bool nearly_equal(float a, float b) @@ -61,6 +89,16 @@ std::array make_sample_points() }; } +std::vector make_polygon_vertices(std::initializer_list points) +{ + std::vector vertices; + vertices.reserve(points.size()); + for (const auto& point : points) { + vertices.emplace_back(point); + } + return vertices; +} + void retained_stroke_texture_inputs_bind_and_unbind_in_declared_order(pp::tests::Harness& h) { const std::array bindings { @@ -281,6 +319,95 @@ void retained_stroke_sample_executor_unbinds_and_skips_draw_when_bounds_are_empt PP_EXPECT(h, draw_calls == 0); } +void retained_stroke_face_sample_polygon_triangulates_and_forwards_face_callbacks(pp::tests::Harness& h) +{ + const auto polygon_vertices = make_polygon_vertices({ + glm::vec2(10.0F, 10.0F), + glm::vec2(30.0F, 10.0F), + glm::vec2(35.0F, 20.0F), + glm::vec2(20.0F, 35.0F), + glm::vec2(5.0F, 20.0F), + }); + + std::vector events; + std::vector uploaded_vertices; + std::array copy_args {}; + int upload_face_index = -1; + int draw_face_index = -1; + + const auto result = pp::panopainter::execute_legacy_canvas_stroke_face_sample_polygon( + pp::panopainter::LegacyStrokeFaceSamplePolygonExecutionRequest { + .context = "test", + .target_size = glm::vec2(64.0F, 64.0F), + .polygon_vertices = polygon_vertices, + .face_index = 4, + .copy_stroke_destination = true, + .bind_destination_texture = [&](int face_index) { + events.emplace_back("bind:" + std::to_string(face_index)); + }, + .copy_framebuffer_to_destination_texture = + [&](int face_index, int src_x, int src_y, int dst_x, int dst_y, int width, int height) { + events.emplace_back("copy:" + std::to_string(face_index)); + copy_args = { face_index, src_x, src_y, dst_x, dst_y, width, height }; + }, + .unbind_destination_texture = [&](int face_index) { + events.emplace_back("unbind:" + std::to_string(face_index)); + }, + .upload_brush_vertices = [&](int face_index, std::span vertices) { + events.emplace_back("upload:" + std::to_string(face_index) + ":" + std::to_string(vertices.size())); + upload_face_index = face_index; + uploaded_vertices.assign(vertices.begin(), vertices.end()); + }, + .draw_brush_shape = [&](int face_index) { + events.emplace_back("draw:" + std::to_string(face_index)); + draw_face_index = face_index; + }, + }); + + PP_EXPECT(h, result.ok); + PP_EXPECT(h, result.copy_position == glm::ivec2(4, 9)); + PP_EXPECT(h, result.copy_size == glm::ivec2(32, 27)); + PP_EXPECT(h, nearly_equal(result.dirty_bounds.x, 4.0F)); + PP_EXPECT(h, nearly_equal(result.dirty_bounds.y, 9.0F)); + PP_EXPECT(h, nearly_equal(result.dirty_bounds.z, 36.0F)); + PP_EXPECT(h, nearly_equal(result.dirty_bounds.w, 36.0F)); + PP_EXPECT(h, upload_face_index == 4); + PP_EXPECT(h, draw_face_index == 4); + const std::vector expected_events { + "bind:4", + "copy:4", + "upload:4:9", + "draw:4", + "unbind:4", + }; + PP_EXPECT(h, events == expected_events); + PP_EXPECT(h, copy_args[0] == 4); + PP_EXPECT(h, copy_args[1] == 4); + PP_EXPECT(h, copy_args[2] == 9); + PP_EXPECT(h, copy_args[3] == 4); + PP_EXPECT(h, copy_args[4] == 9); + PP_EXPECT(h, copy_args[5] == 32); + PP_EXPECT(h, copy_args[6] == 27); + PP_EXPECT(h, uploaded_vertices.size() == 9U); + + const auto expected_triangulated_vertices = make_polygon_vertices({ + glm::vec2(5.0F, 20.0F), + glm::vec2(10.0F, 10.0F), + glm::vec2(20.0F, 35.0F), + glm::vec2(20.0F, 35.0F), + glm::vec2(10.0F, 10.0F), + glm::vec2(30.0F, 10.0F), + glm::vec2(20.0F, 35.0F), + glm::vec2(30.0F, 10.0F), + glm::vec2(35.0F, 20.0F), + }); + PP_EXPECT(h, uploaded_vertices.size() == expected_triangulated_vertices.size()); + for (std::size_t index = 0; index < uploaded_vertices.size(); ++index) { + PP_EXPECT(h, nearly_equal(uploaded_vertices[index].pos.x, expected_triangulated_vertices[index].pos.x)); + PP_EXPECT(h, nearly_equal(uploaded_vertices[index].pos.y, expected_triangulated_vertices[index].pos.y)); + } +} + struct StrokeFrame { int id = -1; std::array, 6> shapes {}; @@ -825,6 +952,9 @@ int main() harness.run( "retained_stroke_sample_executor_unbinds_and_skips_draw_when_bounds_are_empty", retained_stroke_sample_executor_unbinds_and_skips_draw_when_bounds_are_empty); + harness.run( + "retained_stroke_face_sample_polygon_triangulates_and_forwards_face_callbacks", + retained_stroke_face_sample_polygon_triangulates_and_forwards_face_callbacks); harness.run( "retained_stroke_frame_samples_preserve_frame_face_callback_order", retained_stroke_frame_samples_preserve_frame_face_callback_order);