Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2021 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
| 7 | |
| 8 | #include "src/gpu/GrRenderTaskCluster.h" |
| 9 | #include "src/gpu/mock/GrMockRenderTask.h" |
| 10 | #include "src/gpu/mock/GrMockSurfaceProxy.h" |
| 11 | #include "tests/Test.h" |
| 12 | |
| 13 | typedef void (*CreateGraphPF)(SkTArray<sk_sp<GrMockRenderTask>>* graph, |
| 14 | SkTArray<sk_sp<GrMockRenderTask>>* expected); |
| 15 | |
Adlai Holler | 9a77795 | 2021-01-27 14:11:23 -0500 | [diff] [blame] | 16 | static void make_proxies(int count, SkTArray<sk_sp<GrSurfaceProxy>>* proxies) { |
| 17 | proxies->reset(count); |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 18 | for (int i = 0; i < count; i++) { |
| 19 | auto name = SkStringPrintf("%c", 'A' + i); |
Adlai Holler | 9a77795 | 2021-01-27 14:11:23 -0500 | [diff] [blame] | 20 | proxies->at(i) = sk_make_sp<GrMockSurfaceProxy>(std::move(name)); |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 21 | } |
| 22 | } |
| 23 | |
| 24 | static void make_tasks(int count, SkTArray<sk_sp<GrMockRenderTask>>* tasks) { |
| 25 | tasks->reset(count); |
| 26 | for (int i = 0; i < count; i++) { |
| 27 | tasks->at(i) = sk_make_sp<GrMockRenderTask>(); |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | /* |
| 32 | * In: A1 B1 A2 |
| 33 | * Out: B1 A1 A2 |
| 34 | */ |
| 35 | static void create_graph0(SkTArray<sk_sp<GrMockRenderTask>>* graph, |
| 36 | SkTArray<sk_sp<GrMockRenderTask>>* expected) { |
Adlai Holler | 9a77795 | 2021-01-27 14:11:23 -0500 | [diff] [blame] | 37 | SkTArray<sk_sp<GrSurfaceProxy>> proxies; |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 38 | make_proxies(2, &proxies); |
| 39 | make_tasks(3, graph); |
| 40 | |
| 41 | graph->at(0)->addTarget(proxies[0]); |
| 42 | graph->at(1)->addTarget(proxies[1]); |
| 43 | graph->at(2)->addTarget(proxies[0]); |
| 44 | graph->at(2)->addDependency(graph->at(1).get()); |
| 45 | |
| 46 | expected->push_back(graph->at(1)); |
| 47 | expected->push_back(graph->at(0)); |
| 48 | expected->push_back(graph->at(2)); |
| 49 | } |
| 50 | |
| 51 | /* |
| 52 | * In: A1 B1 A2 C1 A3 |
| 53 | * Out: B1 C1 A1 A2 A3 |
| 54 | */ |
| 55 | static void create_graph1(SkTArray<sk_sp<GrMockRenderTask>>* graph, |
| 56 | SkTArray<sk_sp<GrMockRenderTask>>* expected) { |
Adlai Holler | 9a77795 | 2021-01-27 14:11:23 -0500 | [diff] [blame] | 57 | SkTArray<sk_sp<GrSurfaceProxy>> proxies; |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 58 | make_proxies(3, &proxies); |
| 59 | make_tasks(5, graph); |
| 60 | |
| 61 | graph->at(0)->addTarget(proxies[0]); |
| 62 | graph->at(1)->addTarget(proxies[1]); |
| 63 | graph->at(2)->addTarget(proxies[0]); |
| 64 | graph->at(3)->addTarget(proxies[2]); |
| 65 | graph->at(4)->addTarget(proxies[0]); |
| 66 | |
| 67 | expected->push_back(graph->at(1)); |
| 68 | expected->push_back(graph->at(3)); |
| 69 | expected->push_back(graph->at(0)); |
| 70 | expected->push_back(graph->at(2)); |
| 71 | expected->push_back(graph->at(4)); |
| 72 | } |
| 73 | |
| 74 | /* |
| 75 | * In: A1 B1 A2. |
| 76 | * Srcs: A1->B1, B1->A2. |
| 77 | * Out: A1 B1 A2. Can't reorder. |
| 78 | */ |
| 79 | static void create_graph2(SkTArray<sk_sp<GrMockRenderTask>>* graph, |
| 80 | SkTArray<sk_sp<GrMockRenderTask>>* expected) { |
Adlai Holler | 9a77795 | 2021-01-27 14:11:23 -0500 | [diff] [blame] | 81 | SkTArray<sk_sp<GrSurfaceProxy>> proxies; |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 82 | make_proxies(2, &proxies); |
| 83 | make_tasks(3, graph); |
| 84 | |
| 85 | graph->at(0)->addTarget(proxies[0]); |
| 86 | graph->at(1)->addTarget(proxies[1]); |
| 87 | graph->at(2)->addTarget(proxies[0]); |
| 88 | |
| 89 | graph->at(1)->addDependency(graph->at(0).get()); |
| 90 | graph->at(2)->addDependency(graph->at(1).get()); |
| 91 | |
| 92 | // expected is empty. Can't reorder. |
| 93 | } |
| 94 | |
Adlai Holler | b5dda50 | 2021-01-28 13:23:13 -0500 | [diff] [blame] | 95 | /* |
| 96 | * Write-after-read case. |
| 97 | * In: A1 B1 A2 B2 |
| 98 | * Srcs: A1->B1, A2->B2 |
| 99 | * Used: B1(A), B2(A) |
| 100 | * Out: Can't reorder. |
| 101 | */ |
| 102 | static void create_graph3(SkTArray<sk_sp<GrMockRenderTask>>* graph, |
| 103 | SkTArray<sk_sp<GrMockRenderTask>>* expected) { |
| 104 | SkTArray<sk_sp<GrSurfaceProxy>> proxies; |
| 105 | make_proxies(2, &proxies); |
| 106 | make_tasks(4, graph); |
| 107 | |
| 108 | graph->at(0)->addTarget(proxies[0]); |
| 109 | graph->at(1)->addTarget(proxies[1]); |
| 110 | graph->at(2)->addTarget(proxies[0]); |
| 111 | graph->at(3)->addTarget(proxies[1]); |
| 112 | |
| 113 | graph->at(1)->addDependency(graph->at(0).get()); |
| 114 | graph->at(3)->addDependency(graph->at(2).get()); |
| 115 | |
| 116 | graph->at(1)->addUsed(proxies[0]); |
| 117 | graph->at(3)->addUsed(proxies[0]); |
| 118 | |
| 119 | // expected is empty. Can't reorder. |
| 120 | } |
| 121 | |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 122 | DEF_TEST(GrRenderTaskCluster, reporter) { |
| 123 | CreateGraphPF tests[] = { |
| 124 | create_graph0, |
| 125 | create_graph1, |
Adlai Holler | b5dda50 | 2021-01-28 13:23:13 -0500 | [diff] [blame] | 126 | create_graph2, |
| 127 | create_graph3 |
Adlai Holler | 08f5311 | 2021-01-20 17:44:15 -0500 | [diff] [blame] | 128 | }; |
| 129 | |
| 130 | for (size_t i = 0; i < SK_ARRAY_COUNT(tests); ++i) { |
| 131 | SkTArray<sk_sp<GrMockRenderTask>> graph; |
| 132 | SkTArray<sk_sp<GrMockRenderTask>> expectedOutput; |
| 133 | |
| 134 | (tests[i])(&graph, &expectedOutput); |
| 135 | |
| 136 | SkTInternalLList<GrRenderTask> llist; |
| 137 | // TODO: Why does Span not want to convert from sk_sp<GrMockRenderTask> to |
| 138 | // `const sk_sp<GrRenderTask>`? |
| 139 | SkSpan<const sk_sp<GrRenderTask>> graphSpan( |
| 140 | reinterpret_cast<sk_sp<GrRenderTask>*>(graph.data()), graph.count()); |
| 141 | bool actualResult = GrClusterRenderTasks(graphSpan, &llist); |
| 142 | |
| 143 | if (expectedOutput.empty()) { |
| 144 | REPORTER_ASSERT(reporter, !actualResult); |
| 145 | } else { |
| 146 | REPORTER_ASSERT(reporter, actualResult); |
| 147 | // SkTInternalLList::countEntries is debug-only and these tests run in release. |
| 148 | int newCount = 0; |
| 149 | for ([[maybe_unused]] GrRenderTask* t : llist) { |
| 150 | newCount++; |
| 151 | } |
| 152 | REPORTER_ASSERT(reporter, newCount == expectedOutput.count()); |
| 153 | |
| 154 | int j = 0; |
| 155 | for (GrRenderTask* n : llist) { |
| 156 | REPORTER_ASSERT(reporter, n == expectedOutput[j++].get()); |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | //SkDEBUGCODE(print(graph);) |
| 161 | } |
| 162 | } |