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
8 #include "SkColorSpace.h"
9 #include "SkCommonFlagsConfig.h"
10 #include "Test.h"
11 #include <initializer_list>
12
13 using sk_gpu_test::GrContextFactory;
14
15 namespace {
16 // The code
17 // SkCommandLineFlags::StringArray FLAGS_config1 = make_string_array({"a", "b"})
18 // can be used to construct string array that one gets with command line flags.
19 // For example, the call above is equivalent of
20 // DEFINE_string(config1, "a b", "");
21 // in cases where the default command line flag value ("a b") is used.
22 // make_string_array can be used to construct StringArray strings that have spaces in
23 // them.
make_string_array(std::initializer_list<const char * > strings)24 SkCommandLineFlags::StringArray make_string_array(std::initializer_list<const char*> strings) {
25 SkTArray<SkString> array;
26 for (auto& s : strings) {
27 array.push_back(SkString(s));
28 }
29 return SkCommandLineFlags::StringArray(array);
30 }
31 }
DEF_TEST(ParseConfigs_Gpu,reporter)32 DEF_TEST(ParseConfigs_Gpu, reporter) {
33 // Parses a normal config and returns correct "tag".
34 // Simple GL config works
35 SkCommandLineFlags::StringArray config1 = make_string_array({"gl"});
36 SkCommandLineConfigArray configs;
37 ParseConfigs(config1, &configs);
38
39 REPORTER_ASSERT(reporter, configs.count() == 1);
40 REPORTER_ASSERT(reporter, configs[0]->getTag().equals("gl"));
41 REPORTER_ASSERT(reporter, configs[0]->getViaParts().count() == 0);
42 #if SK_SUPPORT_GPU
43 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu());
44 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getContextType()
45 == GrContextFactory::kGL_ContextType);
46 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getUseNVPR() == false);
47 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getUseDIText() == false);
48 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getSamples() == 1);
49 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getColorType() == kRGBA_8888_SkColorType);
50 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getColorSpace() == nullptr);
51 #endif
52 }
53
DEF_TEST(ParseConfigs_OutParam,reporter)54 DEF_TEST(ParseConfigs_OutParam, reporter) {
55 // Clears the out parameter.
56 SkCommandLineFlags::StringArray config1 = make_string_array({"gles"});
57 SkCommandLineConfigArray configs;
58 ParseConfigs(config1, &configs);
59 REPORTER_ASSERT(reporter, configs.count() == 1);
60 REPORTER_ASSERT(reporter, configs[0]->getTag().equals("gles"));
61
62 SkCommandLineFlags::StringArray config2 = make_string_array({"8888"});
63 ParseConfigs(config2, &configs);
64 REPORTER_ASSERT(reporter, configs.count() == 1);
65 REPORTER_ASSERT(reporter, configs[0]->getTag().equals("8888"));
66
67 SkCommandLineFlags::StringArray config3 = make_string_array({"gl"});
68 ParseConfigs(config3, &configs);
69 REPORTER_ASSERT(reporter, configs.count() == 1);
70 REPORTER_ASSERT(reporter, configs[0]->getTag().equals("gl"));
71 }
72
DEF_TEST(ParseConfigs_DefaultConfigs,reporter)73 DEF_TEST(ParseConfigs_DefaultConfigs, reporter) {
74 // Parses all default configs and returns correct "tag".
75
76 SkCommandLineFlags::StringArray config1 = make_string_array({
77 "565",
78 "8888",
79 "debuggl",
80 "gl",
81 "gldft",
82 "nullgl",
83 "glmsaa8",
84 "glmsaa4",
85 "nonrendering",
86 "nullgl",
87 "gles",
88 "glnvpr8",
89 "glnvpr4",
90 "pdf",
91 "skp",
92 "svg",
93 "xps",
94 "angle_d3d11_es2",
95 "angle_gl_es2",
96 "commandbuffer",
97 "mesa",
98 "hwui",
99 "glf16",
100 "glessrgb",
101 "gl",
102 "glnvpr4",
103 "glsrgb",
104 "glmsaa4",
105 "vk",
106 "glwide",
107 "glnarrow",
108 "glnostencils",
109 "mock",
110 "mtl",
111 "gl4444",
112 "gl565",
113 "gltestthreading",
114 "gl1010102",
115 });
116
117 SkCommandLineConfigArray configs;
118 ParseConfigs(config1, &configs);
119
120 auto srgbColorSpace = SkColorSpace::MakeSRGB();
121
122 REPORTER_ASSERT(reporter, configs.count() == config1.count());
123 for (int i = 0; i < config1.count(); ++i) {
124 REPORTER_ASSERT(reporter, configs[i]->getTag().equals(config1[i]));
125 REPORTER_ASSERT(reporter, configs[i]->getViaParts().count() == 0);
126 }
127 #if SK_SUPPORT_GPU
128 REPORTER_ASSERT(reporter, !configs[0]->asConfigGpu());
129 REPORTER_ASSERT(reporter, !configs[1]->asConfigGpu());
130 REPORTER_ASSERT(reporter, configs[2]->asConfigGpu());
131 REPORTER_ASSERT(reporter, configs[3]->asConfigGpu());
132 REPORTER_ASSERT(reporter, configs[4]->asConfigGpu()->getUseDIText());
133 REPORTER_ASSERT(reporter, configs[5]->asConfigGpu());
134 REPORTER_ASSERT(reporter, configs[6]->asConfigGpu()->getSamples() == 8);
135 REPORTER_ASSERT(reporter, configs[7]->asConfigGpu()->getSamples() == 4);
136 REPORTER_ASSERT(reporter, !configs[8]->asConfigGpu());
137 REPORTER_ASSERT(reporter, configs[9]->asConfigGpu());
138 REPORTER_ASSERT(reporter, configs[10]->asConfigGpu());
139 REPORTER_ASSERT(reporter, configs[11]->asConfigGpu()->getSamples() == 8);
140 REPORTER_ASSERT(reporter, configs[11]->asConfigGpu()->getUseNVPR());
141 REPORTER_ASSERT(reporter, !configs[11]->asConfigGpu()->getUseDIText());
142 REPORTER_ASSERT(reporter, configs[12]->asConfigGpu()->getSamples() == 4);
143 REPORTER_ASSERT(reporter, configs[12]->asConfigGpu()->getUseNVPR());
144 REPORTER_ASSERT(reporter, !configs[12]->asConfigGpu()->getUseDIText());
145 REPORTER_ASSERT(reporter, !configs[13]->asConfigGpu());
146 REPORTER_ASSERT(reporter, !configs[14]->asConfigGpu());
147 REPORTER_ASSERT(reporter, !configs[15]->asConfigGpu());
148 REPORTER_ASSERT(reporter, !configs[16]->asConfigGpu());
149 REPORTER_ASSERT(reporter, configs[17]->asConfigGpu());
150 REPORTER_ASSERT(reporter, configs[18]->asConfigGpu());
151 REPORTER_ASSERT(reporter, configs[19]->asConfigGpu());
152 REPORTER_ASSERT(reporter, !configs[20]->asConfigGpu());
153 REPORTER_ASSERT(reporter, !configs[21]->asConfigGpu());
154 REPORTER_ASSERT(reporter, configs[22]->asConfigGpu()->getColorType() == kRGBA_F16_SkColorType);
155 REPORTER_ASSERT(reporter, configs[22]->asConfigGpu()->getColorSpace());
156 REPORTER_ASSERT(reporter, configs[22]->asConfigGpu()->getColorSpace()->gammaIsLinear());
157 const SkMatrix44* srgbXYZ = srgbColorSpace->toXYZD50();
158 SkASSERT(srgbXYZ);
159 const SkMatrix44* config25XYZ = configs[22]->asConfigGpu()->getColorSpace()->toXYZD50();
160 SkASSERT(config25XYZ);
161 REPORTER_ASSERT(reporter, *config25XYZ == *srgbXYZ);
162 REPORTER_ASSERT(reporter, configs[23]->asConfigGpu()->getColorType() == kRGBA_8888_SkColorType);
163 REPORTER_ASSERT(reporter, configs[23]->asConfigGpu()->getColorSpace() == srgbColorSpace.get());
164 REPORTER_ASSERT(reporter, configs[24]->asConfigGpu());
165 REPORTER_ASSERT(reporter, configs[25]->asConfigGpu());
166 REPORTER_ASSERT(reporter, configs[25]->asConfigGpu()->getSamples() == 4);
167 REPORTER_ASSERT(reporter, configs[25]->asConfigGpu()->getUseNVPR());
168 REPORTER_ASSERT(reporter, configs[26]->asConfigGpu());
169 REPORTER_ASSERT(reporter, configs[26]->asConfigGpu()->getColorType() == kRGBA_8888_SkColorType);
170 REPORTER_ASSERT(reporter, configs[26]->asConfigGpu()->getColorSpace() == srgbColorSpace.get());
171 REPORTER_ASSERT(reporter, configs[27]->asConfigGpu());
172 REPORTER_ASSERT(reporter, configs[27]->asConfigGpu()->getSamples() == 4);
173 #ifdef SK_VULKAN
174 REPORTER_ASSERT(reporter, configs[28]->asConfigGpu());
175 #endif
176 REPORTER_ASSERT(reporter, configs[29]->asConfigGpu()->getColorType() == kRGBA_F16_SkColorType);
177 REPORTER_ASSERT(reporter, configs[29]->asConfigGpu()->getColorSpace());
178 REPORTER_ASSERT(reporter, configs[29]->asConfigGpu()->getColorSpace()->gammaIsLinear());
179 const SkMatrix44* config41XYZ = configs[29]->asConfigGpu()->getColorSpace()->toXYZD50();
180 SkASSERT(config41XYZ);
181 REPORTER_ASSERT(reporter, *config41XYZ != *srgbXYZ);
182 REPORTER_ASSERT(reporter, configs[30]->asConfigGpu()->getColorType() == kRGBA_F16_SkColorType);
183 REPORTER_ASSERT(reporter, configs[30]->asConfigGpu()->getColorSpace());
184 REPORTER_ASSERT(reporter, configs[30]->asConfigGpu()->getColorSpace()->gammaIsLinear());
185 REPORTER_ASSERT(reporter, *configs[30]->asConfigGpu()->getColorSpace()->toXYZD50() !=
186 *srgbColorSpace->toXYZD50());
187 REPORTER_ASSERT(reporter, configs[31]->asConfigGpu()->getContextType() ==
188 GrContextFactory::kGL_ContextType);
189 REPORTER_ASSERT(reporter, SkToBool(configs[31]->asConfigGpu()->getContextOverrides() &
190 SkCommandLineConfigGpu::ContextOverrides::kAvoidStencilBuffers));
191 REPORTER_ASSERT(reporter, configs[32]->asConfigGpu()->getContextType() ==
192 GrContextFactory::kMock_ContextType);
193
194 REPORTER_ASSERT(reporter, configs[34]->asConfigGpu()->getContextType() ==
195 GrContextFactory::kGL_ContextType);
196 REPORTER_ASSERT(reporter, configs[34]->asConfigGpu()->getColorType() == kARGB_4444_SkColorType);
197 REPORTER_ASSERT(reporter, configs[34]->asConfigGpu()->getAlphaType() == kPremul_SkAlphaType);
198 REPORTER_ASSERT(reporter, configs[35]->asConfigGpu()->getContextType() ==
199 GrContextFactory::kGL_ContextType);
200 REPORTER_ASSERT(reporter, configs[35]->asConfigGpu()->getColorType() == kRGB_565_SkColorType);
201 REPORTER_ASSERT(reporter, configs[35]->asConfigGpu()->getAlphaType() == kOpaque_SkAlphaType);
202 REPORTER_ASSERT(reporter, configs[36]->asConfigGpu());
203 REPORTER_ASSERT(reporter, configs[36]->asConfigGpu()->getTestThreading());
204 REPORTER_ASSERT(reporter, configs[37]->asConfigGpu());
205 REPORTER_ASSERT(reporter, configs[37]->asConfigGpu()->getColorType() ==
206 kRGBA_1010102_SkColorType);
207 #endif
208 }
209
DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect,reporter)210 DEF_TEST(ParseConfigs_ExtendedGpuConfigsCorrect, reporter) {
211 SkCommandLineFlags::StringArray config1 = make_string_array({
212 "gpu[api=gl,nvpr=true,dit=false]",
213 "gpu[api=angle_d3d9_es2]",
214 "gpu[api=angle_gl_es3]",
215 "gpu[api=mesa,samples=77]",
216 "gpu[dit=true,api=commandbuffer]",
217 "gpu[api=gles]",
218 "gpu[api=gl]",
219 "gpu[api=vulkan]",
220 "gpu[api=metal]",
221 "gpu[api=mock]",
222 });
223
224 SkCommandLineConfigArray configs;
225 ParseConfigs(config1, &configs);
226 REPORTER_ASSERT(reporter, configs.count() == config1.count());
227 for (int i = 0; i < config1.count(); ++i) {
228 REPORTER_ASSERT(reporter, configs[i]->getTag().equals(config1[i]));
229 }
230 #if SK_SUPPORT_GPU
231 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getContextType() ==
232 GrContextFactory::kGL_ContextType);
233 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getUseNVPR());
234 REPORTER_ASSERT(reporter, !configs[0]->asConfigGpu()->getUseDIText());
235 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu()->getSamples() == 1);
236 REPORTER_ASSERT(reporter, configs[1]->asConfigGpu()->getContextType() ==
237 GrContextFactory::kANGLE_D3D9_ES2_ContextType);
238 REPORTER_ASSERT(reporter, configs[1]->asConfigGpu());
239 REPORTER_ASSERT(reporter, configs[2]->asConfigGpu()->getContextType() ==
240 GrContextFactory::kANGLE_GL_ES3_ContextType);
241 REPORTER_ASSERT(reporter, configs[2]->asConfigGpu());
242 REPORTER_ASSERT(reporter, !configs[3]->asConfigGpu());
243 REPORTER_ASSERT(reporter, configs[4]->asConfigGpu()->getContextType() ==
244 GrContextFactory::kCommandBuffer_ContextType);
245 REPORTER_ASSERT(reporter, configs[5]->asConfigGpu()->getContextType() ==
246 GrContextFactory::kGLES_ContextType);
247 REPORTER_ASSERT(reporter, !configs[5]->asConfigGpu()->getUseNVPR());
248 REPORTER_ASSERT(reporter, !configs[5]->asConfigGpu()->getUseDIText());
249 REPORTER_ASSERT(reporter, configs[5]->asConfigGpu()->getSamples() == 1);
250 REPORTER_ASSERT(reporter, configs[6]->asConfigGpu()->getContextType() ==
251 GrContextFactory::kGL_ContextType);
252 REPORTER_ASSERT(reporter, !configs[6]->asConfigGpu()->getUseNVPR());
253 REPORTER_ASSERT(reporter, !configs[6]->asConfigGpu()->getUseDIText());
254 REPORTER_ASSERT(reporter, configs[6]->asConfigGpu()->getSamples() == 1);
255 #ifdef SK_VULKAN
256 REPORTER_ASSERT(reporter, configs[7]->asConfigGpu()->getContextType() ==
257 GrContextFactory::kVulkan_ContextType);
258 REPORTER_ASSERT(reporter, !configs[7]->asConfigGpu()->getUseNVPR());
259 REPORTER_ASSERT(reporter, !configs[7]->asConfigGpu()->getUseDIText());
260 REPORTER_ASSERT(reporter, configs[7]->asConfigGpu()->getSamples() == 1);
261 #endif
262 #ifdef SK_METAL
263 REPORTER_ASSERT(reporter, configs[8]->asConfigGpu()->getContextType() ==
264 GrContextFactory::kMetal_ContextType);
265 REPORTER_ASSERT(reporter, !configs[8]->asConfigGpu()->getUseNVPR());
266 REPORTER_ASSERT(reporter, !configs[8]->asConfigGpu()->getUseDIText());
267 REPORTER_ASSERT(reporter, configs[8]->asConfigGpu()->getSamples() == 0);
268 #endif
269 REPORTER_ASSERT(reporter, configs[9]->asConfigGpu()->getContextType() ==
270 GrContextFactory::kMock_ContextType);
271 #endif
272 }
273
DEF_TEST(ParseConfigs_ExtendedGpuConfigsIncorrect,reporter)274 DEF_TEST(ParseConfigs_ExtendedGpuConfigsIncorrect, reporter) {
275 SkCommandLineFlags::StringArray config1 = make_string_array({
276 "gpu[api=gl,nvpr=1]", // Number as bool.
277 "gpu[api=gl,]", // Trailing in comma.
278 "gpu[api=angle_glu]", // Unknown api.
279 "gpu[api=,samples=0]", // Empty api.
280 "gpu[api=gl,samples=true]", // Value true as a number.
281 "gpu[api=gl,samples=0,samples=0]", // Duplicate option key.
282 "gpu[,api=gl,samples=0]", // Leading comma.
283 "gpu[samples=54", // Missing closing parenthesis.
284 ",,",
285 "gpu[]", // Missing required api specifier
286 "gpu[samples=4]", // Missing required api specifier
287 "gpu[", // Missing bracket.
288 "samples=54" // No backend.
289 "gpu[nvpr=true ]", // Space.
290 });
291
292 SkCommandLineConfigArray configs;
293 ParseConfigs(config1, &configs);
294 REPORTER_ASSERT(reporter, configs.count() == config1.count());
295 for (int i = 0; i < config1.count(); ++i) {
296 REPORTER_ASSERT(reporter, configs[i]->getTag().equals(config1[i]));
297 REPORTER_ASSERT(reporter, configs[i]->getBackend().equals(config1[i]));
298 #if SK_SUPPORT_GPU
299 REPORTER_ASSERT(reporter, !configs[i]->asConfigGpu());
300 #endif
301 }
302 }
303
DEF_TEST(ParseConfigs_ExtendedGpuConfigsSurprises,reporter)304 DEF_TEST(ParseConfigs_ExtendedGpuConfigsSurprises, reporter) {
305 // These just list explicitly some properties of the system.
306 SkCommandLineFlags::StringArray config1 = make_string_array({
307 // Options are not canonized -> two same configs have a different tag.
308 "gpu[api=gl,nvpr=true,dit=true]", "gpu[api=gl,dit=true,nvpr=true]",
309 "gpu[api=debuggl]", "gpu[api=gl]", "gpu[api=gles]", ""
310 "gpu[api=gl]", "gpu[api=gl,samples=0]", "gpu[api=gles,samples=0]"
311 });
312 SkCommandLineConfigArray configs;
313 ParseConfigs(config1, &configs);
314 REPORTER_ASSERT(reporter, configs.count() == config1.count());
315 for (int i = 0; i < config1.count(); ++i) {
316 REPORTER_ASSERT(reporter, configs[i]->getTag().equals(config1[i]));
317 #if SK_SUPPORT_GPU
318 REPORTER_ASSERT(reporter, configs[i]->getBackend().equals("gpu"));
319 REPORTER_ASSERT(reporter, configs[i]->asConfigGpu());
320 #else
321 REPORTER_ASSERT(reporter, configs[i]->getBackend().equals(config1[i]));
322 #endif
323 }
324 }
325
326 #if SK_SUPPORT_GPU
DEF_TEST(ParseConfigs_ViaParsing,reporter)327 DEF_TEST(ParseConfigs_ViaParsing, reporter) {
328 SkCommandLineFlags::StringArray config1 = make_string_array({
329 "a-b-c-8888",
330 "zz-qq-gpu",
331 "a-angle_gl_es2"
332 });
333
334 SkCommandLineConfigArray configs;
335 ParseConfigs(config1, &configs);
336 const struct {
337 const char* backend;
338 const char* vias[3];
339 } expectedConfigs[] = {
340 {"8888", {"a", "b", "c"}},
341 {"gpu", {"zz", "qq", nullptr}},
342 {"gpu", { "a", nullptr, nullptr }}
343 };
344 for (int i = 0; i < config1.count(); ++i) {
345 REPORTER_ASSERT(reporter, configs[i]->getTag().equals(config1[i]));
346 REPORTER_ASSERT(reporter, configs[i]->getBackend().equals(expectedConfigs[i].backend));
347 for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(expectedConfigs[i].vias)); ++j) {
348 if (!expectedConfigs[i].vias[j]) {
349 REPORTER_ASSERT(reporter, configs[i]->getViaParts().count() == j);
350 break;
351 }
352 REPORTER_ASSERT(reporter,
353 configs[i]->getViaParts()[j].equals(expectedConfigs[i].vias[j]));
354 }
355 }
356 }
357 #endif
358
DEF_TEST(ParseConfigs_ViaParsingExtendedForm,reporter)359 DEF_TEST(ParseConfigs_ViaParsingExtendedForm, reporter) {
360 SkCommandLineFlags::StringArray config1 = make_string_array({
361 "zz-qq-gpu[api=gles]",
362 "abc-nbc-cbs-gpu[api=angle_d3d9_es2,samples=1]",
363 "a-gpu[api=gl",
364 "abc-def-angle_gl_es2[api=gles]",
365 });
366
367 SkCommandLineConfigArray configs;
368 ParseConfigs(config1, &configs);
369 const struct {
370 const char* backend;
371 const char* vias[3];
372 } expectedConfigs[] = {
373 #if SK_SUPPORT_GPU
374 {"gpu", {"zz", "qq", nullptr}},
375 {"gpu", {"abc", "nbc", "cbs"}},
376 #else
377 {"gpu[api=gles]", {"zz", "qq", nullptr}},
378 {"gpu[api=angle_d3d9_es2,samples=1]", {"abc", "nbc", "cbs"}},
379 #endif
380 {"gpu[api=gl", {"a", nullptr, nullptr}}, // Missing bracket makes this is not extended
381 // form but via still works as expected.
382 {"angle_gl_es2[api=gles]", {"abc", "def", nullptr}} // This is not extended form.
383 // angle_gl_es2 is an api type not a
384 // backend.
385 };
386 for (int i = 0; i < config1.count(); ++i) {
387 REPORTER_ASSERT(reporter, configs[i]->getTag().equals(config1[i]));
388 REPORTER_ASSERT(reporter, configs[i]->getBackend().equals(expectedConfigs[i].backend));
389 for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(expectedConfigs[i].vias)); ++j) {
390 if (!expectedConfigs[i].vias[j]) {
391 REPORTER_ASSERT(reporter, configs[i]->getViaParts().count() ==
392 static_cast<int>(j));
393 break;
394 }
395 REPORTER_ASSERT(reporter,
396 configs[i]->getViaParts()[j].equals(expectedConfigs[i].vias[j]));
397 }
398 }
399 #if SK_SUPPORT_GPU
400 REPORTER_ASSERT(reporter, configs[0]->asConfigGpu());
401 REPORTER_ASSERT(reporter, configs[1]->asConfigGpu());
402 REPORTER_ASSERT(reporter, !configs[2]->asConfigGpu());
403 REPORTER_ASSERT(reporter, !configs[3]->asConfigGpu());
404 #endif
405 }
406