Flutter Engine
The Flutter Engine
CommonFlagsConfig.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
9
15#include "src/core/SkTHash.h"
16
17#include <stdlib.h>
18#include <string_view>
19#include <unordered_map>
20
21using namespace skia_private;
23
24#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
25#define DEFAULT_GPU_CONFIG "gles"
26#else
27#define DEFAULT_GPU_CONFIG "gl"
28#endif
29
30static const char defaultConfigs[] = "8888 " DEFAULT_GPU_CONFIG
31 " nonrendering "
32#if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
33 " angle_d3d11_es2"
34#endif
35 ;
36
37#undef DEFAULT_GPU_CONFIG
38
39// clang-format off
40static const struct {
41 const char* predefinedConfig;
42 const char* backend;
43 const char* options;
45 { "gl", "gpu", "api=gl" },
46 { "glf16", "gpu", "api=gl,color=f16" },
47 { "glf16norm", "gpu", "api=gl,color=f16norm" },
48 { "glsrgba", "gpu", "api=gl,color=srgba" },
49 { "gl1010102", "gpu", "api=gl,color=1010102" },
50 { "gles", "gpu", "api=gles" },
51 { "glesf16", "gpu", "api=gles,color=f16" },
52 { "glessrgba", "gpu", "api=gles,color=srgba" },
53 { "gles1010102", "gpu", "api=gles,color=1010102" },
54 { "glesfakev2", "gpu", "api=glesfakev2" },
55 { "gldmsaa", "gpu", "api=gl,dmsaa=true" },
56 { "glesdmsaa", "gpu", "api=gles,dmsaa=true" },
57 { "glmsaa4", "gpu", "api=gl,samples=4" },
58 { "glmsaa8" , "gpu", "api=gl,samples=8" },
59 { "glesmsaa4", "gpu", "api=gles,samples=4" },
60 { "glbetex", "gpu", "api=gl,surf=betex" },
61 { "glesbetex", "gpu", "api=gles,surf=betex" },
62 { "glbert", "gpu", "api=gl,surf=bert" },
63 { "glesbert", "gpu", "api=gles,surf=bert" },
64 { "gl4444", "gpu", "api=gl,color=4444" },
65 { "gles4444", "gpu", "api=gles,color=4444" },
66 { "gl565", "gpu", "api=gl,color=565" },
67 { "gl888x", "gpu", "api=gl,color=888x" },
68 { "gles888x", "gpu", "api=gles,color=888x" },
69 { "glr8", "gpu", "api=gl,color=r8" },
70 { "glnostencils", "gpu", "api=gl,stencils=false" },
71 { "gldft", "gpu", "api=gl,dit=true" },
72 { "glesdft", "gpu", "api=gles,dit=true" },
73 { "glslug", "gpu", "api=gl,slug=true" },
74 { "glserializeslug", "gpu", "api=gl,serializeSlug=true" },
75 { "glremoteslug", "gpu", "api=gl,remoteSlug=true" },
76 { "gltestpersistentcache", "gpu", "api=gl,testPersistentCache=1" },
77 { "gltestglslcache", "gpu", "api=gl,testPersistentCache=2" },
78 { "gltestprecompile", "gpu", "api=gl,testPrecompile=true" },
79 { "glestestprecompile", "gpu", "api=gles,testPrecompile=true" },
80 { "glddl", "gpu", "api=gl,useDDLSink=true" },
81 { "glreducedshaders", "gpu", "api=gl,reducedShaders=true" },
82 { "glesreducedshaders", "gpu", "api=gles,reducedShaders=true" },
83 { "angle_d3d11_es2", "gpu", "api=angle_d3d11_es2" },
84 { "angle_d3d11_es3", "gpu", "api=angle_d3d11_es3" },
85 { "angle_d3d9_es2", "gpu", "api=angle_d3d9_es2" },
86 { "angle_d3d11_es2_msaa4", "gpu", "api=angle_d3d11_es2,samples=4" },
87 { "angle_d3d11_es2_msaa8", "gpu", "api=angle_d3d11_es2,samples=8" },
88 { "angle_d3d11_es2_dmsaa", "gpu", "api=angle_d3d11_es2,dmsaa=true" },
89 { "angle_d3d11_es3_msaa4", "gpu", "api=angle_d3d11_es3,samples=4" },
90 { "angle_d3d11_es3_msaa8", "gpu", "api=angle_d3d11_es3,samples=8" },
91 { "angle_d3d11_es3_dmsaa", "gpu", "api=angle_d3d11_es3,dmsaa=true" },
92 { "angle_gl_es2", "gpu", "api=angle_gl_es2" },
93 { "angle_gl_es3", "gpu", "api=angle_gl_es3" },
94 { "angle_gl_es2_msaa4", "gpu", "api=angle_gl_es2,samples=4" },
95 { "angle_gl_es2_msaa8", "gpu", "api=angle_gl_es2,samples=8" },
96 { "angle_gl_es2_dmsaa", "gpu", "api=angle_gl_es2,dmsaa=true" },
97 { "angle_gl_es3_msaa4", "gpu", "api=angle_gl_es3,samples=4" },
98 { "angle_gl_es3_msaa8", "gpu", "api=angle_gl_es3,samples=8" },
99 { "angle_gl_es3_dmsaa", "gpu", "api=angle_gl_es3,dmsaa=true" },
100 { "angle_mtl_es2", "gpu", "api=angle_mtl_es2" },
101 { "angle_mtl_es3", "gpu", "api=angle_mtl_es3" },
102 { "mock", "gpu", "api=mock" },
103#ifdef SK_VULKAN
104 { "vk", "gpu", "api=vulkan" },
105 { "vkf16", "gpu", "api=vulkan,color=f16" },
106 { "vk1010102", "gpu", "api=vulkan,color=1010102" },
107 { "vkdmsaa", "gpu", "api=vulkan,dmsaa=true" },
108 { "vknostencils", "gpu", "api=vulkan,stencils=false" },
109 { "vkmsaa4", "gpu", "api=vulkan,samples=4" },
110 { "vkmsaa8", "gpu", "api=vulkan,samples=8" },
111 { "vkbetex", "gpu", "api=vulkan,surf=betex" },
112 { "vkbert", "gpu", "api=vulkan,surf=bert" },
113 { "vktestpersistentcache", "gpu", "api=vulkan,testPersistentCache=1" },
114 { "vkddl", "gpu", "api=vulkan,useDDLSink=true" },
115#endif
116#ifdef SK_METAL
117 { "mtl", "gpu", "api=metal" },
118 { "mtlf16", "gpu", "api=metal,color=f16" },
119 { "mtlf16norm", "gpu", "api=metal,color=f16norm" },
120 { "mtlsrgba", "gpu", "api=metal,color=srgba"},
121 { "mtl1010102", "gpu", "api=metal,color=1010102" },
122 { "mtl_dmsaa", "gpu", "api=metal,dmsaa=true" },
123 { "mtlmsaa4", "gpu", "api=metal,samples=4" },
124 { "mtlmsaa8", "gpu", "api=metal,samples=8" },
125 { "mtlddl", "gpu", "api=metal,useDDLSink=true" },
126 { "mtltestprecompile", "gpu", "api=metal,testPrecompile=true" },
127 { "mtlreducedshaders", "gpu", "api=metal,reducedShaders=true" },
128#endif
129#ifdef SK_DIRECT3D
130 { "d3d", "gpu", "api=direct3d" },
131 { "d3dmsaa4", "gpu", "api=direct3d,samples=4" },
132 { "d3dmsaa8", "gpu", "api=direct3d,samples=8" },
133#endif
134
135#if defined(SK_GRAPHITE)
136#ifdef SK_DIRECT3D
137 { "grd3d", "graphite", "api=direct3d" },
138#endif
139#ifdef SK_DAWN
140 { "grdawn_fakeWGPU", "graphite", "api=dawn_mtl,fakeWGPU=true" },
141 { "grdawn_d3d11", "graphite", "api=dawn_d3d11" },
142 { "grdawn_d3d12", "graphite", "api=dawn_d3d12" },
143 { "grdawn_mtl", "graphite", "api=dawn_mtl" },
144 { "grdawn_vk", "graphite", "api=dawn_vk" },
145 { "grdawn_gl", "graphite", "api=dawn_gl" },
146 { "grdawn_gles", "graphite", "api=dawn_gles" },
147#if defined(SK_ENABLE_PRECOMPILE)
148 { "grdawn_mtlprecompile", "graphite", "api=dawn_mtl,precompile=true" },
149 { "grdawn_vkprecompile", "graphite", "api=dawn_vk, precompile=true" },
150#endif
151#endif
152#ifdef SK_METAL
153 { "grmtl", "graphite", "api=metal" },
154 { "grmtlf16", "graphite", "api=metal,color=f16" },
155 { "grmtlf16norm", "graphite", "api=metal,color=f16norm" },
156 { "grmtlsrgba", "graphite", "api=metal,color=srgba"},
157 { "grmtl1010102", "graphite", "api=metal,color=1010102" },
158#if defined(SK_ENABLE_PRECOMPILE)
159 { "grmtlprecompile", "graphite", "api=metal,precompile=true" },
160 { "grmtlprecompilef16", "graphite", "api=metal,precompile=true,color=f16" },
161 { "grmtlprecompile1010102","graphite", "api=metal,precompile=true,color=1010102" },
162#endif
163#endif
164#ifdef SK_VULKAN
165 { "grvk", "graphite", "api=vulkan" },
166#if defined(SK_ENABLE_PRECOMPILE)
167 { "grvkprecompile", "graphite", "api=vulkan,precompile=true" },
168#endif
169#endif
170#endif
171
173// clang-format on
174
175static const char configHelp[] =
176 "Options: 565 4444 8888 rgba bgra rgbx 1010102 101010x bgra1010102 bgr101010x f16 f16norm "
177 "f32 nonrendering null pdf pdfa pdf300 skp svg xps";
178
179static const char* config_help_fn() {
180 static SkString helpString;
181 helpString.set(configHelp);
182 for (const auto& config : gPredefinedConfigs) {
183 helpString.appendf(" %s", config.predefinedConfig);
184 }
185 helpString.append(" or use extended form 'backend[option=value,...]'.\n");
186 return helpString.c_str();
187}
188
189static const char configExtendedHelp[] =
190 "Extended form: 'backend(option=value,...)'\n\n"
191 "Possible backends and options:\n"
192 "\n"
193 "gpu[api=string,color=string,dit=bool,dmsaa=bool,samples=int]\n"
194 "\tapi\ttype: string\trequired\n"
195 "\t Select graphics API to use with gpu backend.\n"
196 "\t Options:\n"
197 "\t\tgl \t\t\tUse OpenGL.\n"
198 "\t\tgles \t\t\tUse OpenGL ES.\n"
199 "\t\tglesfakev2 \t\t\tUse OpenGL ES with version faked as 2.0.\n"
200 "\t\tnullgl \t\t\tUse null OpenGL.\n"
201 "\t\tangle_d3d9_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D9 backend.\n"
202 "\t\tangle_d3d11_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D11 backend.\n"
203 "\t\tangle_d3d11_es3\t\tUse OpenGL ES3 on the ANGLE Direct3D11 backend.\n"
204 "\t\tangle_gl_es2\t\tUse OpenGL ES2 on the ANGLE OpenGL backend.\n"
205 "\t\tangle_gl_es3\t\tUse OpenGL ES3 on the ANGLE OpenGL backend.\n"
206 "\t\tmock\t\t\tUse mock context.\n"
207#ifdef SK_VULKAN
208 "\t\tvulkan\t\t\tUse Vulkan.\n"
209#endif
210#ifdef SK_METAL
211 "\t\tmetal\t\t\tUse Metal.\n"
212#endif
213 "\tcolor\ttype: string\tdefault: 8888.\n"
214 "\t Select framebuffer color format.\n"
215 "\t Options:\n"
216 "\t\t8888\t\t\tLinear 8888.\n"
217 "\t\t888x\t\t\tLinear 888x.\n"
218 "\t\t4444\t\t\tLinear 4444.\n"
219 "\t\t565\t\t\tLinear 565.\n"
220 "\t\t1010102\t\t\tLinear 1010102.\n"
221 "\t\tf16\t\t\t16-bit floating point.\n"
222 "\tdit\ttype: bool\tdefault: false.\n"
223 "\t Use device independent text.\n"
224 "\tdmsaa\ttype: bool\tdefault: false.\n"
225 "\t Use internal MSAA to render to non-MSAA surfaces.\n"
226 "\tsamples\ttype: int\tdefault: 0.\n"
227 "\t Use multisampling with N samples.\n"
228 "\tstencils\ttype: bool\tdefault: true.\n"
229 "\t Allow the use of stencil buffers.\n"
230 "\t Run with and without worker threads, check that results match.\n"
231 "\ttestPersistentCache\ttype: int\tdefault: 0.\n"
232 "\t 1: Run using a pre-warmed binary GrContextOptions::fPersistentCache.\n"
233 "\t 2: Run using a pre-warmed GLSL GrContextOptions::fPersistentCache.\n"
234 "\tsurf\ttype: string\tdefault: default.\n"
235 "\t Controls the type of backing store for SkSurfaces.\n"
236 "\t Options:\n"
237 "\t\tdefault\t\t\tA renderable texture created in Skia's resource cache.\n"
238 "\t\tbetex\t\t\tA wrapped backend texture.\n"
239 "\t\tbert\t\t\tA wrapped backend render target\n"
240 "\n"
241 "Predefined configs:\n\n"
242 // Help text for pre-defined configs is auto-generated from gPredefinedConfigs
243 ;
244
245static const char* config_extended_help_fn() {
246 static SkString helpString;
247 helpString.set(configExtendedHelp);
248 for (const auto& config : gPredefinedConfigs) {
249 helpString.appendf("\t%-10s\t= gpu(%s)\n", config.predefinedConfig, config.options);
250 }
251 return helpString.c_str();
252}
253
255
257 const SkString& backend,
258 const TArray<SkString>& viaParts)
259 : fTag(tag), fBackend(backend) {
260 static const auto* kColorSpaces = new std::unordered_map<std::string_view, SkColorSpace*>{
261 {"narrow", // 'narrow' has a gamut narrower than sRGB, and different transfer function.
263 {"srgb",
265 {"srgb2", // The same as "srgb" but works around ignoring prior images in Gold
267 {"linear",
269 {"p3",
271 {"spin",
273 {"rec2020",
275 };
276
277 // Strip off any via parts that refer to color spaces (and remember the last one we see)
278 for (const SkString& via : viaParts) {
279 auto it = kColorSpaces->find(via.c_str());
280 if (it == kColorSpaces->end()) {
281 fViaParts.push_back(via);
282 } else {
283 fColorSpace = sk_ref_sp(it->second);
284 }
285 }
286}
287
289
290static bool parse_option_int(const SkString& value, int* outInt) {
291 if (value.isEmpty()) {
292 return false;
293 }
294 char* endptr = nullptr;
295 long intValue = strtol(value.c_str(), &endptr, 10);
296 if (*endptr != '\0') {
297 return false;
298 }
299 *outInt = static_cast<int>(intValue);
300 return true;
301}
302static bool parse_option_bool(const SkString& value, bool* outBool) {
303 if (value.equals("true")) {
304 *outBool = true;
305 return true;
306 }
307 if (value.equals("false")) {
308 *outBool = false;
309 return true;
310 }
311 return false;
312}
315 bool* outFakeGLESVersion2) {
316 *outFakeGLESVersion2 = false;
317 if (value.equals("gl")) {
318 *outContextType = skgpu::ContextType::kGL;
319 return true;
320 }
321 if (value.equals("gles")) {
322 *outContextType = skgpu::ContextType::kGLES;
323 return true;
324 }
325 if (value.equals("glesfakev2")) {
326 *outContextType = skgpu::ContextType::kGLES;
327 *outFakeGLESVersion2 = true;
328 return true;
329 }
330 if (value.equals("angle_d3d9_es2")) {
331 *outContextType = skgpu::ContextType::kANGLE_D3D9_ES2;
332 return true;
333 }
334 if (value.equals("angle_d3d11_es2")) {
335 *outContextType = skgpu::ContextType::kANGLE_D3D11_ES2;
336 return true;
337 }
338 if (value.equals("angle_d3d11_es3")) {
339 *outContextType = skgpu::ContextType::kANGLE_D3D11_ES3;
340 return true;
341 }
342 if (value.equals("angle_gl_es2")) {
343 *outContextType = skgpu::ContextType::kANGLE_GL_ES2;
344 return true;
345 }
346 if (value.equals("angle_gl_es3")) {
347 *outContextType = skgpu::ContextType::kANGLE_GL_ES3;
348 return true;
349 }
350 if (value.equals("angle_mtl_es2")) {
351 *outContextType = skgpu::ContextType::kANGLE_Metal_ES2;
352 return true;
353 }
354 if (value.equals("angle_mtl_es3")) {
355 *outContextType = skgpu::ContextType::kANGLE_Metal_ES3;
356 return true;
357 }
358 if (value.equals("mock")) {
359 *outContextType = skgpu::ContextType::kMock;
360 return true;
361 }
362#ifdef SK_VULKAN
363 if (value.equals("vulkan")) {
364 *outContextType = skgpu::ContextType::kVulkan;
365 return true;
366 }
367#endif
368#ifdef SK_METAL
369 if (value.equals("metal")) {
370 *outContextType = skgpu::ContextType::kMetal;
371 return true;
372 }
373#endif
374#ifdef SK_DIRECT3D
375 if (value.equals("direct3d")) {
376 *outContextType = skgpu::ContextType::kDirect3D;
377 return true;
378 }
379#endif
380 return false;
381}
382
384 SkColorType* outColorType,
385 SkAlphaType* alphaType) {
386 // We always use premul unless the color type is 565.
387 *alphaType = kPremul_SkAlphaType;
388
389 if (value.equals("8888")) {
390 *outColorType = kRGBA_8888_SkColorType;
391 } else if (value.equals("888x")) {
392 *outColorType = kRGB_888x_SkColorType;
393 } else if (value.equals("bgra8")) {
394 *outColorType = kBGRA_8888_SkColorType;
395 } else if (value.equals("4444")) {
396 *outColorType = kARGB_4444_SkColorType;
397 } else if (value.equals("565")) {
398 *outColorType = kRGB_565_SkColorType;
399 *alphaType = kOpaque_SkAlphaType;
400 } else if (value.equals("1010102")) {
401 *outColorType = kRGBA_1010102_SkColorType;
402 } else if (value.equals("f16")) {
403 *outColorType = kRGBA_F16_SkColorType;
404 } else if (value.equals("f16norm")) {
405 *outColorType = kRGBA_F16Norm_SkColorType;
406 } else if (value.equals("srgba")) {
407 *outColorType = kSRGBA_8888_SkColorType;
408 } else if (value.equals("r8")) {
409 *outColorType = kR8_unorm_SkColorType;
410 *alphaType = kOpaque_SkAlphaType;
411 } else {
412 return false;
413 }
414 return true;
415}
416
419 if (value.equals("default")) {
421 return true;
422 }
423 if (value.equals("betex")) {
425 return true;
426 }
427 if (value.equals("bert")) {
429 return true;
430 }
431 return false;
432}
433
434// Extended options take form --config item[key1=value1,key2=value2,...]
435// Example: --config gpu[api=gl,color=8888]
437public:
438 ExtendedOptions(const SkString& optionsString, bool* outParseSucceeded) {
439 TArray<SkString> optionParts;
440 SkStrSplit(optionsString.c_str(), ",", kStrict_SkStrSplitMode, &optionParts);
441 for (int i = 0; i < optionParts.size(); ++i) {
442 TArray<SkString> keyValueParts;
443 SkStrSplit(optionParts[i].c_str(), "=", kStrict_SkStrSplitMode, &keyValueParts);
444 if (keyValueParts.size() != 2) {
445 *outParseSucceeded = false;
446 return;
447 }
448 const SkString& key = keyValueParts[0];
449 const SkString& value = keyValueParts[1];
450 if (fOptionsMap.find(key) == nullptr) {
451 fOptionsMap.set(key, value);
452 } else {
453 // Duplicate values are not allowed.
454 *outParseSucceeded = false;
455 return;
456 }
457 }
458 *outParseSucceeded = true;
459 }
460
461 bool get_option_gpu_color(const char* optionKey,
462 SkColorType* outColorType,
463 SkAlphaType* alphaType,
464 bool optional = true) const {
465 SkString* optionValue = fOptionsMap.find(SkString(optionKey));
466 if (optionValue == nullptr) {
467 return optional;
468 }
469 return parse_option_gpu_color(*optionValue, outColorType, alphaType);
470 }
471
472 bool get_option_gpu_api(const char* optionKey,
474 bool* outFakeGLESVersion2,
475 bool optional = true) const {
476 SkString* optionValue = fOptionsMap.find(SkString(optionKey));
477 if (optionValue == nullptr) {
478 return optional;
479 }
480 return parse_option_gpu_api(*optionValue, outContextType, outFakeGLESVersion2);
481 }
482
483#if defined(SK_GRAPHITE)
484 bool get_option_graphite_api(const char* optionKey,
485 SkCommandLineConfigGraphite::ContextType* outContextType) const {
486 SkString* optionValue = fOptionsMap.find(SkString(optionKey));
487 if (optionValue == nullptr) {
488 return false;
489 }
490#ifdef SK_DAWN
491 if (optionValue->equals("dawn_d3d11")) {
492 *outContextType = skgpu::ContextType::kDawn_D3D11;
493 return true;
494 }
495 if (optionValue->equals("dawn_d3d12")) {
496 *outContextType = skgpu::ContextType::kDawn_D3D12;
497 return true;
498 }
499 if (optionValue->equals("dawn_mtl")) {
500 *outContextType = skgpu::ContextType::kDawn_Metal;
501 return true;
502 }
503 if (optionValue->equals("dawn_vk")) {
504 *outContextType = skgpu::ContextType::kDawn_Vulkan;
505 return true;
506 }
507 if (optionValue->equals("dawn_gl")) {
508 *outContextType = skgpu::ContextType::kDawn_OpenGL;
509 return true;
510 }
511 if (optionValue->equals("dawn_gles")) {
512 *outContextType = skgpu::ContextType::kDawn_OpenGLES;
513 return true;
514 }
515#endif
516#ifdef SK_DIRECT3D
517 if (optionValue->equals("direct3d")) {
518 *outContextType = skgpu::ContextType::kDirect3D;
519 return true;
520 }
521#endif
522#ifdef SK_METAL
523 if (optionValue->equals("metal")) {
524 *outContextType = skgpu::ContextType::kMetal;
525 return true;
526 }
527#endif
528#ifdef SK_VULKAN
529 if (optionValue->equals("vulkan")) {
530 *outContextType = skgpu::ContextType::kVulkan;
531 return true;
532 }
533#endif
534
535 return false;
536 }
537#endif
538
539 bool get_option_gpu_surf_type(const char* optionKey,
541 bool optional = true) const {
542 SkString* optionValue = fOptionsMap.find(SkString(optionKey));
543 if (optionValue == nullptr) {
544 return optional;
545 }
546 return parse_option_gpu_surf_type(*optionValue, outSurfType);
547 }
548
549 bool get_option_int(const char* optionKey, int* outInt, bool optional = true) const {
550 SkString* optionValue = fOptionsMap.find(SkString(optionKey));
551 if (optionValue == nullptr) {
552 return optional;
553 }
554 return parse_option_int(*optionValue, outInt);
555 }
556
557 bool get_option_bool(const char* optionKey, bool* outBool, bool optional = true) const {
558 SkString* optionValue = fOptionsMap.find(SkString(optionKey));
559 if (optionValue == nullptr) {
560 return optional;
561 }
562 return parse_option_bool(*optionValue, outBool);
563 }
564
565private:
567};
568
570 const TArray<SkString>& viaParts,
571 ContextType contextType,
572 bool fakeGLESVersion2,
573 uint32_t surfaceFlags,
574 int samples,
576 SkAlphaType alphaType,
577 bool useStencilBuffers,
578 int testPersistentCache,
579 bool testPrecompile,
580 bool useDDLSink,
581 bool slug,
582 bool serializeSlug,
583 bool remoteSlug,
584 bool reducedShaders,
585 SurfType surfType)
586 : SkCommandLineConfig(tag, SkString("gpu"), viaParts)
587 , fContextType(contextType)
588 , fContextOverrides(ContextOverrides::kNone)
589 , fSurfaceFlags(surfaceFlags)
590 , fSamples(samples)
592 , fAlphaType(alphaType)
593 , fTestPersistentCache(testPersistentCache)
594 , fTestPrecompile(testPrecompile)
595 , fUseDDLSink(useDDLSink)
596 , fSlug(slug)
597 , fSerializeSlug(serializeSlug)
598 , fRemoteSlug(remoteSlug)
599 , fReducedShaders(reducedShaders)
600 , fSurfType(surfType) {
601 if (!useStencilBuffers) {
602 fContextOverrides |= ContextOverrides::kAvoidStencilBuffers;
603 }
604 if (fakeGLESVersion2) {
605 fContextOverrides |= ContextOverrides::kFakeGLESVersionAs2;
606 }
607 if (reducedShaders) {
608 fContextOverrides |= ContextOverrides::kReducedShaders;
609 }
610}
611
613 const TArray<SkString>& vias,
614 const SkString& options) {
615 // Defaults for GPU backend.
617 bool useDIText = false;
618 bool useDMSAA = false;
619 int samples = 1;
622 bool useStencils = true;
623 int testPersistentCache = 0;
624 bool testPrecompile = false;
625 bool useDDLs = false;
626 bool slug = false;
627 bool serializeSlug = false;
628 bool remoteSlug = false;
629 bool reducedShaders = false;
630 bool fakeGLESVersion2 = false;
632
633 bool parseSucceeded = false;
634 ExtendedOptions extendedOptions(options, &parseSucceeded);
635 if (!parseSucceeded) {
636 return nullptr;
637 }
638
639 bool validOptions =
640 extendedOptions.get_option_gpu_api("api", &contextType, &fakeGLESVersion2, false) &&
641 extendedOptions.get_option_bool("dit", &useDIText) &&
642 extendedOptions.get_option_int("samples", &samples) &&
643 extendedOptions.get_option_bool("dmsaa", &useDMSAA) &&
644 extendedOptions.get_option_gpu_color("color", &colorType, &alphaType) &&
645 extendedOptions.get_option_bool("stencils", &useStencils) &&
646 extendedOptions.get_option_int("testPersistentCache", &testPersistentCache) &&
647 extendedOptions.get_option_bool("testPrecompile", &testPrecompile) &&
648 extendedOptions.get_option_bool("useDDLSink", &useDDLs) &&
649 extendedOptions.get_option_bool("slug", &slug) &&
650 extendedOptions.get_option_bool("serializeSlug", &serializeSlug) &&
651 extendedOptions.get_option_bool("remoteSlug", &remoteSlug) &&
652 extendedOptions.get_option_bool("reducedShaders", &reducedShaders) &&
653 extendedOptions.get_option_gpu_surf_type("surf", &surfType);
654
655 if (!validOptions) {
656 return nullptr;
657 }
658
659 uint32_t surfaceFlags = 0;
660 if (useDIText) {
662 }
663 if (useDMSAA) {
664 surfaceFlags |= SkSurfaceProps::kDynamicMSAA_Flag;
665 }
666
667 return new SkCommandLineConfigGpu(tag,
668 vias,
669 contextType,
670 fakeGLESVersion2,
671 surfaceFlags,
672 samples,
673 colorType,
674 alphaType,
675 useStencils,
676 testPersistentCache,
677 testPrecompile,
678 useDDLs,
679 slug,
680 serializeSlug,
681 remoteSlug,
682 reducedShaders,
683 surfType);
684}
685
686#if defined(SK_GRAPHITE)
687
688SkCommandLineConfigGraphite* parse_command_line_config_graphite(const SkString& tag,
689 const TArray<SkString>& vias,
690 const SkString& options) {
692
696 bool testPrecompile = false;
697
699
700 bool parseSucceeded = false;
701 ExtendedOptions extendedOptions(options, &parseSucceeded);
702 if (!parseSucceeded) {
703 return nullptr;
704 }
705
706 bool fakeWGPU = false;
707 bool validOptions = extendedOptions.get_option_graphite_api("api", &contextType) &&
708 extendedOptions.get_option_gpu_color("color", &colorType, &alphaType) &&
709 extendedOptions.get_option_bool("fakeWGPU", &fakeWGPU) &&
710 extendedOptions.get_option_bool("precompile", &testPrecompile);
711 if (!validOptions) {
712 return nullptr;
713 }
714
716 if (fakeWGPU) {
717 testOptions.fNeverYieldToWebGPU = true;
718 surfaceType = SkCommandLineConfigGraphite::SurfaceType::kWrapTextureView;
719 }
720
721 return new SkCommandLineConfigGraphite(tag,
722 vias,
723 contextType,
724 surfaceType,
725 testOptions,
726 colorType,
727 alphaType,
728 testPrecompile);
729}
730
731#endif
732
734 const TArray<SkString>& viaParts,
735 int pageIndex)
736 : SkCommandLineConfig(tag, SkString("svg"), viaParts), fPageIndex(pageIndex) {}
737
739 const TArray<SkString>& vias,
740 const SkString& options) {
741 // Defaults for SVG backend.
742 int pageIndex = 0;
743
744 bool parseSucceeded = false;
745 ExtendedOptions extendedOptions(options, &parseSucceeded);
746 if (!parseSucceeded) {
747 return nullptr;
748 }
749
750 bool validOptions = extendedOptions.get_option_int("page", &pageIndex);
751
752 if (!validOptions) {
753 return nullptr;
754 }
755
756 return new SkCommandLineConfigSvg(tag, vias, pageIndex);
757}
758
760 SkCommandLineConfigArray* outResult) {
761 outResult->clear();
762 for (int i = 0; i < configs.size(); ++i) {
763 SkString extendedBackend;
764 SkString extendedOptions;
765 SkString simpleBackend;
766 TArray<SkString> vias;
767
768 SkString tag(configs[i]);
771 if (parts.size() == 2) {
772 TArray<SkString> parts2;
773 SkStrSplit(parts[1].c_str(), "]", kStrict_SkStrSplitMode, &parts2);
774 if (parts2.size() == 2 && parts2[1].isEmpty()) {
775 SkStrSplit(parts[0].c_str(), "-", kStrict_SkStrSplitMode, &vias);
776 if (vias.size()) {
777 extendedBackend = vias[vias.size() - 1];
778 vias.pop_back();
779 } else {
780 extendedBackend = parts[0];
781 }
782 extendedOptions = parts2[0];
783 simpleBackend.printf("%s[%s]", extendedBackend.c_str(), extendedOptions.c_str());
784 }
785 }
786
787 if (extendedBackend.isEmpty()) {
788 simpleBackend = tag;
789 SkStrSplit(tag.c_str(), "-", kStrict_SkStrSplitMode, &vias);
790 if (vias.size()) {
791 simpleBackend = vias[vias.size() - 1];
792 vias.pop_back();
793 }
795 if (simpleBackend.equals(predefinedConfig.predefinedConfig)) {
796 extendedBackend = predefinedConfig.backend;
797 extendedOptions = predefinedConfig.options;
798 break;
799 }
800 }
801 }
802 SkCommandLineConfig* parsedConfig = nullptr;
803 if (extendedBackend.equals("gpu")) {
804 parsedConfig = parse_command_line_config_gpu(tag, vias, extendedOptions);
805 }
806#if defined(SK_GRAPHITE)
807 if (extendedBackend.equals("graphite")) {
808 parsedConfig = parse_command_line_config_graphite(tag, vias, extendedOptions);
809 }
810#endif
811 if (extendedBackend.equals("svg")) {
812 parsedConfig = parse_command_line_config_svg(tag, vias, extendedOptions);
813 }
814 if (!parsedConfig) {
815 parsedConfig = new SkCommandLineConfig(tag, simpleBackend, vias);
816 }
817 outResult->emplace_back(parsedConfig);
818 }
819}
const char * options
static bool parse_option_gpu_color(const SkString &value, SkColorType *outColorType, SkAlphaType *alphaType)
SkCommandLineConfigGpu * parse_command_line_config_gpu(const SkString &tag, const TArray< SkString > &vias, const SkString &options)
static bool parse_option_bool(const SkString &value, bool *outBool)
static const char defaultConfigs[]
static const char * config_extended_help_fn()
const char * predefinedConfig
static const char * config_help_fn()
SkCommandLineConfigSvg * parse_command_line_config_svg(const SkString &tag, const TArray< SkString > &vias, const SkString &options)
void ParseConfigs(const CommandLineFlags::StringArray &configs, SkCommandLineConfigArray *outResult)
static const struct @440 gPredefinedConfigs[]
const char * backend
static const char configHelp[]
DEFINE_extended_string(config, defaultConfigs, config_help_fn(), config_extended_help_fn())
static const char configExtendedHelp[]
static bool parse_option_gpu_api(const SkString &value, SkCommandLineConfigGpu::ContextType *outContextType, bool *outFakeGLESVersion2)
static bool parse_option_gpu_surf_type(const SkString &value, SkCommandLineConfigGpu::SurfType *surfType)
static bool parse_option_int(const SkString &value, int *outInt)
#define DEFAULT_GPU_CONFIG
sk_gpu_test::GrContextFactory::ContextType ContextType
SkColorType fColorType
SkAlphaType fAlphaType
SkAlphaType
Definition: SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
static constexpr skcms_Matrix3x3 gNarrow_toXYZD50
SkColorType
Definition: SkColorType.h:19
@ kR8_unorm_SkColorType
Definition: SkColorType.h:54
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition: SkColorType.h:23
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kSRGBA_8888_SkColorType
Definition: SkColorType.h:53
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:25
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:27
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition: SkColorType.h:36
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
void SkStrSplit(const char *str, const char *delimiters, SkStrSplitMode splitMode, TArray< SkString > *out)
@ kStrict_SkStrSplitMode
Definition: SkStringUtils.h:47
bool get_option_gpu_color(const char *optionKey, SkColorType *outColorType, SkAlphaType *alphaType, bool optional=true) const
bool get_option_gpu_surf_type(const char *optionKey, SkCommandLineConfigGpu::SurfType *outSurfType, bool optional=true) const
bool get_option_gpu_api(const char *optionKey, SkCommandLineConfigGpu::ContextType *outContextType, bool *outFakeGLESVersion2, bool optional=true) const
bool get_option_int(const char *optionKey, int *outInt, bool optional=true) const
ExtendedOptions(const SkString &optionsString, bool *outParseSucceeded)
bool get_option_bool(const char *optionKey, bool *outBool, bool optional=true) const
static sk_sp< SkColorSpace > MakeSRGB()
sk_sp< SkColorSpace > makeColorSpin() const
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
static sk_sp< SkColorSpace > MakeSRGBLinear()
SkCommandLineConfigGpu(const SkString &tag, const skia_private::TArray< SkString > &viaParts, ContextType contextType, bool fakeGLESVer2, uint32_t surfaceFlags, int samples, SkColorType colorType, SkAlphaType alphaType, bool useStencilBuffers, int testPersistentCache, bool testPrecompile, bool useDDLSink, bool slug, bool serializedSlug, bool remoteSlug, bool reducedShaders, SurfType)
SkCommandLineConfigSvg(const SkString &tag, const skia_private::TArray< SkString > &viaParts, int pageIndex)
SkCommandLineConfig(const SkString &tag, const SkString &backend, const skia_private::TArray< SkString > &viaParts)
void printf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:534
void set(const SkString &src)
Definition: SkString.h:186
bool equals(const SkString &) const
Definition: SkString.cpp:324
bool isEmpty() const
Definition: SkString.h:130
void append(const char text[])
Definition: SkString.h:203
const char * c_str() const
Definition: SkString.h:133
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:550
@ kUseDeviceIndependentFonts_Flag
T * release()
Definition: SkRefCnt.h:324
int size() const
Definition: SkTArray.h:421
T & emplace_back(Args &&... args)
Definition: SkTArray.h:248
V * find(const K &key) const
Definition: SkTHash.h:494
V * set(K key, V val)
Definition: SkTHash.h:487
@ kDefault
uint8_t value
static constexpr skcms_Matrix3x3 kRec2020
Definition: SkColorSpace.h:93
static constexpr skcms_Matrix3x3 kDisplayP3
Definition: SkColorSpace.h:87
static constexpr skcms_TransferFunction kRec2020
Definition: SkColorSpace.h:54
static constexpr skcms_TransferFunction k2Dot2
Definition: SkColorSpace.h:48
static constexpr skcms_TransferFunction kSRGB
Definition: SkColorSpace.h:45
@ kNone
Definition: layer.h:53
ContextType
Definition: ContextType.h:19
@ kDawn_OpenGLES
Dawn on OpenGL.
@ kDawn_Metal
Dawn on Direct3D12.
@ kGLES
OpenGL context.
@ kANGLE_GL_ES2
ANGLE on Direct3D11 OpenGL ES 3 context.
@ kDawn_D3D12
Dawn on Direct3D11.
@ kANGLE_GL_ES3
ANGLE on OpenGL OpenGL ES 2 context.
@ kANGLE_D3D11_ES2
ANGLE on Direct3D9 OpenGL ES 2 context.
@ kDawn_Vulkan
Dawn on Metal.
@ kVulkan
ANGLE on Metal ES 3 context.
@ kDawn_OpenGL
Dawn on Vulkan.
@ kDawn_D3D11
Direct3D 12.
@ kANGLE_D3D11_ES3
ANGLE on Direct3D11 OpenGL ES 2 context.
@ kANGLE_D3D9_ES2
OpenGL ES context.
@ kANGLE_Metal_ES2
ANGLE on OpenGL OpenGL ES 3 context.
@ kANGLE_Metal_ES3
ANGLE on Metal ES 2 context.
@ kMock
Dawn on OpenGL ES.