xref: /aosp_15_r20/external/skia/tests/GrRenderTaskClusterTest.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 "include/core/SkRefCnt.h"
9 #include "include/core/SkSpan.h"
10 #include "include/core/SkString.h"
11 #include "include/private/base/SkTArray.h"
12 #include "src/base/SkTInternalLList.h"
13 #include "src/gpu/ganesh/GrRenderTask.h"
14 #include "src/gpu/ganesh/GrRenderTaskCluster.h"
15 #include "src/gpu/ganesh/GrSurfaceProxy.h"
16 #include "src/gpu/ganesh/mock/GrMockRenderTask.h"
17 #include "src/gpu/ganesh/mock/GrMockSurfaceProxy.h"
18 #include "tests/Test.h"
19 
20 #include <array>
21 #include <cstddef>
22 #include <utility>
23 
24 using namespace skia_private;
25 
26 typedef void (*CreateGraphPF)(TArray<sk_sp<GrMockRenderTask>>* graph,
27                               TArray<sk_sp<GrMockRenderTask>>* expected);
28 
make_proxies(int count,TArray<sk_sp<GrSurfaceProxy>> * proxies)29 static void make_proxies(int count, TArray<sk_sp<GrSurfaceProxy>>* proxies) {
30     proxies->reset(count);
31     for (int i = 0; i < count; i++) {
32         auto name = SkStringPrintf("%c", 'A' + i);
33         proxies->at(i) = sk_make_sp<GrMockSurfaceProxy>(std::move(name),
34         /*label=*/"RenderTaskClusterTest");
35     }
36 }
37 
make_tasks(int count,TArray<sk_sp<GrMockRenderTask>> * tasks)38 static void make_tasks(int count, TArray<sk_sp<GrMockRenderTask>>* tasks) {
39     tasks->reset(count);
40     for (int i = 0; i < count; i++) {
41         tasks->at(i) = sk_make_sp<GrMockRenderTask>();
42     }
43 }
44 
45 /*
46  * In:  A1 B1 A2
47  * Out: B1 A1 A2
48  */
create_graph0(TArray<sk_sp<GrMockRenderTask>> * graph,TArray<sk_sp<GrMockRenderTask>> * expected)49 static void create_graph0(TArray<sk_sp<GrMockRenderTask>>* graph,
50                           TArray<sk_sp<GrMockRenderTask>>* expected) {
51     TArray<sk_sp<GrSurfaceProxy>> proxies;
52     make_proxies(2, &proxies);
53     make_tasks(3, graph);
54 
55     graph->at(0)->addTarget(proxies[0]);
56     graph->at(1)->addTarget(proxies[1]);
57     graph->at(2)->addTarget(proxies[0]);
58     graph->at(2)->addDependency(graph->at(1).get());
59 
60     expected->push_back(graph->at(1));
61     expected->push_back(graph->at(0));
62     expected->push_back(graph->at(2));
63 }
64 
65 /*
66  * In:  A1 B1 A2 C1 A3
67  * Out: B1 C1 A1 A2 A3
68  */
create_graph1(TArray<sk_sp<GrMockRenderTask>> * graph,TArray<sk_sp<GrMockRenderTask>> * expected)69 static void create_graph1(TArray<sk_sp<GrMockRenderTask>>* graph,
70                           TArray<sk_sp<GrMockRenderTask>>* expected) {
71     TArray<sk_sp<GrSurfaceProxy>> proxies;
72     make_proxies(3, &proxies);
73     make_tasks(5, graph);
74 
75     graph->at(0)->addTarget(proxies[0]);
76     graph->at(1)->addTarget(proxies[1]);
77     graph->at(2)->addTarget(proxies[0]);
78     graph->at(3)->addTarget(proxies[2]);
79     graph->at(4)->addTarget(proxies[0]);
80 
81     expected->push_back(graph->at(1));
82     expected->push_back(graph->at(3));
83     expected->push_back(graph->at(0));
84     expected->push_back(graph->at(2));
85     expected->push_back(graph->at(4));
86 }
87 
88 /*
89  * In:   A1 B1 A2.
90  * Srcs: A1->B1, B1->A2.
91  * Out:  A1 B1 A2. Can't reorder.
92  */
create_graph2(TArray<sk_sp<GrMockRenderTask>> * graph,TArray<sk_sp<GrMockRenderTask>> * expected)93 static void create_graph2(TArray<sk_sp<GrMockRenderTask>>* graph,
94                           TArray<sk_sp<GrMockRenderTask>>* expected) {
95     TArray<sk_sp<GrSurfaceProxy>> proxies;
96     make_proxies(2, &proxies);
97     make_tasks(3, graph);
98 
99     graph->at(0)->addTarget(proxies[0]);
100     graph->at(1)->addTarget(proxies[1]);
101     graph->at(2)->addTarget(proxies[0]);
102 
103     graph->at(1)->addDependency(graph->at(0).get());
104     graph->at(2)->addDependency(graph->at(1).get());
105 
106     // expected is empty. Can't reorder.
107 }
108 
109 /*
110  * Write-after-read case.
111  * In:   A1 B1 A2 B2
112  * Srcs: A1->B1, A2->B2
113  * Used: B1(A), B2(A)
114  * Out:  Can't reorder.
115  */
create_graph3(TArray<sk_sp<GrMockRenderTask>> * graph,TArray<sk_sp<GrMockRenderTask>> * expected)116 static void create_graph3(TArray<sk_sp<GrMockRenderTask>>* graph,
117                           TArray<sk_sp<GrMockRenderTask>>* expected) {
118     TArray<sk_sp<GrSurfaceProxy>> proxies;
119     make_proxies(2, &proxies);
120     make_tasks(4, graph);
121 
122     graph->at(0)->addTarget(proxies[0]);
123     graph->at(1)->addTarget(proxies[1]);
124     graph->at(2)->addTarget(proxies[0]);
125     graph->at(3)->addTarget(proxies[1]);
126 
127     graph->at(1)->addDependency(graph->at(0).get());
128     graph->at(3)->addDependency(graph->at(2).get());
129 
130     graph->at(1)->addUsed(proxies[0]);
131     graph->at(3)->addUsed(proxies[0]);
132 
133     // expected is empty. Can't reorder.
134 }
135 
DEF_TEST(GrRenderTaskCluster,reporter)136 DEF_TEST(GrRenderTaskCluster, reporter) {
137     CreateGraphPF tests[] = {
138         create_graph0,
139         create_graph1,
140         create_graph2,
141         create_graph3
142     };
143 
144     for (size_t i = 0; i < std::size(tests); ++i) {
145         TArray<sk_sp<GrMockRenderTask>> graph;
146         TArray<sk_sp<GrMockRenderTask>> expectedOutput;
147 
148         (tests[i])(&graph, &expectedOutput);
149 
150         SkTInternalLList<GrRenderTask> llist;
151         // TODO: Why does Span not want to convert from sk_sp<GrMockRenderTask> to
152         // `const sk_sp<GrRenderTask>`?
153         SkSpan<const sk_sp<GrRenderTask>> graphSpan(
154             reinterpret_cast<sk_sp<GrRenderTask>*>(graph.data()), graph.size());
155         bool actualResult = GrClusterRenderTasks(graphSpan, &llist);
156 
157         if (expectedOutput.empty()) {
158             REPORTER_ASSERT(reporter, !actualResult);
159             size_t newCount = 0;
160             for (const GrRenderTask* t : llist) {
161                 REPORTER_ASSERT(reporter, newCount < graphSpan.size() &&
162                                           t == graph[newCount].get());
163                 ++newCount;
164             }
165             REPORTER_ASSERT(reporter, newCount == graphSpan.size());
166         } else {
167             REPORTER_ASSERT(reporter, actualResult);
168             // SkTInternalLList::countEntries is debug-only and these tests run in release.
169             int newCount = 0;
170             for ([[maybe_unused]] GrRenderTask* t : llist) {
171                 newCount++;
172             }
173             REPORTER_ASSERT(reporter, newCount == expectedOutput.size());
174 
175             int j = 0;
176             for (GrRenderTask* n : llist) {
177                 REPORTER_ASSERT(reporter, n == expectedOutput[j++].get());
178             }
179         }
180 
181         //SkDEBUGCODE(print(graph);)
182     }
183 }
184