Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
TopoSortTest.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2015 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
12#include "src/base/SkRandom.h"
14#include "tests/Test.h"
15#include "tools/ToolUtils.h"
16
17#include <cstddef>
18#include <vector>
19
20using namespace skia_private;
21
23
24/* Simple diamond
25 * 3
26 * . .
27 * / \
28 * 1 2
29 * . .
30 * \ /
31 * 0
32 */
35
36 (*graph)[0]->dependsOn((*graph)[1].get());
37 (*graph)[0]->dependsOn((*graph)[2].get());
38 (*graph)[1]->dependsOn((*graph)[3].get());
39 (*graph)[2]->dependsOn((*graph)[3].get());
40}
41
44
45 for (int i = 0; i < n - 1; ++i) {
46 (*graph)[i+1]->dependsOn((*graph)[i].get());
47 }
48}
49
50/* Simple chain
51 * 0
52 * ^
53 * |
54 * 1
55 * ^
56 * |
57 * 2
58 * ^
59 * |
60 * 3
61 */
65
66/* Simple Loop
67 * 2
68 * / .
69 * / \
70 * . \
71 * 0 ---> 1
72 */
75
76 (*graph)[0]->dependsOn((*graph)[1].get());
77 (*graph)[1]->dependsOn((*graph)[2].get());
78 (*graph)[2]->dependsOn((*graph)[0].get());
79}
80
81/* Double diamond
82 * 6
83 * . .
84 * / \
85 * 4 5
86 * . .
87 * \ /
88 * 3
89 * . .
90 * / \
91 * 1 2
92 * . .
93 * \ /
94 * 0
95 */
98
99 (*graph)[0]->dependsOn((*graph)[1].get());
100 (*graph)[0]->dependsOn((*graph)[2].get());
101 (*graph)[1]->dependsOn((*graph)[3].get());
102 (*graph)[2]->dependsOn((*graph)[3].get());
103
104 (*graph)[3]->dependsOn((*graph)[4].get());
105 (*graph)[3]->dependsOn((*graph)[5].get());
106 (*graph)[4]->dependsOn((*graph)[6].get());
107 (*graph)[5]->dependsOn((*graph)[6].get());
108}
109
110/* Two independent diamonds
111 * 3 7
112 * . . . .
113 * / \ / \
114 * 1 2 5 6
115 * . . . .
116 * \ / \ /
117 * 0 4
118 */
121
122 (*graph)[0]->dependsOn((*graph)[1].get());
123 (*graph)[0]->dependsOn((*graph)[2].get());
124 (*graph)[1]->dependsOn((*graph)[3].get());
125 (*graph)[2]->dependsOn((*graph)[3].get());
126
127 (*graph)[4]->dependsOn((*graph)[5].get());
128 (*graph)[4]->dependsOn((*graph)[6].get());
129 (*graph)[5]->dependsOn((*graph)[7].get());
130 (*graph)[6]->dependsOn((*graph)[7].get());
131}
132
133/* Two linked diamonds w/ two loops
134 * 5 6
135 * / . . \
136 * . \ / .
137 * 2 3 4
138 * \ . /
139 * . / \ .
140 * 0 1
141 */
144
145 (*graph)[0]->dependsOn((*graph)[3].get());
146 (*graph)[1]->dependsOn((*graph)[3].get());
147 (*graph)[2]->dependsOn((*graph)[0].get());
148 (*graph)[3]->dependsOn((*graph)[5].get());
149 (*graph)[3]->dependsOn((*graph)[6].get());
150 (*graph)[4]->dependsOn((*graph)[1].get());
151 (*graph)[5]->dependsOn((*graph)[2].get());
152 (*graph)[6]->dependsOn((*graph)[4].get());
153}
154
155/* Two disjoint loops
156 * 2 5
157 * / . / .
158 * / \ / \
159 * . \ . \
160 * 0 ---> 1 3 ---> 4
161 */
164
165 (*graph)[0]->dependsOn((*graph)[1].get());
166 (*graph)[1]->dependsOn((*graph)[2].get());
167 (*graph)[2]->dependsOn((*graph)[0].get());
168
169 (*graph)[3]->dependsOn((*graph)[4].get());
170 (*graph)[4]->dependsOn((*graph)[5].get());
171 (*graph)[5]->dependsOn((*graph)[3].get());
172}
173
174DEF_TEST(TopoSort, reporter) {
175 SkRandom rand;
176
177 struct {
178 CreateGraphPF fCreate;
179 bool fExpectedResult;
180 } tests[] = {
181 { create_graph0, true },
182 { create_graph1, true },
183 { create_graph2, false },
184 { create_graph3, true },
185 { create_graph4, true },
186 { create_graph5, false },
187 { create_graph6, false },
188 };
189
190 for (size_t i = 0; i < std::size(tests); ++i) {
192
193 (tests[i].fCreate)(&graph);
194
195 const int numNodes = graph.size();
196
198
199 bool actualResult = GrTTopoSort<ToolUtils::TopoTestNode>(graph);
200 REPORTER_ASSERT(reporter, actualResult == tests[i].fExpectedResult);
201 REPORTER_ASSERT(reporter, numNodes == graph.size());
202
203 if (tests[i].fExpectedResult) {
204 for (const auto& node : graph) {
205 REPORTER_ASSERT(reporter, node->check());
206 }
207 } else {
208 // When the topological sort fails all the nodes should still appear in the result
209 // but their order can be somewhat arbitrary.
210 std::vector<bool> seen(numNodes, false);
211
212 for (const auto& node : graph) {
213 SkASSERT(node);
214 SkASSERT(!seen[node->id()]);
215 seen[node->id()] = true;
216 }
217 }
218
219 //SkDEBUGCODE(print(graph);)
220 }
221
222 // Some additional tests that do multiple partial sorts of graphs where we know nothing in an
223 // earlier partion depends on anything in a later partition.
224 for (int n = 2; n < 6; ++n) {
225 for (int split = 1; split < n; ++split) {
227 create_simple_chain(&graph, n);
228 SkSpan spanA = SkSpan(graph.begin(), split);
229 SkSpan spanB = SkSpan(graph.begin() + split, n - split);
232 bool result = GrTTopoSort(spanA);
233 if (!result) {
234 ERRORF(reporter, "Topo sort on partial chain failed.");
235 return;
236 }
237 // Nothing outside of the processed span should have been output.
238 for (const auto& node : spanB) {
240 }
241 result = GrTTopoSort(spanB, split);
242 if (!result) {
243 ERRORF(reporter, "Topo sort on partial chain failed.");
244 return;
245 }
246 for (const auto& node : graph) {
247 REPORTER_ASSERT(reporter, node->check());
248 }
249 }
250 }
251}
static BlurTest tests[]
Definition BlurTest.cpp:84
reporter
bool GrTTopoSort(SkSpan< sk_sp< T > > graph, uint32_t offset=0)
Definition GrTTopoSort.h:92
#define SkASSERT(cond)
Definition SkAssert.h:116
#define DEF_TEST(name, reporter)
Definition Test.h:312
#define REPORTER_ASSERT(r, cond,...)
Definition Test.h:286
#define ERRORF(r,...)
Definition Test.h:293
static void create_graph1(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_graph5(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_graph4(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_simple_chain(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph, int n)
void(* CreateGraphPF)(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_graph6(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_graph0(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_graph3(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static void create_graph2(TArray< sk_sp< ToolUtils::TopoTestNode > > *graph)
static bool WasOutput(TopoTestNode *node)
Definition ToolUtils.h:218
static void AllocNodes(skia_private::TArray< sk_sp< ToolUtils::TopoTestNode > > *graph, int num)
Definition ToolUtils.h:229
static void Shuffle(SkSpan< sk_sp< TopoTestNode > > graph, SkRandom *rand)
Definition ToolUtils.h:247
int size() const
Definition SkTArray.h:416
GAsyncResult * result