7#include <unordered_set>
25#if IMPELLER_SUPPORTS_RENDERING
37 return builder.asReceiver();
41 return builder.CurrentAttributes();
45 return builder.LastOpIndex();
50static std::vector<testing::DisplayListInvocationGroup>
allGroups =
53template <
typename BaseT>
65 return builder.
Build();
68 static sk_sp<DisplayList>
Build(
size_t g_index,
size_t v_index) {
72 uint32_t op_count = 0u;
73 size_t byte_count = 0u;
75 uint32_t render_op_depth_cost = 1u;
78 size_t j = (
i == g_index ? v_index : 0);
86 invocation.
Invoke(receiver);
87 render_op_depth_cost =
90 sk_sp<DisplayList> dl = builder.
Build();
96 if (v_index >=
allGroups[g_index].variants.size()) {
99 name +=
" variant " + std::to_string(v_index + 1);
102 EXPECT_EQ(dl->op_count(
false), op_count) <<
name;
104 EXPECT_EQ(dl->total_depth(), depth) <<
name;
127 EXPECT_EQ(builder_paint, defaults);
146 const std::string& desc) {
149 renderer(builder, paint, render_rect);
150 auto dl = builder.
Build();
151 EXPECT_EQ(dl->op_count(), 1u) << desc;
152 EXPECT_EQ(dl->GetBounds(), expected_bounds) << desc;
156 const std::string& desc) {
164 auto empty_setup = [](
DlCanvas&) {};
170 ASSERT_TRUE(invertedLR.
IsEmpty());
172 ASSERT_TRUE(invertedTB.
IsEmpty());
175 ASSERT_TRUE(invertedLTRB.
IsEmpty());
180 ref_bounds, desc +
" LR swapped");
182 ref_bounds, desc +
" TB swapped");
184 ref_bounds, desc +
" LR&TB swapped");
197 stroke_bounds, desc +
" LR swapped, sw 2");
199 stroke_bounds, desc +
" TB swapped, sw 2");
201 stroke_bounds, desc +
" LR&TB swapped, sw 2");
208 maskblur_bounds, desc +
" LR swapped, mask 2");
210 maskblur_bounds, desc +
" TB swapped, mask 2");
212 maskblur_bounds, desc +
" LR&TB swapped, mask 2");
219 erode_bounds, desc +
" LR swapped, erode 2");
221 erode_bounds, desc +
" TB swapped, erode 2");
223 erode_bounds, desc +
" LR&TB swapped, erode 2");
228 for (
DlIndex i = 0;
i < dl->GetRecordCount();
i++) {
229 if (dl->GetOpType(
i) == op_type) {
243 check_defaults(builder);
248 auto dl = builder.
Build();
249 EXPECT_EQ(dl->op_count(), 0u);
251 EXPECT_EQ(dl->total_depth(), 0u);
256 auto dl1 = builder.
Build();
257 auto dl2 = builder.
Build();
258 auto dl3 = builder.
Build();
259 ASSERT_TRUE(dl1->Equals(dl2));
260 ASSERT_TRUE(dl2->Equals(dl3));
268 auto dl1 = builder.
Build();
269 EXPECT_EQ(dl1->op_count(), 1u);
275 auto dl2 = builder.
Build();
276 EXPECT_EQ(dl2->op_count(), 0u);
278 EXPECT_EQ(dl2->GetBounds(),
DlRect());
288 for (
int i = 0;
i <= max_type;
i++) {
294 for (
int i = 0;
i <= max_category;
i++) {
303 auto dl = builder.
Build();
305 EXPECT_EQ(dl->GetOpType(
i), DisplayListOpType::kDrawRect)
315 auto dl = builder.
Build();
318 EXPECT_FALSE(dl->Dispatch(receiver, -1));
319 EXPECT_FALSE(dl->Dispatch(receiver, dl->GetRecordCount()));
323 EXPECT_EQ(dl->GetOpCategory(dl->GetRecordCount()),
336 auto dl = builder.
Build();
339 EXPECT_EQ(dl->GetRecordCount(), 1u);
340 EXPECT_TRUE(dl->Dispatch(receiver, 0u));
341 EXPECT_EQ(dl->GetOpType(0u), DisplayListOpType::kDrawRect);
349 auto dl = builder.
Build();
351 auto dl2 = builder.
Build();
352 ASSERT_TRUE(dl->Equals(dl2));
362 check_defaults(builder, cull_rect);
365 builder.
Scale(10.0f, 10.0f);
367 check_defaults(builder, cull_rect);
370 builder.
Skew(0.1f, 0.1f);
372 check_defaults(builder, cull_rect);
377 check_defaults(builder, cull_rect);
382 check_defaults(builder, cull_rect);
388 check_defaults(builder, cull_rect);
392 0.0f, 1.0f, 0.0f, 35.0f,
393 0.0f, 0.0f, 1.0f, 5.0f,
394 0.0f, 0.0f, 0.0f, 1.0f);
396 check_defaults(builder, cull_rect);
405 check_defaults(builder, cull_rect);
407 builder.
Scale(10.0f, 10.0f);
409 check_defaults(builder, cull_rect);
411 builder.
Skew(0.1f, 0.1f);
413 check_defaults(builder, cull_rect);
417 check_defaults(builder, cull_rect);
421 check_defaults(builder, cull_rect);
426 check_defaults(builder, cull_rect);
429 0.0f, 1.0f, 0.0f, 35.0f,
430 0.0f, 0.0f, 1.0f, 5.0f,
431 0.0f, 0.0f, 0.0f, 1.0f);
433 check_defaults(builder, cull_rect);
443 check_defaults(builder, cull_rect);
449 check_defaults(builder, cull_rect);
454 check_defaults(builder, cull_rect);
463 check_defaults(builder, cull_rect);
468 check_defaults(builder, cull_rect);
472 check_defaults(builder, cull_rect);
482 check_defaults(builder, cull_rect);
486 check_defaults(builder, cull_rect);
490 check_defaults(builder, cull_rect);
494 check_defaults(builder, cull_rect);
498 check_defaults(builder, cull_rect);
502 check_defaults(builder, cull_rect);
506 check_defaults(builder, cull_rect);
510 check_defaults(builder, cull_rect);
514 check_defaults(builder, cull_rect);
518 check_defaults(builder, cull_rect);
522 check_defaults(builder, cull_rect);
526 check_defaults(builder, cull_rect);
530 check_defaults(builder, cull_rect);
549 auto NaN = std::numeric_limits<DlScalar>::quiet_NaN();
600 ASSERT_TRUE(cull_rect.
Contains(clip_rect));
601 ASSERT_TRUE(cull_rect.
Contains(draw_rect));
607 builder.
SaveLayer(cull_rect, &layer_paint);
614 auto display_list = builder.
Build();
616 EXPECT_EQ(display_list->op_count(), 6u);
617 EXPECT_EQ(display_list->total_depth(), 2u);
623 EXPECT_EQ(display_list->GetBounds(), result_rect);
634 ASSERT_TRUE(cull_rect.
Contains(clip_rect));
635 ASSERT_TRUE(cull_rect.
Contains(draw_rect));
641 builder.
SaveLayer(cull_rect, &layer_paint);
648 auto display_list = builder.
Build();
650 EXPECT_EQ(display_list->op_count(), 6u);
651 EXPECT_EQ(display_list->total_depth(), 2u);
657 EXPECT_EQ(display_list->GetBounds(), result_rect);
672 ASSERT_TRUE(filter->map_local_bounds(draw_rect, mapped_rect));
676 builder.
SaveLayer(cull_rect, &layer_paint);
681 auto display_list = builder.
Build();
683 EXPECT_EQ(display_list->op_count(), 2u);
684 EXPECT_EQ(display_list->total_depth(), 1u);
686 EXPECT_TRUE(display_list->GetBounds().IsEmpty()) << display_list->GetBounds();
702 ASSERT_TRUE(filter->map_local_bounds(draw_rect, mapped_rect));
706 builder.
SaveLayer(cull_rect, &layer_paint);
711 auto display_list = builder.
Build();
713 EXPECT_EQ(display_list->op_count(), 2u);
714 EXPECT_EQ(display_list->total_depth(), 1u);
716 EXPECT_TRUE(display_list->GetBounds().IsEmpty()) << display_list->GetBounds();
721 for (
size_t i = 0;
i < group.variants.size();
i++) {
722 auto& invocation = group.variants[
i];
723 sk_sp<DisplayList> dl = Build(invocation);
724 auto desc = group.op_name +
"(variant " + std::to_string(
i + 1) +
")";
725 EXPECT_EQ(dl->op_count(
false), invocation.op_count()) << desc;
726 EXPECT_EQ(dl->bytes(
false), invocation.byte_count()) << desc;
727 EXPECT_EQ(dl->total_depth(), invocation.depth_accumulated()) << desc;
735 for (
size_t i = 0;
i < group.variants.size();
i++) {
736 sk_sp<DisplayList> dl = Build(group.variants[
i]);
738 group.op_name +
"(variant " + std::to_string(
i + 1) +
" != empty)";
739 if (group.variants[
i].is_empty()) {
741 ASSERT_TRUE(empty->Equals(*dl)) << desc;
744 ASSERT_FALSE(empty->Equals(*dl)) << desc;
752 for (
size_t i = 0;
i < group.variants.size();
i++) {
753 sk_sp<DisplayList> dl = Build(group.variants[
i]);
759 sk_sp<DisplayList> copy = copy_builder.
Build();
761 group.op_name +
"(variant " + std::to_string(
i + 1) +
" == copy)";
763 ASSERT_EQ(copy->op_count(
false), dl->op_count(
false)) << desc;
764 ASSERT_EQ(copy->GetRecordCount(), dl->GetRecordCount());
765 ASSERT_EQ(copy->bytes(
false), dl->bytes(
false)) << desc;
766 ASSERT_EQ(copy->op_count(
true), dl->op_count(
true)) << desc;
767 ASSERT_EQ(copy->bytes(
true), dl->bytes(
true)) << desc;
768 ASSERT_EQ(copy->total_depth(), dl->total_depth()) << desc;
769 ASSERT_EQ(copy->GetBounds(), dl->GetBounds()) << desc;
770 ASSERT_TRUE(copy->Equals(*dl)) << desc;
771 ASSERT_TRUE(dl->Equals(*copy)) << desc;
778 for (
size_t i = 0;
i < group.variants.size();
i++) {
779 sk_sp<DisplayList> dl = Build(group.variants[
i]);
784 for (
DlIndex i = 0;
i < dl->GetRecordCount();
i++) {
786 EXPECT_NE(dl->GetOpCategory(
i),
788 EXPECT_TRUE(dl->Dispatch(r,
i));
790 sk_sp<DisplayList> copy = copy_builder.
Build();
792 group.op_name +
"(variant " + std::to_string(
i + 1) +
" == copy)";
794 ASSERT_EQ(copy->op_count(
false), dl->op_count(
false)) << desc;
795 ASSERT_EQ(copy->GetRecordCount(), dl->GetRecordCount());
796 ASSERT_EQ(copy->bytes(
false), dl->bytes(
false)) << desc;
797 ASSERT_EQ(copy->op_count(
true), dl->op_count(
true)) << desc;
798 ASSERT_EQ(copy->bytes(
true), dl->bytes(
true)) << desc;
799 ASSERT_EQ(copy->total_depth(), dl->total_depth()) << desc;
800 ASSERT_EQ(copy->GetBounds(), dl->GetBounds()) << desc;
801 ASSERT_TRUE(copy->Equals(*dl)) << desc;
802 ASSERT_TRUE(dl->Equals(*copy)) << desc;
809 std::vector<sk_sp<DisplayList>> lists_a;
810 std::vector<sk_sp<DisplayList>> lists_b;
811 for (
size_t i = 0;
i < group.variants.size();
i++) {
812 lists_a.push_back(Build(group.variants[
i]));
813 lists_b.push_back(Build(group.variants[
i]));
816 for (
size_t i = 0;
i < lists_a.size();
i++) {
817 const sk_sp<DisplayList>& listA = lists_a[
i];
818 for (
size_t j = 0; j < lists_b.size(); j++) {
819 const sk_sp<DisplayList>& listB = lists_b[j];
820 auto desc = group.op_name +
"(variant " + std::to_string(
i + 1) +
821 " ==? variant " + std::to_string(j + 1) +
")";
823 (group.variants[
i].is_empty() && group.variants[j].is_empty())) {
825 ASSERT_EQ(listA->op_count(
false), listB->op_count(
false)) << desc;
826 ASSERT_EQ(listA->bytes(
false), listB->bytes(
false)) << desc;
827 ASSERT_EQ(listA->op_count(
true), listB->op_count(
true)) << desc;
828 ASSERT_EQ(listA->bytes(
true), listB->bytes(
true)) << desc;
829 EXPECT_EQ(listA->total_depth(), listB->total_depth()) << desc;
830 ASSERT_EQ(listA->GetBounds(), listB->GetBounds()) << desc;
831 ASSERT_TRUE(listA->Equals(*listB)) << desc;
832 ASSERT_TRUE(listB->Equals(*listA)) << desc;
836 ASSERT_FALSE(listA->Equals(*listB)) << desc;
837 ASSERT_FALSE(listB->Equals(*listA)) << desc;
846 for (
size_t i = 0;
i < group.variants.size();
i++) {
849 group.variants[
i].Invoke(ToReceiver(builder1));
850 group.variants[
i].Invoke(ToReceiver(builder2));
851 sk_sp<DisplayList> dl1 = builder1.
Build();
852 sk_sp<DisplayList> dl2 = builder2.
Build();
854 auto desc = group.op_name +
"(variant " + std::to_string(
i + 1) +
" )";
855 ASSERT_EQ(dl1->op_count(
false), dl2->op_count(
false)) << desc;
856 ASSERT_EQ(dl1->bytes(
false), dl2->bytes(
false)) << desc;
857 ASSERT_EQ(dl1->op_count(
true), dl2->op_count(
true)) << desc;
858 ASSERT_EQ(dl1->bytes(
true), dl2->bytes(
true)) << desc;
859 EXPECT_EQ(dl1->total_depth(), dl2->total_depth()) << desc;
860 ASSERT_EQ(dl1->GetBounds(), dl2->GetBounds()) << desc;
861 ASSERT_EQ(dl1->total_depth(), dl2->total_depth()) << desc;
864 ASSERT_EQ(dl1->rtree().get(),
nullptr) << desc;
865 ASSERT_NE(dl2->rtree().get(),
nullptr) << desc;
877 sk_sp<DisplayList> dl = builder.
Build();
880 ASSERT_EQ(dl->op_count(
false), 0u);
881 ASSERT_EQ(dl->op_count(
true), 0u);
882 EXPECT_EQ(dl->total_depth(), 0u);
889 sk_sp<DisplayList> dl = builder.
Build();
892 ASSERT_EQ(dl->op_count(
false), 0u);
893 ASSERT_EQ(dl->op_count(
true), 0u);
894 EXPECT_EQ(dl->total_depth(), 0u);
898 sk_sp<DisplayList> default_dl = Build(
allGroups.size(), 0);
899 ASSERT_TRUE(default_dl->Equals(*default_dl)) <<
"Default == itself";
900 for (
size_t gi = 0; gi <
allGroups.size(); gi++) {
902 sk_sp<DisplayList> missing_dl = Build(gi, group.
variants.size());
903 auto desc =
"[Group " + group.
op_name +
" omitted]";
904 ASSERT_TRUE(missing_dl->Equals(*missing_dl)) << desc <<
" == itself";
905 ASSERT_FALSE(missing_dl->Equals(*default_dl)) << desc <<
" != Default";
906 ASSERT_FALSE(default_dl->Equals(*missing_dl)) <<
"Default != " << desc;
907 for (
size_t vi = 0; vi < group.
variants.size(); vi++) {
908 auto desc =
"[Group " + group.
op_name +
" variant " +
909 std::to_string(vi + 1) +
"]";
910 sk_sp<DisplayList> variant_dl = Build(gi, vi);
911 ASSERT_TRUE(variant_dl->Equals(*variant_dl)) << desc <<
" == itself";
913 ASSERT_TRUE(variant_dl->Equals(*default_dl)) << desc <<
" == Default";
914 ASSERT_TRUE(default_dl->Equals(*variant_dl)) <<
"Default == " << desc;
916 ASSERT_FALSE(variant_dl->Equals(*default_dl)) << desc <<
" != Default";
917 ASSERT_FALSE(default_dl->Equals(*variant_dl)) <<
"Default != " << desc;
919 if (group.
variants[vi].is_empty()) {
920 ASSERT_TRUE(variant_dl->Equals(*missing_dl)) << desc <<
" != omitted";
921 ASSERT_TRUE(missing_dl->Equals(*variant_dl)) <<
"omitted != " << desc;
923 ASSERT_FALSE(variant_dl->Equals(*missing_dl)) << desc <<
" != omitted";
924 ASSERT_FALSE(missing_dl->Equals(*variant_dl)) <<
"omitted != " << desc;
935 const float color_matrix[] = {
944 const float alpha_matrix[] = {
959 sk_sp<DisplayList> display_list = builder.
Build();
960 ASSERT_EQ(display_list->GetBounds(), rect);
968 builder.
SaveLayer(save_bounds, &save_paint);
971 sk_sp<DisplayList> display_list = builder.
Build();
972 ASSERT_EQ(display_list->GetBounds(), rect);
982 builder.
SaveLayer(save_bounds, &save_paint);
985 sk_sp<DisplayList> display_list = builder.
Build();
986 ASSERT_EQ(display_list->GetBounds(), build_bounds);
995 builder.
SaveLayer(std::nullopt, &save_paint);
998 sk_sp<DisplayList> display_list = builder.
Build();
999 ASSERT_EQ(display_list->GetBounds(), build_bounds);
1009 builder.
SaveLayer(save_bounds, &save_paint);
1012 sk_sp<DisplayList> display_list = builder.
Build();
1013 ASSERT_EQ(display_list->GetBounds(), rect);
1023 builder.
SaveLayer(save_bounds, &save_paint);
1026 sk_sp<DisplayList> display_list = builder.
Build();
1027 ASSERT_EQ(display_list->GetBounds(), build_bounds);
1036 builder.
SaveLayer(std::nullopt, &save_paint);
1039 sk_sp<DisplayList> display_list = builder.
Build();
1040 ASSERT_EQ(display_list->GetBounds(), build_bounds);
1048 builder.
SaveLayer(save_bounds, &save_paint);
1051 sk_sp<DisplayList> display_list = builder.
Build();
1052 ASSERT_EQ(display_list->GetBounds(), build_bounds);
1060 builder.
SaveLayer(std::nullopt, &save_paint);
1063 sk_sp<DisplayList> display_list = builder.
Build();
1064 ASSERT_EQ(display_list->GetBounds(), build_bounds);
1071 for (
int y = 10;
y <= 60;
y += 10) {
1072 for (
int x = 10;
x <= 60;
x += 10) {
1081 auto display_list = outer_builder.
Build();
1083 ASSERT_EQ(display_list->op_count(), 1u);
1084 ASSERT_EQ(display_list->op_count(
true), 36u);
1085 EXPECT_EQ(display_list->total_depth(), 37u);
1110 ASSERT_EQ(dl_matrix, matrix);
1124 ASSERT_NE(dl_matrix, matrix);
1130 builder.
Scale(20.0, 20.0);
1136 auto run_tests = [](
const std::string&
name,
1138 bool expect_for_op,
bool expect_with_kSrc) {
1144 build(builder, paint);
1145 auto display_list = builder.
Build();
1146 EXPECT_EQ(display_list->can_apply_group_opacity(), expect_for_op)
1148 <<
" " <<
name << std::endl
1157 build(builder, paint);
1158 auto display_list = builder.
Build();
1159 EXPECT_EQ(display_list->can_apply_group_opacity(), expect_with_kSrc)
1161 <<
" receiver.setBlendMode(kSrc);" << std::endl
1162 <<
" " <<
name << std::endl
1167#define RUN_TESTS(body) \
1169 #body, [](DlCanvas& canvas, const DlPaint& paint) { body }, true, false)
1171#define RUN_TESTS2(body, expect) \
1173 #body, [](DlCanvas& canvas, const DlPaint& paint) { body }, expect, \
1240 static auto display_list = builder.
Build();
1245#if IMPELLER_SUPPORTS_RENDERING
1259 for (
int i = 0;
i < 10;
i++) {
1262 auto display_list = builder.
Build();
1263 EXPECT_FALSE(display_list->can_apply_group_opacity());
1268 for (
int i = 0;
i < 10;
i++) {
1271 auto display_list = builder.
Build();
1272 EXPECT_TRUE(display_list->can_apply_group_opacity());
1282 auto display_list = builder.
Build();
1283 EXPECT_TRUE(display_list->can_apply_group_opacity());
1288 builder.
SaveLayer(std::nullopt,
nullptr);
1289 for (
int i = 0;
i < 10;
i++) {
1293 auto display_list = builder.
Build();
1294 EXPECT_TRUE(display_list->can_apply_group_opacity());
1300 builder.
SaveLayer(std::nullopt, &save_paint);
1301 for (
int i = 0;
i < 10;
i++) {
1305 auto display_list = builder.
Build();
1306 EXPECT_TRUE(display_list->can_apply_group_opacity());
1317 builder.
SaveLayer(std::nullopt,
nullptr);
1320 auto display_list = builder.
Build();
1321 EXPECT_TRUE(display_list->can_apply_group_opacity());
1328 builder.
SaveLayer(std::nullopt, &save_paint);
1331 auto display_list = builder.
Build();
1332 EXPECT_FALSE(display_list->can_apply_group_opacity());
1337 builder.
SaveLayer(std::nullopt,
nullptr);
1339 DlPaint().setBlendMode(DlBlendMode::kSrc));
1341 auto display_list = builder.
Build();
1342 EXPECT_TRUE(display_list->can_apply_group_opacity());
1348 builder.
SaveLayer(std::nullopt, &save_paint);
1350 DlPaint().setBlendMode(DlBlendMode::kSrc));
1352 auto display_list = builder.
Build();
1353 EXPECT_TRUE(display_list->can_apply_group_opacity());
1359 builder.
SaveLayer(std::nullopt, &save_paint);
1370#define SAVE_LAYER_EXPECTOR(name) SaveLayerExpector name(__FILE__, __LINE__)
1386 std::optional<SaveLayerOptionsTester>
tester;
1390::std::ostream&
operator<<(::std::ostream& os,
1391 const SaveLayerExpectations& expect) {
1392 os <<
"SaveLayerExpectation(";
1393 if (expect.options.has_value()) {
1394 os <<
"options: " << expect.options.value();
1396 if (expect.tester.has_value()) {
1397 os <<
"option tester: " << &expect.tester.value();
1399 if (expect.max_blend_mode.has_value()) {
1400 os <<
"max_blend: " << expect.max_blend_mode.value();
1413 : file_(file), line_(line), detail_(
"") {}
1416 EXPECT_EQ(save_layer_count_, expected_.size()) << label();
1417 while (save_layer_count_ < expected_.size()) {
1418 auto expect = expected_[save_layer_count_];
1419 FML_LOG(ERROR) <<
"leftover expectation[" << save_layer_count_
1420 <<
"] = " << expect;
1421 save_layer_count_++;
1431 expected_.push_back(expected);
1448 std::optional<int64_t> backdrop_id)
override {
1454 uint32_t total_content_depth,
1457 std::optional<int64_t> backdrop_id = std::nullopt) {
1458 ASSERT_LT(save_layer_count_, expected_.size()) << label();
1459 auto expect = expected_[save_layer_count_];
1460 if (expect.options.has_value()) {
1461 EXPECT_EQ(options, expect.options.value()) << label();
1463 if (expect.tester.has_value()) {
1464 EXPECT_TRUE(expect.tester.value()(options)) << label();
1466 if (expect.max_blend_mode.has_value()) {
1467 EXPECT_EQ(max_content_blend_mode, expect.max_blend_mode.value())
1470 save_layer_count_++;
1474 return save_layer_count_ == expected_.size();
1479 mutable std::vector<SaveLayerExpectations> expected_;
1480 size_t save_layer_count_ = 0;
1482 const std::string file_;
1484 std::string detail_;
1486 std::string label() {
1487 std::string label =
"at index " + std::to_string(save_layer_count_) +
1489 ":" + std::to_string(line_);
1490 if (detail_.length() > 0) {
1491 label = label +
" (" + detail_ +
")";
1499 expector.addExpectation(
1505 builder.
SaveLayer(std::nullopt, &save_paint);
1509 builder.
Build()->Dispatch(expector);
1510 EXPECT_TRUE(expector.all_expectations_checked());
1515 expector.addExpectation(
1519 builder.
SaveLayer(std::nullopt,
nullptr);
1523 builder.
Build()->Dispatch(expector);
1524 EXPECT_TRUE(expector.all_expectations_checked());
1534 builder.
SaveLayer(std::nullopt, &save_paint);
1539 builder.
Build()->Dispatch(expector);
1540 EXPECT_TRUE(expector.all_expectations_checked());
1555 builder.
SaveLayer(std::nullopt, &save_paint);
1556 builder.
SaveLayer(std::nullopt, &save_paint);
1558 builder.
SaveLayer(std::nullopt, &save_paint);
1564 builder.
Build()->Dispatch(expector);
1565 EXPECT_TRUE(expector.all_expectations_checked());
1579 builder.
SaveLayer(std::nullopt, &save_paint);
1580 builder.
SaveLayer(std::nullopt,
nullptr);
1585 builder.
Build()->Dispatch(expector);
1586 EXPECT_TRUE(expector.all_expectations_checked());
1597 builder.
SaveLayer(std::nullopt, &save_paint);
1601 builder.
Build()->Dispatch(expector);
1602 EXPECT_TRUE(expector.all_expectations_checked());
1613 builder.
SaveLayer(std::nullopt, &save_paint);
1617 builder.
Build()->Dispatch(expector);
1618 EXPECT_TRUE(expector.all_expectations_checked());
1629 builder.
SaveLayer(std::nullopt, &save_paint);
1633 builder.
Build()->Dispatch(expector);
1634 EXPECT_TRUE(expector.all_expectations_checked());
1639 expector.addExpectation(
1645 builder.
SaveLayer(std::nullopt, &save_paint);
1646 DlPaint draw_paint = save_paint;
1651 builder.
Build()->Dispatch(expector);
1652 EXPECT_TRUE(expector.all_expectations_checked());
1662 builder.
SaveLayer(std::nullopt, &save_paint);
1663 DlPaint draw_paint = save_paint;
1668 builder.
Build()->Dispatch(expector);
1669 EXPECT_TRUE(expector.all_expectations_checked());
1679 builder.
SaveLayer(std::nullopt, &save_paint);
1680 DlPaint draw_paint = save_paint;
1685 builder.
Build()->Dispatch(expector);
1686 EXPECT_TRUE(expector.all_expectations_checked());
1693 path_builder1.
MoveTo({25.54f, 37.52f});
1697 path_builder1.
LineTo({13, 30});
1698 path_builder1.
LineTo({12.45f, 29.42f});
1709 {16.7603f, 18.3081f},
1712 {15.4653f, 19.5169f},
1718 {16.3239f, 23.9309f},
1721 {20.6607f, 27.8428f},
1730 {25.5538f, 25.9723f},
1739 {27.906f, 37.4704f},
1741 path_builder1.
Close();
1742 path_builder1.
MoveTo({11.17f, 12.23f});
1744 {10.2522f, 12.4819f},
1749 path_builder1.
LineTo({14.62f, 28.45f});
1750 path_builder1.
LineTo({15.16f, 28.96f});
1758 {27.7359f, 28.4018f},
1761 {25.8676f, 28.2367f},
1764 {25.269f, 28.9252f},
1769 path_builder1.
LineTo({21.41f, 30.72f});
1771 {17.6787f, 28.4133f},
1774 {13.2693f, 23.5295f},
1776 path_builder1.
LineTo({12.2f, 21.44f});
1784 {14.8404f, 16.8359f},
1787 {13.9585f, 14.0843f},
1790 {11.8824f, 12.2971f},
1792 path_builder1.
LineTo({11.17f, 12.23f});
1793 path_builder1.
Close();
1794 path_builder1.
MoveTo({27, 19.34f});
1795 path_builder1.
LineTo({24.74f, 19.34f});
1797 {24.262f, 18.2881f},
1799 path_builder1.
LineTo({23.68f, 16.05f});
1800 path_builder1.
LineTo({23.7f, 16.05f});
1802 {26.9863f, 17.5248f},
1804 path_builder1.
LineTo({27, 19.34f});
1805 path_builder1.
Close();
1806 path_builder1.
MoveTo({32.3f, 19.34f});
1807 path_builder1.
LineTo({30.07f, 19.34f});
1811 path_builder1.
LineTo({23.69f, 10.72f});
1815 path_builder1.
Close();
1816 path_builder1.
SetFillType(DlPathFillType::kNonZero);
1820 path_builder2.
MoveTo({37.5f, 19.33f});
1821 path_builder2.
LineTo({35.27f, 19.33f});
1825 path_builder2.
LineTo({23.69f, 5.52f});
1829 path_builder2.
Close();
1830 path_builder2.
SetFillType(DlPathFillType::kNonZero);
1848 builder.
SaveLayer(std::nullopt,
nullptr,
nullptr);
1852 0, 1.53125, 236.548);
1859 0, 1.53125, 236.548);
1871 sk_sp<DisplayList> display_list = builder.
Build();
1873 EXPECT_FALSE(display_list->GetBounds().IsEmpty());
1881 ASSERT_TRUE(max_bounds.
Contains(min_bounds));
1882 EXPECT_TRUE(max_bounds.
Contains(display_list->GetBounds()));
1883 EXPECT_TRUE(display_list->GetBounds().Contains(min_bounds));
1888 EXPECT_EQ(display_list->op_count(), 19u);
1889 EXPECT_EQ(display_list->bytes(),
sizeof(
DisplayList) + 408u);
1890 EXPECT_EQ(display_list->total_depth(), 3u);
1898 ASSERT_EQ(cur_matrix, matrix);
1901 ASSERT_NE(builder.
GetMatrix(), cur_matrix);
1903 ASSERT_EQ(cur_matrix, matrix);
1908 builder.
Scale(12.3, 14.5);
1911 ASSERT_EQ(cur_matrix, matrix);
1914 ASSERT_NE(builder.
GetMatrix(), cur_matrix);
1916 ASSERT_EQ(cur_matrix, matrix);
1924 ASSERT_EQ(cur_matrix, matrix);
1927 ASSERT_NE(builder.
GetMatrix(), cur_matrix);
1929 ASSERT_EQ(cur_matrix, matrix);
1934 builder.
Skew(12.3f, 14.5f);
1937 ASSERT_EQ(cur_matrix, matrix);
1940 ASSERT_NE(builder.
GetMatrix(), cur_matrix);
1942 ASSERT_EQ(cur_matrix, matrix);
1950 1.0f, 5.0f, 0.0f, 14.5,
1951 0.0f, 0.0f, 1.0f, 0.0f,
1952 0.0f, 0.0f, 0.0f, 1.0f
1955 ASSERT_EQ(cur_matrix, matrix);
1958 ASSERT_NE(builder.
GetMatrix(), cur_matrix);
1960 ASSERT_EQ(cur_matrix, matrix);
1966 1.0f, 5.0f, 3.0f, 14.5f,
1967 0.0f, 0.0f, 7.0f, 16.2f,
1968 0.0f, 0.0f, 0.0f, 1.0f);
1970 1.0f, 5.0f, 3.0f, 14.5f,
1971 0.0f, 0.0f, 7.0f, 16.2f,
1972 0.0f, 0.0f, 0.0f, 1.0f);
1974 ASSERT_EQ(cur_matrix, matrix);
1977 ASSERT_NE(builder.
GetMatrix(), cur_matrix);
1979 ASSERT_EQ(cur_matrix, matrix);
1990 ASSERT_EQ(initial_local_bounds, clip_bounds);
1991 ASSERT_EQ(initial_destination_bounds, clip_bounds);
1999 ASSERT_EQ(initial_local_bounds, clip_bounds);
2000 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2008 builder.
Scale(2.0f, 2.0f);
2029 ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
2030 ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
2038 ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
2039 ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
2047 builder.
Scale(2, 2);
2087 ASSERT_EQ(initial_local_bounds, clip_bounds);
2088 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2096 ASSERT_EQ(initial_local_bounds, clip_bounds);
2097 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2105 builder.
Scale(2, 2);
2127 ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
2128 ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
2136 ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
2137 ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
2145 builder.
Scale(2, 2);
2189 ASSERT_EQ(initial_local_bounds, clip_bounds);
2190 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2198 ASSERT_EQ(initial_local_bounds, clip_bounds);
2199 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2207 builder.
Scale(2, 2);
2229 ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
2230 ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
2238 ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
2239 ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
2247 builder.
Scale(2, 2);
2291 ASSERT_EQ(initial_local_bounds, clip_bounds);
2292 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2311 ASSERT_EQ(initial_local_bounds, clip_bounds);
2312 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2330 ASSERT_EQ(initial_local_bounds, clip_bounds);
2331 ASSERT_EQ(initial_destination_bounds, clip_bounds);
2394#define TEST_RTREE(rtree, query, expected_rects, expected_indices) \
2395 test_rtree(rtree, query, expected_rects, expected_indices, __FILE__, __LINE__)
2399 std::vector<DlRect> expected_rects,
2400 const std::vector<int>& expected_indices,
2401 const std::string& file,
2403 std::vector<int> indices;
2404 auto label =
"from " + file +
":" + std::to_string(line);
2405 rtree->search(query, &indices);
2406 EXPECT_EQ(indices, expected_indices) << label;
2407 EXPECT_EQ(indices.size(), expected_indices.size()) << label;
2408 std::list<DlRect> rects = rtree->searchAndConsolidateRects(query,
false);
2410 auto iterator = rects.cbegin();
2411 for (
int i : expected_indices) {
2412 ASSERT_TRUE(iterator != rects.cend()) << label;
2413 EXPECT_EQ(*iterator++, expected_rects[
i]) << label;
2419 std::vector<DlRect> rects = {
2425 auto display_list = builder.
Build();
2426 auto rtree = display_list->rtree();
2442 std::vector<int>({0, 1}));
2451 auto display_list = builder.
Build();
2452 auto rtree = display_list->rtree();
2453 std::vector<DlRect> rects = {
2472 std::vector<int>({0, 1}));
2482 builder.
SaveLayer(std::nullopt, &filter_paint);
2487 auto display_list = builder.
Build();
2488 auto rtree = display_list->rtree();
2489 std::vector<DlRect> rects = {
2507 auto expected_indices = std::vector<int>{0, 1};
2515 auto nested_display_list = nested_dl_builder.
Build();
2519 auto display_list = builder.
Build();
2521 auto rtree = display_list->rtree();
2522 std::vector<DlRect> rects = {
2529 std::vector<int>({0, 1}));
2583 builder1.
Scale(2, 2);
2593 auto display_list1 = builder1.
Build();
2599 builder2.
Scale(2, 2);
2605 auto display_list2 = builder2.
Build();
2614 builder1.
SaveLayer(std::nullopt,
nullptr);
2617 builder1.
Scale(2, 2);
2622 auto display_list1 = builder1.
Build();
2625 builder2.
SaveLayer(std::nullopt,
nullptr);
2628 builder2.
Scale(2, 2);
2631 auto display_list2 = builder2.
Build();
2640 const float alpha_matrix[] = {
2659 sk_sp<DisplayList> display_list1 = builder.
Build();
2665 sk_sp<DisplayList> display_list2 = builder2.
Build();
2678 sk_sp<DisplayList> display_list1 = builder.
Build();
2686 sk_sp<DisplayList> display_list2 = builder2.
Build();
2711 auto display_list1 = builder1.
Build();
2732 auto display_list2 = builder2.
Build();
2749 auto display_list1 = builder1.
Build();
2758 auto display_list2 = builder2.
Build();
2778 auto display_list1 = builder1.
Build();
2790 auto display_list2 = builder2.
Build();
2807 auto display_list1 = builder1.
Build();
2816 auto display_list2 = builder2.
Build();
2827 builder1.
Skew(10, 10);
2833 auto display_list1 = builder1.
Build();
2838 builder2.
Skew(10, 10);
2842 auto display_list2 = builder2.
Build();
2859 auto display_list1 = builder1.
Build();
2868 auto display_list2 = builder2.
Build();
2879 builder1.
Scale(0.5, 0.5);
2885 auto display_list1 = builder1.
Build();
2890 builder2.
Scale(0.5, 0.5);
2894 auto display_list2 = builder2.
Build();
2917 auto display_list1 = builder1.
Build();
2932 auto display_list2 = builder2.
Build();
2955 auto display_list1 = builder1.
Build();
2968 auto display_list2 = builder2.
Build();
2990 auto display_list1 = builder1.
Build();
3004 auto display_list2 = builder2.
Build();
3022 auto display_list1 = builder1.
Build();
3027 auto display_list2 = builder2.
Build();
3038 builder1.
Scale(1.0, 1.0);
3045 auto display_list1 = builder1.
Build();
3050 auto display_list2 = builder2.
Build();
3068 auto display_list1 = builder1.
Build();
3073 auto display_list2 = builder2.
Build();
3084 builder1.
Skew(0, 0);
3091 auto display_list1 = builder1.
Build();
3096 auto display_list2 = builder2.
Build();
3121 auto display_list1 = builder1.
Build();
3126 auto display_list2 = builder2.
Build();
3144 auto display_list1 = builder1.
Build();
3149 auto display_list2 = builder2.
Build();
3171 auto display_list1 = builder1.
Build();
3176 auto display_list2 = builder2.
Build();
3198 auto display_list1 = builder1.
Build();
3208 auto display_list2 = builder2.
Build();
3215 DlScalar NaN = std::numeric_limits<DlScalar>::quiet_NaN();
3229 auto display_list1 = builder1.
Build();
3234 auto display_list2 = builder2.
Build();
3248 builder.
SaveLayer(std::nullopt, &filter_paint);
3254 auto display_list = builder.
Build();
3255 auto rtree = display_list->rtree();
3256 std::vector<DlRect> rects = {
3275 std::vector<int>({0, 1}));
3289 main_builder.
DrawRect(rect1, paint1);
3290 main_builder.
DrawRect(rect2, paint2);
3291 main_builder.
DrawRect(rect3, paint3);
3292 main_builder.
DrawRect(rect4, paint4);
3295 auto test = [
main](
DlIRect cull_rect,
const sk_sp<DisplayList>& expected,
3296 const std::string& label) {
3301 main->Dispatch(ToReceiver(culling_builder), cull_rect);
3304 <<
"using cull rect " << cull_rect
3305 <<
" where " << label;
3310 main->Dispatch(ToReceiver(culling_builder), cull_rectf);
3313 <<
"using cull rect " << cull_rectf
3314 <<
" where " << label;
3320 auto indices =
main->GetCulledIndices(cull_rectf);
3322 EXPECT_TRUE(
main->Dispatch(receiver,
i));
3326 <<
"using culled indices on cull rect " << cull_rectf
3327 <<
" where " << label;
3335 auto expected = expected_builder.
Build();
3337 test(cull_rect, expected,
"no rects intersect");
3344 expected_builder.
DrawRect(rect1, paint1);
3345 auto expected = expected_builder.
Build();
3347 test(cull_rect, expected,
"rect 1 intersects");
3356 ToReceiver(expected_builder).setColor(paint1.
getColor());
3357 expected_builder.
DrawRect(rect2, paint2);
3358 auto expected = expected_builder.
Build();
3360 test(cull_rect, expected,
"rect 2 intersects");
3369 ToReceiver(expected_builder).setColor(paint1.
getColor());
3370 ToReceiver(expected_builder).setColor(paint2.
getColor());
3371 expected_builder.
DrawRect(rect3, paint3);
3372 auto expected = expected_builder.
Build();
3374 test(cull_rect, expected,
"rect 3 intersects");
3383 ToReceiver(expected_builder).setColor(paint1.
getColor());
3384 ToReceiver(expected_builder).setColor(paint2.
getColor());
3385 ToReceiver(expected_builder).setColor(paint3.
getColor());
3386 expected_builder.
DrawRect(rect4, paint4);
3387 auto expected = expected_builder.
Build();
3389 test(cull_rect, expected,
"rect 4 intersects");
3395 test(cull_rect,
main,
"all rects intersect");
3406 auto display_list = builder.
Build();
3408 ASSERT_FALSE(display_list->can_apply_group_opacity());
3415 check_inverted_bounds(renderer,
"DrawRect");
3422 check_inverted_bounds(renderer,
"DrawRoundRect");
3429 check_inverted_bounds(renderer,
"DrawOval");
3436 check_inverted_bounds(renderer,
"DrawRectangularPath");
3443 check_inverted_bounds(renderer,
"DrawOvalPath");
3451 check_inverted_bounds(renderer,
"DrawRoundRectPath Clockwise");
3459 check_inverted_bounds(renderer,
"DrawRoundRectPath Counter-Clockwise");
3463 auto run_tests = [](
const std::string&
name,
3465 uint32_t expected_op_count = 0u,
3466 uint32_t expected_total_depth = 0u) {
3468 [init](
const std::string&
name,
3470 uint32_t expected_op_count = 0u,
3471 uint32_t expected_total_depth = 0u) {
3474 init(builder, paint);
3475 build(builder, paint);
3476 auto list = builder.
Build();
3477 if (list->op_count() != expected_op_count) {
3480 ASSERT_EQ(list->op_count(), expected_op_count) <<
name;
3481 EXPECT_EQ(list->total_depth(), expected_total_depth) <<
name;
3482 ASSERT_TRUE(list->GetBounds().IsEmpty()) <<
name;
3485 name +
" DrawColor",
3489 expected_op_count, expected_total_depth);
3491 name +
" DrawPaint",
3495 expected_op_count, expected_total_depth);
3501 expected_op_count, expected_total_depth);
3503 name +
" Other Draw Ops",
3542#if IMPELLER_SUPPORTS_RENDERING
3554 expected_op_count, expected_total_depth);
3556 name +
" SaveLayer",
3558 builder.
SaveLayer(std::nullopt, &paint,
nullptr);
3562 expected_op_count, expected_total_depth);
3564 name +
" inside Save",
3570 expected_op_count, expected_total_depth);
3572 run_tests(
"transparent color",
3576 run_tests(
"0 alpha",
3584 run_tests(
"BlendMode::kDst",
3588 run_tests(
"Empty rect clip",
3592 run_tests(
"Empty rrect clip",
3596 run_tests(
"Empty path clip",
3600 run_tests(
"Transparent SaveLayer",
3604 builder.
SaveLayer(std::nullopt, &save_paint);
3606 run_tests(
"0 alpha SaveLayer",
3614 builder.
SaveLayer(std::nullopt, &save_paint);
3616 run_tests(
"Dst blended SaveLayer",
3620 builder.
SaveLayer(std::nullopt, &save_paint);
3623 "Nop inside SaveLayer",
3625 builder.
SaveLayer(std::nullopt,
nullptr);
3629 run_tests(
"DrawImage inside Culled SaveLayer",
3633 builder.
SaveLayer(std::nullopt, &save_paint);
3648 expected_.emplace_back(BoundsExpectation{
3656 bool clipped =
false) {
3662 expected_.emplace_back(BoundsExpectation{
3672 std::optional<int64_t> backdrop_id)
override {
3673 ASSERT_LT(save_layer_count_, expected_.size());
3674 auto expected = expected_[save_layer_count_];
3676 expected.options.bounds_from_caller())
3677 <<
"expected bounds index " << save_layer_count_;
3679 expected.options.content_is_clipped())
3680 <<
"expected bounds index " << save_layer_count_;
3685 EXPECT_EQ(bounds, expected.bounds)
3686 <<
"expected bounds index " << save_layer_count_;
3688 save_layer_count_++;
3692 return save_layer_count_ == expected_.size();
3696 struct BoundsExpectation {
3701 std::vector<BoundsExpectation> expected_;
3702 size_t save_layer_count_ = 0;
3709 builder.
SaveLayer(std::nullopt,
nullptr);
3714 auto display_list = builder.
Build();
3718 display_list->Dispatch(expector);
3729 builder.
SaveLayer(std::nullopt,
nullptr);
3731 builder.
DrawRect(rect, draw_paint);
3734 auto display_list = builder.
Build();
3738 display_list->Dispatch(expector);
3749 builder.
SaveLayer(std::nullopt,
nullptr);
3751 builder.
DrawRect(rect, draw_paint);
3754 auto display_list = builder.
Build();
3758 display_list->Dispatch(expector);
3769 builder.
SaveLayer(std::nullopt,
nullptr);
3771 builder.
DrawRect(rect, draw_paint);
3774 auto display_list = builder.
Build();
3778 display_list->Dispatch(expector);
3787 builder.
SaveLayer(std::nullopt,
nullptr);
3792 auto display_list = builder.
Build();
3796 display_list->Dispatch(expector);
3804 builder.
Scale(10.0f, 10.0f);
3805 builder.
SaveLayer(std::nullopt,
nullptr);
3810 auto display_list = builder.
Build();
3814 display_list->Dispatch(expector);
3823 builder.
SaveLayer(std::nullopt,
nullptr);
3828 auto display_list = builder.
Build();
3832 display_list->Dispatch(expector);
3841 builder.
Scale(10.0f, 10.0f);
3842 builder.
SaveLayer(std::nullopt,
nullptr);
3844 builder.
Scale(20.0f, 20.0f);
3850 auto display_list = builder.
Build();
3854 display_list->Dispatch(expector);
3862 builder.
SaveLayer(std::nullopt,
nullptr);
3868 auto display_list = builder.
Build();
3872 display_list->Dispatch(expector);
3880 builder.
SaveLayer(std::nullopt,
nullptr);
3882 builder.
Scale(10.0f, 10.0f);
3886 auto display_list = builder.
Build();
3891 display_list->Dispatch(expector);
3899 builder.
SaveLayer(std::nullopt,
nullptr);
3905 auto display_list = builder.
Build();
3910 display_list->Dispatch(expector);
3918 builder.
SaveLayer(std::nullopt,
nullptr);
3920 builder.
SaveLayer(std::nullopt,
nullptr);
3927 auto display_list = builder.
Build();
3932 display_list->Dispatch(expector);
3941 ASSERT_TRUE(color_filter->modifies_transparent_black());
3944 ASSERT_NE(clip_rect, rect);
3945 ASSERT_TRUE(clip_rect.
Contains(rect));
3949 builder.
SaveLayer(std::nullopt, &save_paint);
3954 auto display_list = builder.
Build();
3958 display_list->Dispatch(expector);
3967 ASSERT_TRUE(color_filter->modifies_transparent_black());
3970 ASSERT_NE(clip_rect, rect);
3971 ASSERT_TRUE(clip_rect.
Contains(rect));
3975 builder.
SaveLayer(std::nullopt,
nullptr);
3977 builder.
SaveLayer(std::nullopt, &save_paint);
3984 auto display_list = builder.
Build();
3986 EXPECT_EQ(display_list->GetBounds(), clip_rect);
3991 display_list->Dispatch(expector);
4000 ASSERT_TRUE(color_filter->modifies_transparent_black());
4004 ASSERT_NE(clip_rect, rect);
4005 ASSERT_TRUE(clip_rect.
Contains(rect));
4009 builder.
SaveLayer(std::nullopt,
nullptr);
4011 builder.
DrawRect(rect, draw_paint);
4014 auto display_list = builder.
Build();
4018 display_list->Dispatch(expector);
4027 ASSERT_TRUE(color_filter->modifies_transparent_black());
4030 ASSERT_NE(clip_rect, rect);
4031 ASSERT_TRUE(clip_rect.
Contains(rect));
4035 builder.
SaveLayer(std::nullopt,
nullptr);
4037 builder.
DrawRect(rect, draw_paint);
4040 auto display_list = builder.
Build();
4046 display_list->Dispatch(expector);
4060 auto display_list = builder.
Build();
4064 display_list->Dispatch(expector);
4079 auto display_list = builder.
Build();
4083 display_list->Dispatch(expector);
4098 ASSERT_FALSE(layer_bounds.
IsEmpty());
4099 ASSERT_FALSE(draw_rect.
IsEmpty());
4102 builder.
SaveLayer(layer_bounds,
nullptr);
4105 auto display_list = builder.
Build();
4109 display_list->Dispatch(expector);
4120 : depth_expectations_(
std::move(expectations)) {}
4125 FAIL() <<
"save(no depth parameter) method should not be called";
4128 void save(uint32_t total_content_depth)
override {
4129 ASSERT_LT(index_, depth_expectations_.size());
4130 EXPECT_EQ(depth_expectations_[index_], total_content_depth)
4131 <<
"at index " << index_;
4138 std::optional<int64_t> backdrop_id)
override {
4141 FAIL() <<
"saveLayer(no depth parameter) method should not be called";
4146 uint32_t total_content_depth,
4149 std::optional<int64_t> backdrop_id)
override {
4150 ASSERT_LT(index_, depth_expectations_.size());
4151 EXPECT_EQ(depth_expectations_[index_], total_content_depth)
4152 <<
"at index " << index_;
4157 return index_ == depth_expectations_.size();
4162 std::vector<uint32_t> depth_expectations_;
4169 auto child = child_builder.
Build();
4181 builder.
SaveLayer(std::nullopt,
nullptr);
4195 auto display_list = builder.
Build();
4197 EXPECT_EQ(display_list->total_depth(), 11u);
4200 display_list->Dispatch(expector);
4210 const float matrix[] = {
4211 0.5f, 0.0f, 0.0f, 0.0f, 0.5f,
4212 0.5f, 0.0f, 0.0f, 0.0f, 0.5f,
4213 0.5f, 0.0f, 0.0f, 0.0f, 0.5f,
4214 0.5f, 0.0f, 0.0f, 0.0f, 0.5f
4219 builder.
SaveLayer(std::nullopt, &save_paint);
4228 auto dl = builder.
Build();
4229 std::vector<int> indices;
4230 dl->rtree()->search(
DlRect::MakeLTRB(0.0f, 0.0f, 500.0f, 500.0f), &indices);
4231 ASSERT_EQ(indices.size(), 3u);
4232 EXPECT_EQ(dl->rtree()->id(indices[0]), save_layer_id);
4233 EXPECT_EQ(dl->rtree()->id(indices[1]), draw_rect_id);
4234 EXPECT_EQ(dl->rtree()->id(indices[2]), restore_id);
4246 builder.
SaveLayer(std::nullopt, &save_paint);
4252 auto dl = builder.
Build();
4253 EXPECT_EQ(dl->GetBounds(),
DlRect::MakeLTRB(120.0f, 120.0f, 125.0f, 125.0f));
4265 builder.
SaveLayer(std::nullopt, &save_paint);
4271 auto dl = builder.
Build();
4272 EXPECT_EQ(dl->GetBounds(),
DlRect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f));
4280 DlPaint().setBlendMode(DlBlendMode::kClear));
4281 EXPECT_FALSE(builder.
Build()->can_apply_group_opacity());
4291 DlPaint().setBlendMode(DlBlendMode::kClear));
4296 EXPECT_FALSE(builder.
Build()->can_apply_group_opacity());
4302 EXPECT_EQ(builder.
Build()->max_root_blend_mode(), DlBlendMode::kClear);
4311 (
mode == DlBlendMode::kDst) ? DlBlendMode::kClear :
mode;
4312 EXPECT_EQ(builder.
Build()->max_root_blend_mode(), expect)
4313 <<
"testing " <<
mode;
4316 for (
int i = 0; i < static_cast<int>(DlBlendMode::kLastMode);
i++) {
4326 builder.
Scale(2.0f, 2.0f);
4328 DlPaint().setBlendMode(DlBlendMode::kModulate));
4332 EXPECT_EQ(builder.
Build()->max_root_blend_mode(), DlBlendMode::kModulate);
4341 DlPaint().setBlendMode(DlBlendMode::kModulate));
4345 EXPECT_EQ(builder.
Build()->max_root_blend_mode(), DlBlendMode::kModulate);
4350 builder.
SaveLayer(std::nullopt,
nullptr);
4353 DlPaint().setBlendMode(DlBlendMode::kModulate));
4356 auto dl = builder.
Build();
4357 EXPECT_EQ(dl->max_root_blend_mode(), DlBlendMode::kSrcOver);
4359 expector.addExpectation(DlBlendMode::kModulate);
4360 dl->Dispatch(expector);
4361 EXPECT_TRUE(expector.all_expectations_checked());
4368 builder.
SaveLayer(std::nullopt, &save_paint);
4371 DlPaint().setBlendMode(DlBlendMode::kModulate));
4374 auto dl = builder.
Build();
4375 EXPECT_EQ(dl->max_root_blend_mode(), DlBlendMode::kScreen);
4377 expector.addExpectation(DlBlendMode::kModulate);
4378 dl->Dispatch(expector);
4379 EXPECT_TRUE(expector.all_expectations_checked());
4387 DlPaint().setBlendMode(DlBlendMode::kModulate));
4391 ASSERT_GT(DlBlendMode::kScreen, DlBlendMode::kModulate);
4393 DlPaint().setBlendMode(DlBlendMode::kScreen));
4398 ASSERT_LT(DlBlendMode::kSrc, DlBlendMode::kModulate);
4400 DlPaint().setBlendMode(DlBlendMode::kSrc));
4405 auto expect = std::max(DlBlendMode::kModulate, DlBlendMode::kScreen);
4406 expect = std::max(expect, DlBlendMode::kSrc);
4407 ASSERT_EQ(expect, DlBlendMode::kScreen);
4409 EXPECT_EQ(builder.
Build()->max_root_blend_mode(), DlBlendMode::kScreen);
4414 builder.
SaveLayer(std::nullopt,
nullptr);
4418 DlPaint().setBlendMode(DlBlendMode::kModulate));
4419 builder.
SaveLayer(std::nullopt,
nullptr);
4423 DlPaint().setBlendMode(DlBlendMode::kScreen));
4428 ASSERT_LT(DlBlendMode::kSrc, DlBlendMode::kModulate);
4430 DlPaint().setBlendMode(DlBlendMode::kSrc));
4436 auto expect = std::max(DlBlendMode::kModulate, DlBlendMode::kSrc);
4437 ASSERT_EQ(expect, DlBlendMode::kModulate);
4439 auto dl = builder.
Build();
4440 EXPECT_EQ(dl->max_root_blend_mode(), DlBlendMode::kSrcOver);
4443 .addExpectation(DlBlendMode::kModulate)
4444 .addExpectation(DlBlendMode::kScreen);
4445 dl->Dispatch(expector);
4446 EXPECT_TRUE(expector.all_expectations_checked());
4451 EXPECT_FALSE(builder.
Build()->root_has_backdrop_filter());
4457 EXPECT_FALSE(builder.
Build()->root_has_backdrop_filter());
4468 auto dl = builder.
Build();
4470 EXPECT_TRUE(dl->root_has_backdrop_filter());
4474 expector.addExpectation(
4476 dl->Dispatch(expector);
4477 EXPECT_TRUE(expector.all_expectations_checked());
4482 builder.
SaveLayer(std::nullopt,
nullptr);
4494 auto dl = builder.
Build();
4496 EXPECT_FALSE(dl->root_has_backdrop_filter());
4500 .with_contains_backdrop_filter()
4501 .with_content_is_unbounded())
4504 dl->Dispatch(expector);
4505 EXPECT_TRUE(expector.all_expectations_checked());
4511 DlPaint().setBlendMode(DlBlendMode::kMultiply));
4512 auto child_dl = child_builder.
Build();
4513 EXPECT_EQ(child_dl->max_root_blend_mode(), DlBlendMode::kMultiply);
4514 EXPECT_FALSE(child_dl->root_has_backdrop_filter());
4518 auto parent_dl = parent_builder.
Build();
4519 EXPECT_EQ(parent_dl->max_root_blend_mode(), DlBlendMode::kMultiply);
4520 EXPECT_FALSE(parent_dl->root_has_backdrop_filter());
4526 child_builder.
SaveLayer(std::nullopt,
nullptr, &backdrop);
4528 DlPaint().setBlendMode(DlBlendMode::kMultiply));
4530 auto child_dl = child_builder.
Build();
4531 EXPECT_EQ(child_dl->max_root_blend_mode(), DlBlendMode::kSrcOver);
4532 EXPECT_TRUE(child_dl->root_has_backdrop_filter());
4536 auto parent_dl = parent_builder.
Build();
4537 EXPECT_EQ(parent_dl->max_root_blend_mode(), DlBlendMode::kSrcOver);
4538 EXPECT_TRUE(parent_dl->root_has_backdrop_filter());
4541#define CLIP_EXPECTOR(name) ClipExpector name(__FILE__, __LINE__)
4544 std::variant<DlRect, DlRoundRect, DlRoundSuperellipse, DlPath>
shape;
4550 switch (
shape.index()) {
4552 return is_oval ?
"Oval" :
"Rect";
4554 return "DlRoundRect";
4556 return "DlRoundSuperellipse";
4565::std::ostream&
operator<<(::std::ostream& os,
const ClipExpectation& expect) {
4566 os <<
"Expectation(";
4567 switch (expect.shape.index()) {
4569 os << std::get<DlRect>(expect.shape);
4570 if (expect.is_oval) {
4575 os << std::get<DlRoundRect>(expect.shape);
4578 os << std::get<DlPath>(expect.shape).GetSkPath();
4583 os <<
", " << expect.clip_op;
4584 os <<
", " << expect.is_aa;
4596 : file_(file), line_(line) {}
4599 EXPECT_EQ(index_, clip_expectations_.size()) << label();
4600 while (index_ < clip_expectations_.size()) {
4601 auto expect = clip_expectations_[index_];
4602 FML_LOG(ERROR) <<
"leftover clip shape[" << index_ <<
"] = " << expect;
4609 bool is_aa =
false) {
4610 clip_expectations_.push_back({
4621 bool is_aa =
false) {
4622 clip_expectations_.push_back({
4633 bool is_aa =
false) {
4634 clip_expectations_.push_back({
4645 bool is_aa =
false) {
4646 clip_expectations_.push_back({
4656 check(rect, clip_op, is_aa);
4659 check(bounds, clip_op, is_aa,
true);
4663 bool is_aa)
override {
4664 check(rrect, clip_op, is_aa);
4668 bool is_aa)
override {
4669 check(rse, clip_op, is_aa);
4672 check(
path, clip_op, is_aa);
4677 std::vector<ClipExpectation> clip_expectations_;
4679 template <
typename T>
4680 void check(
const T& shape,
4683 bool is_oval =
false) {
4684 ASSERT_LT(index_, clip_expectations_.size())
4685 << label() << std::endl
4686 <<
"extra clip shape = " << shape << (is_oval ?
" (oval)" :
"");
4687 auto expected = clip_expectations_[index_];
4688 if (!std::holds_alternative<T>(expected.shape)) {
4689 EXPECT_TRUE(std::holds_alternative<T>(expected.shape))
4690 << label() <<
", expected type: " << expected.shape_name();
4692 EXPECT_EQ(std::get<T>(expected.shape), shape) << label();
4694 EXPECT_EQ(expected.is_oval, is_oval) << label();
4695 EXPECT_EQ(expected.clip_op, clip_op) << label();
4696 EXPECT_EQ(expected.is_aa, is_aa) << label();
4700 const std::string file_;
4703 std::string label() {
4704 return "at index " + std::to_string(index_) +
4706 ":" + std::to_string(line_);
4725 cull_builder.
Scale(DPR, DPR);
4727 auto cull_dl = cull_builder.
Build();
4731 cull_dl->Dispatch(expector);
4740 auto cull_dl = cull_builder.
Build();
4744 cull_dl->Dispatch(expector);
4749 auto smaller_clip = clip.Expand(-1.0f, -1.0f);
4754 auto cull_dl = cull_builder.
Build();
4759 cull_dl->Dispatch(expector);
4764 auto larger_clip = clip.Expand(1.0f, 1.0f);
4768 cull_builder.
Save();
4771 auto cull_dl = cull_builder.
Build();
4775 cull_dl->Dispatch(expector);
4780 auto larger_clip = clip.Expand(1.0f, 1.0f);
4783 cull_builder.
Save();
4788 auto cull_dl = cull_builder.
Build();
4793 cull_dl->Dispatch(expector);
4798 auto smaller_clip = clip.Expand(-1.0f, -1.0f);
4799 auto smallest_clip = clip.Expand(-2.0f, -2.0f);
4803 cull_builder.
Save();
4807 auto cull_dl = cull_builder.
Build();
4812 cull_dl->Dispatch(expector);
4817 auto smaller_clip = clip.Expand(-1.0f, -1.0f);
4818 auto smallest_clip = clip.Expand(-2.0f, -2.0f);
4822 cull_builder.
Save();
4827 auto cull_dl = cull_builder.
Build();
4833 cull_dl->Dispatch(expector);
4842 auto encompassing_oval = clip.Expand(2.072f, 2.072f);
4847 auto cull_dl = cull_builder.
Build();
4851 cull_dl->Dispatch(expector);
4860 auto non_encompassing_oval = clip.Expand(2.071f, 2.071f);
4865 auto cull_dl = cull_builder.
Build();
4871 cull_dl->Dispatch(expector);
4877 ASSERT_FALSE(rrect.IsOval());
4882 auto cull_dl = cull_builder.
Build();
4886 cull_dl->Dispatch(expector);
4892 ASSERT_FALSE(rrect.IsOval());
4897 auto cull_dl = cull_builder.
Build();
4902 cull_dl->Dispatch(expector);
4908 path_builder.
MoveTo({0.0f, 0.0f});
4909 path_builder.
LineTo({1000.0f, 0.0f});
4910 path_builder.
LineTo({0.0f, 1000.0f});
4911 path_builder.
Close();
4919 ASSERT_TRUE(
path.Contains(clip.GetLeftTop()));
4920 ASSERT_TRUE(
path.Contains(clip.GetRightTop()));
4921 ASSERT_TRUE(
path.Contains(clip.GetRightBottom()));
4922 ASSERT_TRUE(
path.Contains(clip.GetLeftBottom()));
4927 auto cull_dl = cull_builder.
Build();
4932 cull_dl->Dispatch(expector);
4942 auto cull_dl = cull_builder.
Build();
4946 cull_dl->Dispatch(expector);
4951 auto smaller_clip = clip.Expand(-1.0f, -1.0f);
4957 auto cull_dl = cull_builder.
Build();
4963 cull_dl->Dispatch(expector);
4972 auto encompassing_oval = clip.Expand(2.072f, 2.072f);
4978 auto cull_dl = cull_builder.
Build();
4982 cull_dl->Dispatch(expector);
4991 auto non_encompassing_oval = clip.Expand(2.071f, 2.071f);
4997 auto cull_dl = cull_builder.
Build();
5004 cull_dl->Dispatch(expector);
5010 ASSERT_FALSE(
path.IsOval());
5015 auto cull_dl = cull_builder.
Build();
5019 cull_dl->Dispatch(expector);
5025 ASSERT_FALSE(rrect.IsOval());
5031 auto cull_dl = cull_builder.
Build();
5037 cull_dl->Dispatch(expector);
5041 constexpr size_t vertex_count = 2000000;
5042 auto points = std::vector<DlPoint>();
5043 points.reserve(vertex_count);
5044 auto colors = std::vector<DlColor>();
5045 colors.reserve(vertex_count);
5046 for (
size_t i = 0;
i < vertex_count;
i++) {
5050 ASSERT_EQ(
points.size(), vertex_count);
5051 ASSERT_EQ(colors.size(), vertex_count);
5054 ASSERT_GT(vertices->size(), 1u << 24);
5057 for (
int i = 0;
i < 1000;
i++) {
5059 for (
int j = 0; j < 16; j++) {
5060 builder.
SaveLayer(std::nullopt,
nullptr, backdrop.get());
5064 auto dl = builder.
Build();
5073 auto dl = builder.
Build();
5077 auto expect_dl = expected.
Build();
5087 auto dl = builder.
Build();
5091 auto expect_dl = expected.
Build();
5100 .top_right =
DlSize(10.0f),
5101 .bottom_left =
DlSize(20.0f),
5102 .bottom_right =
DlSize(50.0f)};
5118 auto dl = builder.
Build();
5120 EXPECT_EQ(CountOps(dl, DisplayListOpType::kDrawDiffRoundRect), 0);
5121 EXPECT_EQ(CountOps(dl, DisplayListOpType::kDrawRoundRect), 1);
5123 DlScalar expected_stroke_width = inner_inset;
5124 DlScalar half_width = expected_stroke_width * 0.5f;
5126 inner_rect.
Expand(half_width),
5127 {.top_left = DlSize(inner_radii.top_left.width + half_width),
5128 .top_right = DlSize(inner_radii.top_right.width + half_width),
5129 .bottom_left = DlSize(inner_radii.bottom_left.width + half_width),
5130 .bottom_right = DlSize(inner_radii.bottom_right.width + half_width)});
5136 expected.
DrawRoundRect(expected_round_rect, expected_paint);
5137 auto expect_dl = expected.
Build();
5149 .top_right =
DlSize(10.0f),
5150 .bottom_left =
DlSize(20.0f),
5151 .bottom_right =
DlSize(50.0f)};
5167 auto dl = builder.
Build();
5169 EXPECT_EQ(CountOps(dl, DisplayListOpType::kDrawDiffRoundRect), 1);
5170 EXPECT_EQ(CountOps(dl, DisplayListOpType::kDrawRoundRect), 0);
5176 DrawDiffRoundRectWithUnequalSidesDoesNotPromoteToDrawRoundRect) {
5182 .top_right =
DlSize(10.0f),
5183 .bottom_left =
DlSize(20.0f),
5184 .bottom_right =
DlSize(50.0f)};
5189 DlRect inner_rect = outer_rect.
Expand(-inner_inset_x, -inner_inset_y);
5201 auto dl = builder.
Build();
5203 EXPECT_EQ(CountOps(dl, DisplayListOpType::kDrawDiffRoundRect), 1);
5204 EXPECT_EQ(CountOps(dl, DisplayListOpType::kDrawRoundRect), 0);
5212 auto dl = builder.
Build();
5216 auto expect_dl = expected.
Build();
5235 auto dl = builder.
Build();
5239 auto expect_dl = expected.
Build();
5245 DrawStrokedUnclosedRectangularLinesDoesNotPromoteToDrawRect) {
5259 auto dl = builder.
Build();
5262 rect_dl_builder.
DrawRect(rect, paint);
5263 auto rect_dl = rect_dl_builder.
Build();
5283 auto dl = builder.
Build();
5287 auto expect_dl = expected.
Build();
5297 auto dl = builder.
Build();
5301 auto expect_dl = expected.
Build();
5312 auto dl = builder.
Build();
5316 auto expect_dl = expected.
Build();
5333 auto dl = builder.Build();
5337 auto expect_dl = expected.
Build();
5348 auto dl = builder.
Build();
5352 auto expect_dl = expected.
Build();
5363 auto dl = builder.
Build();
5367 auto expect_dl = expected.
Build();
5378 auto dl = builder.
Build();
5382 auto expect_dl = expected.
Build();
5396 auto dl = builder.
Build();
5401 auto expect_dl = expected.
Build();
5415 auto dl = builder.
Build();
5420 auto expect_dl = expected.
Build();
5429 ASSERT_TRUE(clip_path.
IsRect(
nullptr));
5435 auto dl = builder.
Build();
5440 auto expect_dl = expected.
Build();
5449 ASSERT_TRUE(clip_path.
IsOval(
nullptr));
5455 auto dl = builder.
Build();
5460 auto expect_dl = expected.
Build();
5476 auto dl = builder.
Build();
5481 auto expect_dl = expected.
Build();
5496 auto dl = builder.
Build();
5501 auto expect_dl = expected.
Build();
5516 auto dl = builder.
Build();
5521 auto expect_dl = expected.
Build();
5530 using Renderer =
const std::function<void(
DlCanvas&)>;
5531 auto test_bounded = [](
const std::string& label,
const Renderer& renderer) {
5535 auto display_list = builder.
Build();
5537 EXPECT_EQ(display_list->GetBounds(), draw_rect) << label;
5538 EXPECT_FALSE(display_list->root_is_unbounded()) << label;
5543 builder.
SaveLayer(std::nullopt,
nullptr);
5546 auto display_list = builder.
Build();
5548 EXPECT_EQ(display_list->GetBounds(), draw_rect) << label;
5549 EXPECT_FALSE(display_list->root_is_unbounded()) << label;
5557 display_list->Dispatch(expector);
5561 test_bounded(
"DrawLine", [](
DlCanvas& builder) {
5572 test_bounded(
"DrawDashedLine", [](
DlCanvas& builder) {
5591 test_bounded(
"DrawRect", [](
DlCanvas& builder) {
5595 test_bounded(
"DrawOval", [](
DlCanvas& builder) {
5599 test_bounded(
"DrawCircle", [](
DlCanvas& builder) {
5604 test_bounded(
"DrawRoundRect", [](
DlCanvas& builder) {
5609 test_bounded(
"DrawDiffRoundRect", [](
DlCanvas& builder) {
5616 test_bounded(
"DrawArc", [](
DlCanvas& builder) {
5620 test_bounded(
"DrawPathEvenOdd", [](
DlCanvas& builder) {
5626 test_bounded(
"DrawPathWinding", [](
DlCanvas& builder) {
5633 std::stringstream ss;
5634 ss <<
"DrawPoints(" <<
mode <<
")";
5636 DlPoint points[4] = {
5637 DlPoint(draw_rect.GetLeft() + 1.0f, draw_rect.GetTop() + 1.0f),
5638 DlPoint(draw_rect.GetRight() - 1.0f, draw_rect.GetTop() + 1.0f),
5639 DlPoint(draw_rect.GetRight() - 1.0f, draw_rect.GetBottom() - 1.0f),
5640 DlPoint(draw_rect.GetLeft() + 1.0f, draw_rect.GetBottom() - 1.0f),
5658 test_bounded(
"DrawVerticesTriangles", [](
DlCanvas& builder) {
5660 DlPoint(draw_rect.GetLeft(), draw_rect.GetTop()),
5661 DlPoint(draw_rect.GetRight(), draw_rect.GetTop()),
5662 DlPoint(draw_rect.GetRight(), draw_rect.GetBottom()),
5663 DlPoint(draw_rect.GetRight(), draw_rect.GetBottom()),
5664 DlPoint(draw_rect.GetLeft(), draw_rect.GetBottom()),
5665 DlPoint(draw_rect.GetLeft(), draw_rect.GetTop()),
5669 vertices.store_vertices(
points);
5670 builder.
DrawVertices(vertices.build(), DlBlendMode::kSrcOver, DlPaint());
5673 test_bounded(
"DrawVerticesTriangleStrip", [](DlCanvas& builder) {
5675 DlPoint(draw_rect.GetLeft(), draw_rect.GetTop()),
5676 DlPoint(draw_rect.GetRight(), draw_rect.GetTop()),
5677 DlPoint(draw_rect.GetRight(), draw_rect.GetBottom()),
5678 DlPoint(draw_rect.GetLeft(), draw_rect.GetBottom()),
5679 DlPoint(draw_rect.GetLeft(), draw_rect.GetTop()),
5680 DlPoint(draw_rect.GetRight(), draw_rect.GetTop()),
5684 vertices.store_vertices(
points);
5685 builder.DrawVertices(vertices.build(), DlBlendMode::kSrcOver,
DlPaint());
5688 test_bounded(
"DrawVerticesTriangleFan", [](DlCanvas& builder) {
5690 draw_rect.GetCenter(),
5691 DlPoint(draw_rect.GetLeft(), draw_rect.GetTop()),
5692 DlPoint(draw_rect.GetRight(), draw_rect.GetTop()),
5693 DlPoint(draw_rect.GetRight(), draw_rect.GetBottom()),
5694 DlPoint(draw_rect.GetLeft(), draw_rect.GetBottom()),
5698 vertices.store_vertices(
points);
5699 builder.DrawVertices(vertices.build(), DlBlendMode::kSrcOver,
DlPaint());
5702 test_bounded(
"DrawImage", [](DlCanvas& builder) {
5704 builder.DrawImage(
image,
DlPoint(draw_rect.GetLeft(), draw_rect.GetTop()),
5708 test_bounded(
"DrawImageRect", [](DlCanvas& builder) {
5713 test_bounded(
"DrawImageNine", [](DlCanvas& builder) {
5719 test_bounded(
"DrawTextBlob", [](DlCanvas& builder) {
5723 ASSERT_LT(blob->bounds().width(), draw_rect.GetWidth());
5724 ASSERT_LT(blob->bounds().height(), draw_rect.GetHeight());
5728 builder.DrawText(
text, draw_rect.GetLeft() - blob->bounds().left(),
5729 draw_rect.GetTop() - blob->bounds().top(),
DlPaint());
5730 builder.DrawText(
text, draw_rect.GetRight() - blob->bounds().right(),
5731 draw_rect.GetBottom() - blob->bounds().bottom(),
5735#if IMPELLER_SUPPORTS_RENDERING
5736 test_bounded(
"DrawTextFrame", [](DlCanvas& builder) {
5740 ASSERT_LT(blob->bounds().width(), draw_rect.GetWidth());
5741 ASSERT_LT(blob->bounds().height(), draw_rect.GetHeight());
5746 builder.DrawText(
text, draw_rect.GetLeft() - blob->bounds().left(),
5747 draw_rect.GetTop() - blob->bounds().top(),
DlPaint());
5748 builder.DrawText(
text, draw_rect.GetRight() - blob->bounds().right(),
5749 draw_rect.GetBottom() - blob->bounds().bottom(),
5754 test_bounded(
"DrawBoundedDisplayList", [](DlCanvas& builder) {
5755 DisplayListBuilder nested_builder(root_cull);
5756 nested_builder.DrawRect(draw_rect,
DlPaint());
5757 auto nested_display_list = nested_builder.Build();
5759 EXPECT_EQ(nested_display_list->GetBounds(), draw_rect);
5760 ASSERT_FALSE(nested_display_list->root_is_unbounded());
5762 builder.DrawDisplayList(nested_display_list);
5765 test_bounded(
"DrawShadow", [](DlCanvas& builder) {
5769 auto shadow_bounds =
5773 ASSERT_LT(shadow_bounds.GetWidth(), draw_rect.GetWidth());
5774 ASSERT_LT(shadow_bounds.GetHeight(), draw_rect.GetHeight());
5778 path.
WithOffset(draw_rect.GetLeftTop() - shadow_bounds.GetLeftTop());
5781 shadow_bounds.GetRightBottom());
5785 for (
int i = 0; i <= static_cast<int>(DlBlendMode::kLastMode);
i++) {
5787 if (mode == DlBlendMode::kDst) {
5791 std::stringstream ss;
5792 ss <<
"DrawRectWith" <<
mode;
5793 test_bounded(ss.str(), [mode](DlCanvas& builder) {
5795 builder.DrawRect(draw_rect, DlPaint().setBlendMode(mode).setAlpha(0x7f));
5805 using Renderer =
const std::function<void(
DlCanvas&)>;
5806 auto test_unbounded = [](
const std::string& label,
5807 const Renderer& renderer,
5808 int extra_save_layers = 0) {
5812 auto display_list = builder.
Build();
5814 EXPECT_EQ(display_list->GetBounds(), root_cull) << label;
5815 EXPECT_TRUE(display_list->root_is_unbounded()) << label;
5822 auto display_list = builder.
Build();
5824 EXPECT_EQ(display_list->GetBounds(), clip_rect) << label;
5825 EXPECT_FALSE(display_list->root_is_unbounded()) << label;
5830 builder.
SaveLayer(std::nullopt,
nullptr);
5833 auto display_list = builder.
Build();
5835 EXPECT_EQ(display_list->GetBounds(), root_cull) << label;
5836 EXPECT_FALSE(display_list->root_is_unbounded()) << label;
5844 for (
int i = 0;
i < extra_save_layers;
i++) {
5845 expector.addOpenExpectation();
5847 display_list->Dispatch(expector);
5852 builder.
SaveLayer(std::nullopt,
nullptr);
5856 auto display_list = builder.
Build();
5858 EXPECT_EQ(display_list->GetBounds(), clip_rect) << label;
5859 EXPECT_FALSE(display_list->root_is_unbounded()) << label;
5867 for (
int i = 0;
i < extra_save_layers;
i++) {
5868 expector.addOpenExpectation();
5870 display_list->Dispatch(expector);
5874 test_unbounded(
"DrawPaint", [](
DlCanvas& builder) {
5878 test_unbounded(
"DrawColor", [](
DlCanvas& builder) {
5882 test_unbounded(
"Clear", [](
DlCanvas& builder) {
5886 test_unbounded(
"DrawUnboundedDisplayList", [](
DlCanvas& builder) {
5889 auto nested_display_list = nested_builder.
Build();
5891 EXPECT_EQ(nested_display_list->GetBounds(), root_cull);
5892 ASSERT_TRUE(nested_display_list->root_is_unbounded());
5897 test_unbounded(
"DrawRectWithUnboundedImageFilter", [](
DlCanvas& builder) {
5900 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
5901 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
5902 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
5903 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
5908 ASSERT_TRUE(unbounded_cf->modifies_transparent_black());
5912 ASSERT_EQ(unbounded_if->map_local_bounds(draw_rect, output_bounds),
5919 "SaveLayerWithBackdropFilter",
5922 builder.
SaveLayer(std::nullopt,
nullptr, filter.get());
5938 ASSERT_TRUE(frame_bounds.
Contains(clip_rect));
5939 ASSERT_TRUE(frame_bounds.
Contains(draw_rect1));
5940 ASSERT_TRUE(frame_bounds.
Contains(draw_rect2));
5941 ASSERT_TRUE(frame_bounds.
Contains(cull_rect));
5943 ASSERT_TRUE(frame_clip.
Contains(clip_rect));
5944 ASSERT_TRUE(frame_clip.
Contains(draw_rect1));
5945 ASSERT_TRUE(frame_clip.
Contains(draw_rect2));
5946 ASSERT_TRUE(frame_clip.
Contains(cull_rect));
5964 builder.
SaveLayer(std::nullopt,
nullptr, bdf_filter.get());
5973 auto display_list = builder.
Build();
5977 display_list->Dispatch(ToReceiver(unculled), frame_bounds);
5978 auto unculled_dl = unculled.
Build();
5985 display_list->Dispatch(ToReceiver(culled), cull_rect);
5986 auto culled_dl = culled.
Build();
5999 auto expected_dl = expected.
Build();
6010 std::vector<DlPoint>
points(2050);
6024 EXPECT_TRUE(!!builder.
Build());
6030 std::vector<DlPoint>
points(40000);
6034 EXPECT_TRUE(!!builder.
Build());
6039 kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
6041 kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
6049 EXPECT_TRUE(builder.
Build()->can_apply_group_opacity());
6060 EXPECT_FALSE(builder.
Build()->can_apply_group_opacity());
6071 EXPECT_FALSE(builder.
Build()->can_apply_group_opacity());
6080 builder.
SaveLayer(std::nullopt,
nullptr);
6085 auto display_list = builder.
Build();
6086 EXPECT_TRUE(display_list->can_apply_group_opacity());
6092 display_list->Dispatch(expector);
6101 builder.
SaveLayer(std::nullopt,
nullptr);
6106 auto display_list = builder.
Build();
6107 EXPECT_TRUE(display_list->can_apply_group_opacity());
6113 display_list->Dispatch(expector);
6123 builder.
SaveLayer(std::nullopt,
nullptr);
6125 builder.
SaveLayer(std::nullopt,
nullptr);
6131 builder.
SaveLayer(std::nullopt,
nullptr);
6140 auto display_list = builder.
Build();
6141 EXPECT_TRUE(display_list->can_apply_group_opacity());
6156 display_list->Dispatch(expector);
6163sk_sp<DisplayList> TestSaveLayerWithMatrix(BuilderTransformer
transform) {
6170 const auto blur_filter =
6182 builder.
SaveLayer(std::nullopt, &save_paint, blur_filter.get());
6185 return builder.
Build();
6191 builder.
Scale(0.7, 0.7);
6199 builder.
Scale(0.0, 0.7);
6207 builder.
Scale(0.7, 0.0);
6215 builder.
Skew(1.0f, 1.0f);
int main(int argc, char **argv)
void DrawOval(const DlRect &bounds, const DlPaint &paint) override
static constexpr DlRect kMaxCullRect
void ClipRect(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint) override
void DrawImageNine(const sk_sp< DlImage > &image, const DlIRect ¢er, const DlRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr) override
void DrawAtlas(const sk_sp< DlImage > &atlas, const DlRSTransform xform[], const DlRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const DlRect *cullRect, const DlPaint *paint=nullptr) override
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint) override
void DrawShadow(const DlPath &path, const DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
Draws the shadow of the given |path| rendered in the provided |color| (which is only consulted for it...
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void DrawColor(DlColor color, DlBlendMode mode) override
DlMatrix GetMatrix() const override
void DrawCircle(const DlPoint ¢er, DlScalar radius, const DlPaint &paint) override
void TransformReset() override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void Rotate(DlScalar degrees) override
void DrawText(const std::shared_ptr< DlText > &text, DlScalar x, DlScalar y, const DlPaint &paint) override
void Scale(DlScalar sx, DlScalar sy) override
void DrawDisplayList(const sk_sp< DisplayList > display_list, DlScalar opacity=SK_Scalar1) override
void Skew(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void Transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
void DrawPaint(const DlPaint &paint) override
sk_sp< DisplayList > Build()
void DrawPath(const DlPath &path, const DlPaint &paint) override
DlRect GetDestinationClipCoverage() const override
void ClipPath(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[], const DlPaint &paint) override
void ClipOval(const DlRect &bounds, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
DlRect GetLocalClipCoverage() const override
int GetSaveCount() const override
void TransformFullPerspective(DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt, DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt, DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override
void DrawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner, const DlPaint &paint) override
void Transform(const DlMatrix &matrix) override
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static std::shared_ptr< DlMaskFilter > Make(DlBlurStyle style, SkScalar sigma, bool respect_ctm=true)
Developer-facing API for rendering anything within the engine.
virtual void DrawPaint(const DlPaint &paint)=0
virtual void DrawCircle(const DlPoint ¢er, DlScalar radius, const DlPaint &paint)=0
virtual void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint)=0
virtual void DrawDisplayList(const sk_sp< DisplayList > display_list, DlScalar opacity=SK_Scalar1)=0
virtual void DrawImageNine(const sk_sp< DlImage > &image, const DlIRect ¢er, const DlRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr)=0
virtual void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt)=0
virtual void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint)=0
virtual void DrawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner, const DlPaint &paint)=0
virtual void DrawRect(const DlRect &rect, const DlPaint &paint)=0
virtual void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint)=0
virtual void DrawText(const std::shared_ptr< DlText > &text, DlScalar x, DlScalar y, const DlPaint &paint)=0
virtual void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr)=0
virtual void DrawOval(const DlRect &bounds, const DlPaint &paint)=0
virtual void DrawColor(DlColor color, DlBlendMode mode=DlBlendMode::kSrcOver)=0
virtual void DrawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length, const DlPaint &paint)=0
virtual void DrawPath(const DlPath &path, const DlPaint &paint)=0
virtual void DrawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[], const DlPaint &paint)=0
void Clear(DlColor color)
virtual void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint)=0
virtual void DrawAtlas(const sk_sp< DlImage > &atlas, const DlRSTransform xform[], const DlRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const DlRect *cullRect, const DlPaint *paint=nullptr)=0
virtual void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast)=0
static DlRect ComputeShadowBounds(const DlPath &path, float elevation, DlScalar dpr, const DlMatrix &ctm)
Compute the local coverage for a |DrawShadow| operation using the given parameters (excluding the col...
virtual void DrawShadow(const DlPath &path, const DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr)=0
Draws the shadow of the given |path| rendered in the provided |color| (which is only consulted for it...
static std::shared_ptr< const DlColorFilter > MakeBlend(DlColor color, DlBlendMode mode)
static std::shared_ptr< const DlColorFilter > MakeMatrix(const float matrix[20])
static std::shared_ptr< DlColorSource > MakeRuntimeEffect(sk_sp< DlRuntimeEffect > runtime_effect, std::vector< std::shared_ptr< DlColorSource > > samplers, std::shared_ptr< std::vector< uint8_t > > uniform_data)
static std::shared_ptr< DlImageFilter > MakeBlur(DlScalar sigma_x, DlScalar sigma_y, DlTileMode tile_mode)
static std::shared_ptr< DlImageFilter > MakeRuntimeEffect(sk_sp< DlRuntimeEffect > runtime_effect, std::vector< std::shared_ptr< DlColorSource > > samplers, std::shared_ptr< std::vector< uint8_t > > uniform_data)
static std::shared_ptr< DlImageFilter > MakeColorFilter(const std::shared_ptr< const DlColorFilter > &filter)
static std::shared_ptr< DlImageFilter > MakeMatrix(const DlMatrix &matrix, DlImageSampling sampling)
Internal API for rendering recorded display lists to backends.
virtual void setStrokeMiter(float limit)=0
virtual void setStrokeWidth(float width)=0
virtual void setMaskFilter(const DlMaskFilter *filter)=0
virtual void setColorFilter(const DlColorFilter *filter)=0
virtual void setAntiAlias(bool aa)=0
virtual void setStrokeJoin(DlStrokeJoin join)=0
virtual void setImageFilter(const DlImageFilter *filter)=0
virtual void setColorSource(const DlColorSource *source)=0
virtual void setDrawStyle(DlDrawStyle style)=0
virtual void setBlendMode(DlBlendMode mode)=0
virtual void setColor(DlColor color)=0
virtual void setInvertColors(bool invert)=0
virtual void setStrokeCap(DlStrokeCap cap)=0
DlStrokeCap getStrokeCap() const
DlPaint & setColor(DlColor color)
DlPaint & setAntiAlias(bool isAntiAlias)
DlBlendMode getBlendMode() const
float getStrokeMiter() const
DlStrokeJoin getStrokeJoin() const
DlPaint & setStrokeCap(DlStrokeCap cap)
DlPaint & setStrokeWidth(float width)
DlPaint & setAlpha(uint8_t alpha)
DlPaint & setBlendMode(DlBlendMode mode)
const std::shared_ptr< const DlMaskFilter > & getMaskFilter() const
DlScalar getOpacity() const
DlDrawStyle getDrawStyle() const
DlPaint & setImageFilter(std::nullptr_t filter)
const std::shared_ptr< const DlColorSource > & getColorSource() const
const std::shared_ptr< DlImageFilter > & getImageFilter() const
float getStrokeWidth() const
const std::shared_ptr< const DlColorFilter > & getColorFilter() const
DlPaint & setMaskFilter(std::nullptr_t filter)
DlPaint & setDrawStyle(DlDrawStyle style)
DlPaint & setStrokeJoin(DlStrokeJoin join)
DlPaint & setColorFilter(std::nullptr_t filter)
DlPaint & setColorSource(std::nullptr_t source)
bool isInvertColors() const
DlPathBuilder & LineTo(DlPoint p2)
Draw a line from the current point to the indicated point p2.
DlPathBuilder & MoveTo(DlPoint p2)
Start a new contour that will originate at the indicated point p2.
DlPathBuilder & SetFillType(DlPathFillType fill_type)
Set the fill type that should be used to determine the interior of this path to the indicated |fill_t...
const DlPath TakePath()
Returns the path constructed by this path builder and resets its internal state to the default state ...
DlPathBuilder & Close()
The path is closed back to the location of the most recent MoveTo call. Contours that are filled are ...
DlPathBuilder & CubicCurveTo(DlPoint cp1, DlPoint cp2, DlPoint p2)
Draw a cubic bezier curve from the current point to the indicated point p2, using the indicated point...
bool IsRect(DlRect *rect=nullptr, bool *is_closed=nullptr) const
static DlPath MakeRectLTRB(DlScalar left, DlScalar top, DlScalar right, DlScalar bottom)
static DlPath MakeLine(const DlPoint a, const DlPoint b)
DlPath WithOffset(const DlPoint offset) const
static DlPath MakeRoundRect(const DlRoundRect &rrect)
static DlPath MakeCircle(const DlPoint center, DlScalar radius)
static DlPath MakeRect(const DlRect &rect)
static DlPath MakeRoundRectXY(const DlRect &rect, DlScalar x_radius, DlScalar y_radius, bool counter_clock_wise=false)
bool IsRoundRect(DlRoundRect *rrect=nullptr) const
static DlPath MakeOvalLTRB(DlScalar left, DlScalar top, DlScalar right, DlScalar bottom)
DlPath WithFillType(DlPathFillType type) const
static DlPath MakeOval(const DlRect &bounds)
bool IsOval(DlRect *bounds=nullptr) const
static std::shared_ptr< DlTextImpeller > MakeFromBlob(const sk_sp< SkTextBlob > &blob)
static std::shared_ptr< DlTextImpeller > Make(const std::shared_ptr< impeller::TextFrame > &frame)
static std::shared_ptr< DlTextSkia > Make(const sk_sp< SkTextBlob > &blob)
static constexpr Flags kNone
static std::shared_ptr< DlVertices > Make(DlVertexMode mode, int vertex_count, const DlPoint vertices[], const DlPoint texture_coordinates[], const DlColor colors[], int index_count=0, const uint16_t indices[]=nullptr, const DlRect *bounds=nullptr)
Constructs a DlVector with compact inline storage for all of its required and optional lists of data.
bool content_is_clipped() const
static const SaveLayerOptions kNoAttributes
SaveLayerOptions with_bounds_from_caller() const
bool bounds_from_caller() const
bool content_is_unbounded() const
static const SaveLayerOptions kWithAttributes
SaveLayerOptions with_content_is_clipped() const
bool can_distribute_opacity() const
void clipOval(const DlRect &bounds, DlClipOp clip_op, bool is_aa) override
void clipRect(const DlRect &rect, DlClipOp clip_op, bool is_aa) override
ClipExpector & addExpectation(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)
void clipPath(const DlPath &path, DlClipOp clip_op, bool is_aa) override
ClipExpector & addExpectation(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)
ClipExpector(const std::string &file, int line)
void clipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op, bool is_aa) override
void clipRoundSuperellipse(const DlRoundSuperellipse &rse, DlClipOp clip_op, bool is_aa) override
ClipExpector & addExpectation(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)
ClipExpector & addOvalExpectation(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false)
void saveLayer(const DlRect &bounds, const SaveLayerOptions &options, uint32_t total_content_depth, DlBlendMode max_content_mode, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void saveLayer(const DlRect &bounds, SaveLayerOptions options, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void save(uint32_t total_content_depth) override
bool all_depths_checked() const
DepthExpector(std::vector< uint32_t > expectations)
uint32_t GetOpsReceived()
static DlOpReceiver & ToReceiver(DisplayListBuilder &builder)
static void check_inverted_bounds(DlRenderer &renderer, const std::string &desc)
const std::function< void(DlCanvas &)> DlSetup
static void check_defaults(DisplayListBuilder &builder, const DlRect &cull_rect=DisplayListBuilder::kMaxCullRect)
static sk_sp< DisplayList > Build(size_t g_index, size_t v_index)
DisplayListTestBase()=default
static void verify_inverted_bounds(DlSetup &setup, DlRenderer &renderer, DlPaint paint, DlRect render_rect, DlRect expected_bounds, const std::string &desc)
static sk_sp< DisplayList > Build(DisplayListInvocation &invocation)
const std::function< void(DlCanvas &, DlPaint &, DlRect &)> DlRenderer
static int CountOps(const sk_sp< DisplayList > &dl, DisplayListOpType op_type)
SaveLayerBoundsExpector & addComputedExpectation(const DlRect &bounds)
bool all_bounds_checked() const
void saveLayer(const DlRect &bounds, const SaveLayerOptions options, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
SaveLayerBoundsExpector & addSuppliedExpectation(const DlRect &bounds, bool clipped=false)
SaveLayerBoundsExpector()
bool all_expectations_checked() const
void saveLayer(const DlRect &bounds, const SaveLayerOptions options, const DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
SaveLayerExpector(const std::string &file, int line)
SaveLayerExpector & addOpenExpectation()
SaveLayerExpector & addExpectation(const SaveLayerExpectations &expected)
SaveLayerExpector & addDetail(const std::string &detail)
virtual void saveLayer(const DlRect &bounds, const SaveLayerOptions &options, uint32_t total_content_depth, DlBlendMode max_content_blend_mode, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt)
SaveLayerExpector & addExpectation(const SaveLayerOptionsTester &tester)
#define CLIP_EXPECTOR(name)
#define SAVE_LAYER_EXPECTOR(name)
#define RUN_TESTS2(body, expect)
#define TEST_RTREE(rtree, query, expected_rects, expected_indices)
FlutterVulkanImage * image
#define FML_LOG(severity)
#define FML_UNREACHABLE()
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
TEST_F(DisplayListTest, Defaults)
static const DlBlurMaskFilter kTestMaskFilter1(DlBlurStyle::kNormal, 3.0)
bool DisplayListsNE_Verbose(const DisplayList *a, const DisplayList *b)
constexpr DlPoint kTestPoints[]
static const auto kTestMatrixColorFilter1
static std::vector< testing::DisplayListInvocationGroup > allGroups
static const std::shared_ptr< DlColorSource > kTestSource1
constexpr DlRect kTestBounds
static const DlPath kTestPath1
sk_sp< DlImage > MakeTestImage(int w, int h, int checker_size)
static void test_rtree(const sk_sp< const DlRTree > &rtree, const DlRect &query, std::vector< DlRect > expected_rects, const std::vector< int > &expected_indices, const std::string &file, int line)
static DlImageSampling kLinearSampling
::std::ostream & operator<<(::std::ostream &os, const SaveLayerExpectations &expect)
bool DisplayListsEQ_Verbose(const DisplayList *a, const DisplayList *b)
static DlImageSampling kNearestSampling
sk_sp< SkTextBlob > GetTestTextBlob(int index)
std::function< bool(const SaveLayerOptions &options)> SaveLayerOptionsTester
static const DlBlurImageFilter kTestBlurImageFilter1(5.0, 5.0, DlTileMode::kClamp)
std::vector< DisplayListInvocationGroup > CreateAllGroups()
static const std::shared_ptr< DlVertices > kTestVertices1
static const DlRoundRect kTestRRect
static sk_sp< DisplayList > TestDisplayList1
impeller::Scalar DlScalar
DlPaint DisplayListBuilderTestingAttributes(DisplayListBuilder &builder)
constexpr bool DlScalarNearlyEqual(DlScalar x, DlScalar y, DlScalar tolerance=kEhCloseEnough)
impeller::RoundRect DlRoundRect
impeller::Matrix DlMatrix
impeller::Degrees DlDegrees
DlOpReceiver & DisplayListBuilderTestingAccessor(DisplayListBuilder &builder)
@ kLines
draw each separate pair of points as a line segment
@ kPolygon
draw each pair of overlapping points as a line segment
@ kPoints
draw each point separately
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library name
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
@ kStrokeAndFill
both strokes and fills shapes
@ kStroke
strokes boundary of shapes
@ kFill
fills interior of shapes
impeller::IRect32 DlIRect
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
@ kNormal
fuzzy inside and outside
impeller::BlendMode DlBlendMode
TEST_F(EngineAnimatorTest, AnimatorAcceptsMultipleRenders)
int DisplayListBuilderTestingLastOpIndex(DisplayListBuilder &builder)
impeller::ShaderType type
static constexpr DlColor kMagenta()
static constexpr DlColor kWhite()
static constexpr DlColor kBlue()
static constexpr DlColor kBlack()
static constexpr DlColor kTransparent()
static constexpr DlColor kRed()
static constexpr DlColor kGreen()
std::variant< DlRect, DlRoundRect, DlRoundSuperellipse, DlPath > shape
std::vector< DisplayListInvocation > variants
uint32_t adjust_render_op_depth_cost(uint32_t previous_cost)
uint32_t depth_accumulated(uint32_t depth_scale=1u)
void Invoke(DlOpReceiver &builder)
SaveLayerExpectations(const SaveLayerOptionsTester &t)
std::optional< SaveLayerOptions > options
SaveLayerExpectations(DlBlendMode mode)
SaveLayerExpectations(const SaveLayerOptions &o)
std::optional< SaveLayerOptionsTester > tester
std::optional< DlBlendMode > max_blend_mode
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeTranslation(const Vector3 &t)
constexpr bool IsIdentity() const
bool IsInvertible() const
static constexpr Matrix MakeRow(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
static constexpr Matrix MakeSkew(Scalar sx, Scalar sy)
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
static RoundRect MakeRectRadii(const Rect &rect, const RoundingRadii &radii)
static RoundRect MakeOval(const Rect &rect)
static RoundRect MakeRectXY(const Rect &rect, Scalar x_radius, Scalar y_radius)
static RoundRect MakeRect(const Rect &rect)
static constexpr TPoint< Type > MakeXY(Type x, Type y)
constexpr auto GetBottom() const
static constexpr TRect MakeWH(Type width, Type height)
constexpr auto GetTop() const
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
constexpr bool Contains(const TPoint< Type > &p) const
Returns true iff the provided point |p| is inside the half-open interior of this rectangle.
static constexpr std::enable_if_t< std::is_floating_point_v< FT >, TRect > Make(const TRect< U > &rect)
constexpr bool IntersectsWithRect(const TRect &o) const
constexpr auto GetLeft() const
constexpr TPoint< T > GetLeftTop() const
RoundOut(const TRect< U > &r)
constexpr auto GetRight() const
static constexpr TRect MakeXYWH(Type x, Type y, Type width, Type height)
constexpr TRect TransformAndClipBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle, clipped against the near clippin...
constexpr TPoint< T > GetRightBottom() const
constexpr TPoint< T > GetLeftBottom() const
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
constexpr TPoint< T > GetRightTop() const
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
constexpr Point GetCenter() const
Get the center point as a |Point|.
constexpr TRect IntersectionOrEmpty(const TRect &o) const
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
std::vector< Point > points