1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "tools/flags/CommonFlagsConfig.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h"
11cb93a386Sopenharmony_ci#include "include/core/SkStringView.h"
12cb93a386Sopenharmony_ci#include "include/core/SkSurfaceProps.h"
13cb93a386Sopenharmony_ci#include "include/private/SkTHash.h"
14cb93a386Sopenharmony_ci#include "src/core/SkColorSpacePriv.h"
15cb93a386Sopenharmony_ci#include "src/core/SkSurfacePriv.h"
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_ci#include <stdlib.h>
18cb93a386Sopenharmony_ci#include <unordered_map>
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_ciusing sk_gpu_test::GrContextFactory;
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS)
23cb93a386Sopenharmony_ci#define DEFAULT_GPU_CONFIG "gles"
24cb93a386Sopenharmony_ci#else
25cb93a386Sopenharmony_ci#define DEFAULT_GPU_CONFIG "gl"
26cb93a386Sopenharmony_ci#endif
27cb93a386Sopenharmony_ci
28cb93a386Sopenharmony_cistatic const char defaultConfigs[] = "8888 " DEFAULT_GPU_CONFIG
29cb93a386Sopenharmony_ci                                     " nonrendering "
30cb93a386Sopenharmony_ci#if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
31cb93a386Sopenharmony_ci                                     " angle_d3d11_es2"
32cb93a386Sopenharmony_ci#endif
33cb93a386Sopenharmony_ci        ;
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci#undef DEFAULT_GPU_CONFIG
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_ci// clang-format off
38cb93a386Sopenharmony_cistatic const struct {
39cb93a386Sopenharmony_ci    const char* predefinedConfig;
40cb93a386Sopenharmony_ci    const char* backend;
41cb93a386Sopenharmony_ci    const char* options;
42cb93a386Sopenharmony_ci} gPredefinedConfigs[] = {
43cb93a386Sopenharmony_ci    { "gl",                    "gpu", "api=gl" },
44cb93a386Sopenharmony_ci    { "gles",                  "gpu", "api=gles" },
45cb93a386Sopenharmony_ci    { "glesfakev2",            "gpu", "api=glesfakev2" },
46cb93a386Sopenharmony_ci    { "gldmsaa",               "gpu", "api=gl,dmsaa=true" },
47cb93a386Sopenharmony_ci    { "glesdmsaa",             "gpu", "api=gles,dmsaa=true" },
48cb93a386Sopenharmony_ci    { "glmsaa4",               "gpu", "api=gl,samples=4" },
49cb93a386Sopenharmony_ci    { "glmsaa8" ,              "gpu", "api=gl,samples=8" },
50cb93a386Sopenharmony_ci    { "glesmsaa4",             "gpu", "api=gles,samples=4" },
51cb93a386Sopenharmony_ci    { "glbetex",               "gpu", "api=gl,surf=betex" },
52cb93a386Sopenharmony_ci    { "glesbetex",             "gpu", "api=gles,surf=betex" },
53cb93a386Sopenharmony_ci    { "glbert",                "gpu", "api=gl,surf=bert" },
54cb93a386Sopenharmony_ci    { "glesbert",              "gpu", "api=gles,surf=bert" },
55cb93a386Sopenharmony_ci    { "gl4444",                "gpu", "api=gl,color=4444" },
56cb93a386Sopenharmony_ci    { "gles4444",              "gpu", "api=gles,color=4444" },
57cb93a386Sopenharmony_ci    { "gl565",                 "gpu", "api=gl,color=565" },
58cb93a386Sopenharmony_ci    { "gl888x",                "gpu", "api=gl,color=888x" },
59cb93a386Sopenharmony_ci    { "gles888x",              "gpu", "api=gles,color=888x" },
60cb93a386Sopenharmony_ci    { "gl1010102",             "gpu", "api=gl,color=1010102" },
61cb93a386Sopenharmony_ci    { "gles1010102",           "gpu", "api=gles,color=1010102" },
62cb93a386Sopenharmony_ci    { "glf16",                 "gpu", "api=gl,color=f16" },
63cb93a386Sopenharmony_ci    { "glf16norm",             "gpu", "api=gl,color=f16norm" },
64cb93a386Sopenharmony_ci    { "glsrgba",               "gpu", "api=gl,color=srgba" },
65cb93a386Sopenharmony_ci    { "glesf16",               "gpu", "api=gles,color=f16" },
66cb93a386Sopenharmony_ci    { "glessrgba",             "gpu", "api=gles,color=srgba" },
67cb93a386Sopenharmony_ci    { "glnostencils",          "gpu", "api=gl,stencils=false" },
68cb93a386Sopenharmony_ci    { "gldft",                 "gpu", "api=gl,dit=true" },
69cb93a386Sopenharmony_ci    { "glesdft",               "gpu", "api=gles,dit=true" },
70cb93a386Sopenharmony_ci    { "gltestthreading",       "gpu", "api=gl,testThreading=true" },
71cb93a386Sopenharmony_ci    { "gltestpersistentcache", "gpu", "api=gl,testPersistentCache=1" },
72cb93a386Sopenharmony_ci    { "gltestglslcache",       "gpu", "api=gl,testPersistentCache=2" },
73cb93a386Sopenharmony_ci    { "gltestprecompile",      "gpu", "api=gl,testPrecompile=true" },
74cb93a386Sopenharmony_ci    { "glestestprecompile",    "gpu", "api=gles,testPrecompile=true" },
75cb93a386Sopenharmony_ci    { "glddl",                 "gpu", "api=gl,useDDLSink=true" },
76cb93a386Sopenharmony_ci    { "glooprddl",             "gpu", "api=gl,OOPRish=true" },
77cb93a386Sopenharmony_ci    { "glreducedshaders",      "gpu", "api=gl,reducedShaders=true" },
78cb93a386Sopenharmony_ci    { "glesreducedshaders",    "gpu", "api=gles,reducedShaders=true" },
79cb93a386Sopenharmony_ci    { "angle_d3d11_es2",       "gpu", "api=angle_d3d11_es2" },
80cb93a386Sopenharmony_ci    { "angle_d3d11_es3",       "gpu", "api=angle_d3d11_es3" },
81cb93a386Sopenharmony_ci    { "angle_d3d9_es2",        "gpu", "api=angle_d3d9_es2" },
82cb93a386Sopenharmony_ci    { "angle_d3d11_es2_msaa4", "gpu", "api=angle_d3d11_es2,samples=4" },
83cb93a386Sopenharmony_ci    { "angle_d3d11_es2_msaa8", "gpu", "api=angle_d3d11_es2,samples=8" },
84cb93a386Sopenharmony_ci    { "angle_d3d11_es2_dmsaa", "gpu", "api=angle_d3d11_es2,dmsaa=true" },
85cb93a386Sopenharmony_ci    { "angle_d3d11_es3_msaa4", "gpu", "api=angle_d3d11_es3,samples=4" },
86cb93a386Sopenharmony_ci    { "angle_d3d11_es3_msaa8", "gpu", "api=angle_d3d11_es3,samples=8" },
87cb93a386Sopenharmony_ci    { "angle_d3d11_es3_dmsaa", "gpu", "api=angle_d3d11_es3,dmsaa=true" },
88cb93a386Sopenharmony_ci    { "angle_gl_es2",          "gpu", "api=angle_gl_es2" },
89cb93a386Sopenharmony_ci    { "angle_gl_es3",          "gpu", "api=angle_gl_es3" },
90cb93a386Sopenharmony_ci    { "angle_gl_es2_msaa4",    "gpu", "api=angle_gl_es2,samples=4" },
91cb93a386Sopenharmony_ci    { "angle_gl_es2_msaa8",    "gpu", "api=angle_gl_es2,samples=8" },
92cb93a386Sopenharmony_ci    { "angle_gl_es2_dmsaa",    "gpu", "api=angle_gl_es2,dmsaa=true" },
93cb93a386Sopenharmony_ci    { "angle_gl_es3_msaa4",    "gpu", "api=angle_gl_es3,samples=4" },
94cb93a386Sopenharmony_ci    { "angle_gl_es3_msaa8",    "gpu", "api=angle_gl_es3,samples=8" },
95cb93a386Sopenharmony_ci    { "angle_gl_es3_dmsaa",    "gpu", "api=angle_gl_es3,dmsaa=true" },
96cb93a386Sopenharmony_ci    { "cmdbuffer_es2",         "gpu", "api=cmdbuffer_es2" },
97cb93a386Sopenharmony_ci    { "cmdbuffer_es2_dmsaa",   "gpu", "api=cmdbuffer_es2,dmsaa=true" },
98cb93a386Sopenharmony_ci    { "cmdbuffer_es3",         "gpu", "api=cmdbuffer_es3" },
99cb93a386Sopenharmony_ci    { "mock",                  "gpu", "api=mock" },
100cb93a386Sopenharmony_ci#ifdef SK_DAWN
101cb93a386Sopenharmony_ci    { "dawn",                  "gpu", "api=dawn" },
102cb93a386Sopenharmony_ci#endif
103cb93a386Sopenharmony_ci#ifdef SK_VULKAN
104cb93a386Sopenharmony_ci    { "vk",                    "gpu", "api=vulkan" },
105cb93a386Sopenharmony_ci    { "vkdmsaa",               "gpu", "api=vulkan,dmsaa=true" },
106cb93a386Sopenharmony_ci    { "vknostencils",          "gpu", "api=vulkan,stencils=false" },
107cb93a386Sopenharmony_ci    { "vk1010102",             "gpu", "api=vulkan,color=1010102" },
108cb93a386Sopenharmony_ci    { "vkf16",                 "gpu", "api=vulkan,color=f16" },
109cb93a386Sopenharmony_ci    { "vkmsaa4",               "gpu", "api=vulkan,samples=4" },
110cb93a386Sopenharmony_ci    { "vkmsaa8",               "gpu", "api=vulkan,samples=8" },
111cb93a386Sopenharmony_ci    { "vkbetex",               "gpu", "api=vulkan,surf=betex" },
112cb93a386Sopenharmony_ci    { "vkbert",                "gpu", "api=vulkan,surf=bert" },
113cb93a386Sopenharmony_ci    { "vktestpersistentcache", "gpu", "api=vulkan,testPersistentCache=1" },
114cb93a386Sopenharmony_ci    { "vkddl",                 "gpu", "api=vulkan,useDDLSink=true" },
115cb93a386Sopenharmony_ci    { "vkooprddl",             "gpu", "api=vulkan,OOPRish=true" },
116cb93a386Sopenharmony_ci#endif
117cb93a386Sopenharmony_ci#ifdef SK_METAL
118cb93a386Sopenharmony_ci    { "mtl",                   "gpu", "api=metal" },
119cb93a386Sopenharmony_ci    { "mtl1010102",            "gpu", "api=metal,color=1010102" },
120cb93a386Sopenharmony_ci    { "mtlmsaa4",              "gpu", "api=metal,samples=4" },
121cb93a386Sopenharmony_ci    { "mtlmsaa8",              "gpu", "api=metal,samples=8" },
122cb93a386Sopenharmony_ci    { "mtlddl",                "gpu", "api=metal,useDDLSink=true" },
123cb93a386Sopenharmony_ci    { "mtlooprddl",            "gpu", "api=metal,OOPRish=true" },
124cb93a386Sopenharmony_ci    { "mtltestprecompile",     "gpu", "api=metal,testPrecompile=true" },
125cb93a386Sopenharmony_ci    { "mtlreducedshaders",     "gpu", "api=metal,reducedShaders=true" },
126cb93a386Sopenharmony_ci#endif
127cb93a386Sopenharmony_ci#ifdef SK_DIRECT3D
128cb93a386Sopenharmony_ci    { "d3d",                   "gpu", "api=direct3d" },
129cb93a386Sopenharmony_ci    { "d3dmsaa4",              "gpu", "api=direct3d,samples=4" },
130cb93a386Sopenharmony_ci    { "d3dmsaa8",              "gpu", "api=direct3d,samples=8" },
131cb93a386Sopenharmony_ci#endif
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ci#ifdef SK_GRAPHITE_ENABLED
134cb93a386Sopenharmony_ci#ifdef SK_DIRECT3D
135cb93a386Sopenharmony_ci    { "grd3d",                 "graphite", "api=direct3d" },
136cb93a386Sopenharmony_ci#endif
137cb93a386Sopenharmony_ci#ifdef SK_METAL
138cb93a386Sopenharmony_ci    { "grmtl",                 "graphite", "api=metal,testPrecompile=true" },
139cb93a386Sopenharmony_ci#endif
140cb93a386Sopenharmony_ci#ifdef SK_VULKAN
141cb93a386Sopenharmony_ci    { "grvk",                  "graphite", "api=vulkan" },
142cb93a386Sopenharmony_ci#endif
143cb93a386Sopenharmony_ci#endif
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci};
146cb93a386Sopenharmony_ci// clang-format on
147cb93a386Sopenharmony_ci
148cb93a386Sopenharmony_cistatic const char configHelp[] =
149cb93a386Sopenharmony_ci        "Options: 565 4444 8888 rgba bgra rgbx 1010102 101010x bgra1010102 bgr101010x f16 f16norm "
150cb93a386Sopenharmony_ci        "f32 nonrendering null pdf pdfa pdf300 skp svg xps";
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_cistatic const char* config_help_fn() {
153cb93a386Sopenharmony_ci    static SkString helpString;
154cb93a386Sopenharmony_ci    helpString.set(configHelp);
155cb93a386Sopenharmony_ci    for (const auto& config : gPredefinedConfigs) {
156cb93a386Sopenharmony_ci        helpString.appendf(" %s", config.predefinedConfig);
157cb93a386Sopenharmony_ci    }
158cb93a386Sopenharmony_ci    helpString.append(" or use extended form 'backend[option=value,...]'.\n");
159cb93a386Sopenharmony_ci    return helpString.c_str();
160cb93a386Sopenharmony_ci}
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_cistatic const char configExtendedHelp[] =
163cb93a386Sopenharmony_ci        "Extended form: 'backend(option=value,...)'\n\n"
164cb93a386Sopenharmony_ci        "Possible backends and options:\n"
165cb93a386Sopenharmony_ci        "\n"
166cb93a386Sopenharmony_ci        "gpu[api=string,color=string,dit=bool,dmsaa=bool,samples=int]\n"
167cb93a386Sopenharmony_ci        "\tapi\ttype: string\trequired\n"
168cb93a386Sopenharmony_ci        "\t    Select graphics API to use with gpu backend.\n"
169cb93a386Sopenharmony_ci        "\t    Options:\n"
170cb93a386Sopenharmony_ci        "\t\tgl    \t\t\tUse OpenGL.\n"
171cb93a386Sopenharmony_ci        "\t\tgles  \t\t\tUse OpenGL ES.\n"
172cb93a386Sopenharmony_ci        "\t\tglesfakev2  \t\t\tUse OpenGL ES with version faked as 2.0.\n"
173cb93a386Sopenharmony_ci        "\t\tnullgl \t\t\tUse null OpenGL.\n"
174cb93a386Sopenharmony_ci        "\t\tangle_d3d9_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D9 backend.\n"
175cb93a386Sopenharmony_ci        "\t\tangle_d3d11_es2\t\tUse OpenGL ES2 on the ANGLE Direct3D11 backend.\n"
176cb93a386Sopenharmony_ci        "\t\tangle_d3d11_es3\t\tUse OpenGL ES3 on the ANGLE Direct3D11 backend.\n"
177cb93a386Sopenharmony_ci        "\t\tangle_gl_es2\t\tUse OpenGL ES2 on the ANGLE OpenGL backend.\n"
178cb93a386Sopenharmony_ci        "\t\tangle_gl_es3\t\tUse OpenGL ES3 on the ANGLE OpenGL backend.\n"
179cb93a386Sopenharmony_ci        "\t\tcommandbuffer\t\tUse command buffer.\n"
180cb93a386Sopenharmony_ci        "\t\tmock\t\t\tUse mock context.\n"
181cb93a386Sopenharmony_ci#ifdef SK_VULKAN
182cb93a386Sopenharmony_ci        "\t\tvulkan\t\t\tUse Vulkan.\n"
183cb93a386Sopenharmony_ci#endif
184cb93a386Sopenharmony_ci#ifdef SK_METAL
185cb93a386Sopenharmony_ci        "\t\tmetal\t\t\tUse Metal.\n"
186cb93a386Sopenharmony_ci#endif
187cb93a386Sopenharmony_ci        "\tcolor\ttype: string\tdefault: 8888.\n"
188cb93a386Sopenharmony_ci        "\t    Select framebuffer color format.\n"
189cb93a386Sopenharmony_ci        "\t    Options:\n"
190cb93a386Sopenharmony_ci        "\t\t8888\t\t\tLinear 8888.\n"
191cb93a386Sopenharmony_ci        "\t\t888x\t\t\tLinear 888x.\n"
192cb93a386Sopenharmony_ci        "\t\t4444\t\t\tLinear 4444.\n"
193cb93a386Sopenharmony_ci        "\t\t565\t\t\tLinear 565.\n"
194cb93a386Sopenharmony_ci        "\t\t1010102\t\t\tLinear 1010102.\n"
195cb93a386Sopenharmony_ci        "\t\tf16\t\t\t16-bit floating point.\n"
196cb93a386Sopenharmony_ci        "\tdit\ttype: bool\tdefault: false.\n"
197cb93a386Sopenharmony_ci        "\t    Use device independent text.\n"
198cb93a386Sopenharmony_ci        "\tdmsaa\ttype: bool\tdefault: false.\n"
199cb93a386Sopenharmony_ci        "\t    Use internal MSAA to render to non-MSAA surfaces.\n"
200cb93a386Sopenharmony_ci        "\tsamples\ttype: int\tdefault: 0.\n"
201cb93a386Sopenharmony_ci        "\t    Use multisampling with N samples.\n"
202cb93a386Sopenharmony_ci        "\tstencils\ttype: bool\tdefault: true.\n"
203cb93a386Sopenharmony_ci        "\t    Allow the use of stencil buffers.\n"
204cb93a386Sopenharmony_ci        "\ttestThreading\ttype: bool\tdefault: false.\n"
205cb93a386Sopenharmony_ci        "\t    Run with and without worker threads, check that results match.\n"
206cb93a386Sopenharmony_ci        "\ttestPersistentCache\ttype: int\tdefault: 0.\n"
207cb93a386Sopenharmony_ci        "\t    1: Run using a pre-warmed binary GrContextOptions::fPersistentCache.\n"
208cb93a386Sopenharmony_ci        "\t    2: Run using a pre-warmed GLSL GrContextOptions::fPersistentCache.\n"
209cb93a386Sopenharmony_ci        "\tsurf\ttype: string\tdefault: default.\n"
210cb93a386Sopenharmony_ci        "\t    Controls the type of backing store for SkSurfaces.\n"
211cb93a386Sopenharmony_ci        "\t    Options:\n"
212cb93a386Sopenharmony_ci        "\t\tdefault\t\t\tA renderable texture created in Skia's resource cache.\n"
213cb93a386Sopenharmony_ci        "\t\tbetex\t\t\tA wrapped backend texture.\n"
214cb93a386Sopenharmony_ci        "\t\tbert\t\t\tA wrapped backend render target\n"
215cb93a386Sopenharmony_ci        "\n"
216cb93a386Sopenharmony_ci        "Predefined configs:\n\n"
217cb93a386Sopenharmony_ci        // Help text for pre-defined configs is auto-generated from gPredefinedConfigs
218cb93a386Sopenharmony_ci        ;
219cb93a386Sopenharmony_ci
220cb93a386Sopenharmony_cistatic const char* config_extended_help_fn() {
221cb93a386Sopenharmony_ci    static SkString helpString;
222cb93a386Sopenharmony_ci    helpString.set(configExtendedHelp);
223cb93a386Sopenharmony_ci    for (const auto& config : gPredefinedConfigs) {
224cb93a386Sopenharmony_ci        helpString.appendf("\t%-10s\t= gpu(%s)\n", config.predefinedConfig, config.options);
225cb93a386Sopenharmony_ci    }
226cb93a386Sopenharmony_ci    return helpString.c_str();
227cb93a386Sopenharmony_ci}
228cb93a386Sopenharmony_ci
229cb93a386Sopenharmony_ciDEFINE_extended_string(config, defaultConfigs, config_help_fn(), config_extended_help_fn());
230cb93a386Sopenharmony_ci
231cb93a386Sopenharmony_ciSkCommandLineConfig::SkCommandLineConfig(const SkString& tag,
232cb93a386Sopenharmony_ci                                         const SkString& backend,
233cb93a386Sopenharmony_ci                                         const SkTArray<SkString>& viaParts)
234cb93a386Sopenharmony_ci        : fTag(tag), fBackend(backend) {
235cb93a386Sopenharmony_ci
236cb93a386Sopenharmony_ci    static std::unordered_map<skstd::string_view, sk_sp<SkColorSpace>> kColorSpaces = {
237cb93a386Sopenharmony_ci        // 'narrow' has a gamut narrower than sRGB, and different transfer function.
238cb93a386Sopenharmony_ci        { "narrow",  SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, gNarrow_toXYZD50) },
239cb93a386Sopenharmony_ci        { "srgb",    SkColorSpace::MakeSRGB() },
240cb93a386Sopenharmony_ci        { "linear",  SkColorSpace::MakeSRGBLinear() },
241cb93a386Sopenharmony_ci        { "p3",      SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDisplayP3) },
242cb93a386Sopenharmony_ci        { "spin",    SkColorSpace::MakeSRGB()->makeColorSpin() },
243cb93a386Sopenharmony_ci        { "rec2020", SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020) },
244cb93a386Sopenharmony_ci    };
245cb93a386Sopenharmony_ci
246cb93a386Sopenharmony_ci    // Strip off any via parts that refer to color spaces (and remember the last one we see)
247cb93a386Sopenharmony_ci    for (const SkString& via : viaParts) {
248cb93a386Sopenharmony_ci        auto it = kColorSpaces.find(via.c_str());
249cb93a386Sopenharmony_ci        if (it == kColorSpaces.end()) {
250cb93a386Sopenharmony_ci            fViaParts.push_back(via);
251cb93a386Sopenharmony_ci        } else {
252cb93a386Sopenharmony_ci            fColorSpace = it->second;
253cb93a386Sopenharmony_ci        }
254cb93a386Sopenharmony_ci    }
255cb93a386Sopenharmony_ci}
256cb93a386Sopenharmony_ci
257cb93a386Sopenharmony_ciSkCommandLineConfig::~SkCommandLineConfig() {}
258cb93a386Sopenharmony_ci
259cb93a386Sopenharmony_cistatic bool parse_option_int(const SkString& value, int* outInt) {
260cb93a386Sopenharmony_ci    if (value.isEmpty()) {
261cb93a386Sopenharmony_ci        return false;
262cb93a386Sopenharmony_ci    }
263cb93a386Sopenharmony_ci    char* endptr   = nullptr;
264cb93a386Sopenharmony_ci    long  intValue = strtol(value.c_str(), &endptr, 10);
265cb93a386Sopenharmony_ci    if (*endptr != '\0') {
266cb93a386Sopenharmony_ci        return false;
267cb93a386Sopenharmony_ci    }
268cb93a386Sopenharmony_ci    *outInt = static_cast<int>(intValue);
269cb93a386Sopenharmony_ci    return true;
270cb93a386Sopenharmony_ci}
271cb93a386Sopenharmony_cistatic bool parse_option_bool(const SkString& value, bool* outBool) {
272cb93a386Sopenharmony_ci    if (value.equals("true")) {
273cb93a386Sopenharmony_ci        *outBool = true;
274cb93a386Sopenharmony_ci        return true;
275cb93a386Sopenharmony_ci    }
276cb93a386Sopenharmony_ci    if (value.equals("false")) {
277cb93a386Sopenharmony_ci        *outBool = false;
278cb93a386Sopenharmony_ci        return true;
279cb93a386Sopenharmony_ci    }
280cb93a386Sopenharmony_ci    return false;
281cb93a386Sopenharmony_ci}
282cb93a386Sopenharmony_cistatic bool parse_option_gpu_api(const SkString&                      value,
283cb93a386Sopenharmony_ci                                 SkCommandLineConfigGpu::ContextType* outContextType,
284cb93a386Sopenharmony_ci                                 bool*                                outFakeGLESVersion2) {
285cb93a386Sopenharmony_ci    *outFakeGLESVersion2 = false;
286cb93a386Sopenharmony_ci    if (value.equals("gl")) {
287cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kGL_ContextType;
288cb93a386Sopenharmony_ci        return true;
289cb93a386Sopenharmony_ci    }
290cb93a386Sopenharmony_ci    if (value.equals("gles")) {
291cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kGLES_ContextType;
292cb93a386Sopenharmony_ci        return true;
293cb93a386Sopenharmony_ci    }
294cb93a386Sopenharmony_ci    if (value.equals("glesfakev2")) {
295cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kGLES_ContextType;
296cb93a386Sopenharmony_ci        *outFakeGLESVersion2 = true;
297cb93a386Sopenharmony_ci        return true;
298cb93a386Sopenharmony_ci    }
299cb93a386Sopenharmony_ci    if (value.equals("angle_d3d9_es2")) {
300cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kANGLE_D3D9_ES2_ContextType;
301cb93a386Sopenharmony_ci        return true;
302cb93a386Sopenharmony_ci    }
303cb93a386Sopenharmony_ci    if (value.equals("angle_d3d11_es2")) {
304cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kANGLE_D3D11_ES2_ContextType;
305cb93a386Sopenharmony_ci        return true;
306cb93a386Sopenharmony_ci    }
307cb93a386Sopenharmony_ci    if (value.equals("angle_d3d11_es3")) {
308cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kANGLE_D3D11_ES3_ContextType;
309cb93a386Sopenharmony_ci        return true;
310cb93a386Sopenharmony_ci    }
311cb93a386Sopenharmony_ci    if (value.equals("angle_gl_es2")) {
312cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kANGLE_GL_ES2_ContextType;
313cb93a386Sopenharmony_ci        return true;
314cb93a386Sopenharmony_ci    }
315cb93a386Sopenharmony_ci    if (value.equals("angle_gl_es3")) {
316cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kANGLE_GL_ES3_ContextType;
317cb93a386Sopenharmony_ci        return true;
318cb93a386Sopenharmony_ci    }
319cb93a386Sopenharmony_ci    if (value.equals("cmdbuffer_es2")) {
320cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kCommandBuffer_ES2_ContextType;
321cb93a386Sopenharmony_ci        return true;
322cb93a386Sopenharmony_ci    }
323cb93a386Sopenharmony_ci    if (value.equals("cmdbuffer_es3")) {
324cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kCommandBuffer_ES3_ContextType;
325cb93a386Sopenharmony_ci        return true;
326cb93a386Sopenharmony_ci    }
327cb93a386Sopenharmony_ci    if (value.equals("mock")) {
328cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kMock_ContextType;
329cb93a386Sopenharmony_ci        return true;
330cb93a386Sopenharmony_ci    }
331cb93a386Sopenharmony_ci#ifdef SK_VULKAN
332cb93a386Sopenharmony_ci    if (value.equals("vulkan")) {
333cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kVulkan_ContextType;
334cb93a386Sopenharmony_ci        return true;
335cb93a386Sopenharmony_ci    }
336cb93a386Sopenharmony_ci#endif
337cb93a386Sopenharmony_ci#ifdef SK_METAL
338cb93a386Sopenharmony_ci    if (value.equals("metal")) {
339cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kMetal_ContextType;
340cb93a386Sopenharmony_ci        return true;
341cb93a386Sopenharmony_ci    }
342cb93a386Sopenharmony_ci#endif
343cb93a386Sopenharmony_ci#ifdef SK_DIRECT3D
344cb93a386Sopenharmony_ci    if (value.equals("direct3d")) {
345cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kDirect3D_ContextType;
346cb93a386Sopenharmony_ci        return true;
347cb93a386Sopenharmony_ci    }
348cb93a386Sopenharmony_ci#endif
349cb93a386Sopenharmony_ci#ifdef SK_DAWN
350cb93a386Sopenharmony_ci    if (value.equals("dawn")) {
351cb93a386Sopenharmony_ci        *outContextType = GrContextFactory::kDawn_ContextType;
352cb93a386Sopenharmony_ci        return true;
353cb93a386Sopenharmony_ci    }
354cb93a386Sopenharmony_ci#endif
355cb93a386Sopenharmony_ci    return false;
356cb93a386Sopenharmony_ci}
357cb93a386Sopenharmony_ci
358cb93a386Sopenharmony_cistatic bool parse_option_gpu_color(const SkString& value,
359cb93a386Sopenharmony_ci                                   SkColorType*    outColorType,
360cb93a386Sopenharmony_ci                                   SkAlphaType*    alphaType) {
361cb93a386Sopenharmony_ci    // We always use premul unless the color type is 565.
362cb93a386Sopenharmony_ci    *alphaType = kPremul_SkAlphaType;
363cb93a386Sopenharmony_ci
364cb93a386Sopenharmony_ci    if (value.equals("8888")) {
365cb93a386Sopenharmony_ci        *outColorType  = kRGBA_8888_SkColorType;
366cb93a386Sopenharmony_ci    } else if (value.equals("888x")) {
367cb93a386Sopenharmony_ci        *outColorType  = kRGB_888x_SkColorType;
368cb93a386Sopenharmony_ci    } else if (value.equals("bgra8")) {
369cb93a386Sopenharmony_ci        *outColorType  = kBGRA_8888_SkColorType;
370cb93a386Sopenharmony_ci    } else if (value.equals("4444")) {
371cb93a386Sopenharmony_ci        *outColorType  = kARGB_4444_SkColorType;
372cb93a386Sopenharmony_ci    } else if (value.equals("565")) {
373cb93a386Sopenharmony_ci        *outColorType  = kRGB_565_SkColorType;
374cb93a386Sopenharmony_ci        *alphaType     = kOpaque_SkAlphaType;
375cb93a386Sopenharmony_ci    } else if (value.equals("1010102")) {
376cb93a386Sopenharmony_ci        *outColorType  = kRGBA_1010102_SkColorType;
377cb93a386Sopenharmony_ci    } else if (value.equals("f16")) {
378cb93a386Sopenharmony_ci        *outColorType  = kRGBA_F16_SkColorType;
379cb93a386Sopenharmony_ci    } else if (value.equals("f16norm")) {
380cb93a386Sopenharmony_ci        *outColorType  = kRGBA_F16Norm_SkColorType;
381cb93a386Sopenharmony_ci    } else if (value.equals("srgba")) {
382cb93a386Sopenharmony_ci        *outColorType = kSRGBA_8888_SkColorType;
383cb93a386Sopenharmony_ci    } else {
384cb93a386Sopenharmony_ci        return false;
385cb93a386Sopenharmony_ci    }
386cb93a386Sopenharmony_ci    return true;
387cb93a386Sopenharmony_ci}
388cb93a386Sopenharmony_ci
389cb93a386Sopenharmony_cistatic bool parse_option_gpu_surf_type(const SkString&                   value,
390cb93a386Sopenharmony_ci                                       SkCommandLineConfigGpu::SurfType* surfType) {
391cb93a386Sopenharmony_ci    if (value.equals("default")) {
392cb93a386Sopenharmony_ci        *surfType = SkCommandLineConfigGpu::SurfType::kDefault;
393cb93a386Sopenharmony_ci        return true;
394cb93a386Sopenharmony_ci    }
395cb93a386Sopenharmony_ci    if (value.equals("betex")) {
396cb93a386Sopenharmony_ci        *surfType = SkCommandLineConfigGpu::SurfType::kBackendTexture;
397cb93a386Sopenharmony_ci        return true;
398cb93a386Sopenharmony_ci    }
399cb93a386Sopenharmony_ci    if (value.equals("bert")) {
400cb93a386Sopenharmony_ci        *surfType = SkCommandLineConfigGpu::SurfType::kBackendRenderTarget;
401cb93a386Sopenharmony_ci        return true;
402cb93a386Sopenharmony_ci    }
403cb93a386Sopenharmony_ci    return false;
404cb93a386Sopenharmony_ci}
405cb93a386Sopenharmony_ci
406cb93a386Sopenharmony_ci// Extended options take form --config item[key1=value1,key2=value2,...]
407cb93a386Sopenharmony_ci// Example: --config gpu[api=gl,color=8888]
408cb93a386Sopenharmony_ciclass ExtendedOptions {
409cb93a386Sopenharmony_cipublic:
410cb93a386Sopenharmony_ci    ExtendedOptions(const SkString& optionsString, bool* outParseSucceeded) {
411cb93a386Sopenharmony_ci        SkTArray<SkString> optionParts;
412cb93a386Sopenharmony_ci        SkStrSplit(optionsString.c_str(), ",", kStrict_SkStrSplitMode, &optionParts);
413cb93a386Sopenharmony_ci        for (int i = 0; i < optionParts.count(); ++i) {
414cb93a386Sopenharmony_ci            SkTArray<SkString> keyValueParts;
415cb93a386Sopenharmony_ci            SkStrSplit(optionParts[i].c_str(), "=", kStrict_SkStrSplitMode, &keyValueParts);
416cb93a386Sopenharmony_ci            if (keyValueParts.count() != 2) {
417cb93a386Sopenharmony_ci                *outParseSucceeded = false;
418cb93a386Sopenharmony_ci                return;
419cb93a386Sopenharmony_ci            }
420cb93a386Sopenharmony_ci            const SkString& key   = keyValueParts[0];
421cb93a386Sopenharmony_ci            const SkString& value = keyValueParts[1];
422cb93a386Sopenharmony_ci            if (fOptionsMap.find(key) == nullptr) {
423cb93a386Sopenharmony_ci                fOptionsMap.set(key, value);
424cb93a386Sopenharmony_ci            } else {
425cb93a386Sopenharmony_ci                // Duplicate values are not allowed.
426cb93a386Sopenharmony_ci                *outParseSucceeded = false;
427cb93a386Sopenharmony_ci                return;
428cb93a386Sopenharmony_ci            }
429cb93a386Sopenharmony_ci        }
430cb93a386Sopenharmony_ci        *outParseSucceeded = true;
431cb93a386Sopenharmony_ci    }
432cb93a386Sopenharmony_ci
433cb93a386Sopenharmony_ci    bool get_option_gpu_color(const char*  optionKey,
434cb93a386Sopenharmony_ci                              SkColorType* outColorType,
435cb93a386Sopenharmony_ci                              SkAlphaType* alphaType,
436cb93a386Sopenharmony_ci                              bool         optional = true) const {
437cb93a386Sopenharmony_ci        SkString* optionValue = fOptionsMap.find(SkString(optionKey));
438cb93a386Sopenharmony_ci        if (optionValue == nullptr) {
439cb93a386Sopenharmony_ci            return optional;
440cb93a386Sopenharmony_ci        }
441cb93a386Sopenharmony_ci        return parse_option_gpu_color(*optionValue, outColorType, alphaType);
442cb93a386Sopenharmony_ci    }
443cb93a386Sopenharmony_ci
444cb93a386Sopenharmony_ci    bool get_option_gpu_api(const char*                          optionKey,
445cb93a386Sopenharmony_ci                            SkCommandLineConfigGpu::ContextType* outContextType,
446cb93a386Sopenharmony_ci                            bool*                                outFakeGLESVersion2,
447cb93a386Sopenharmony_ci                            bool                                 optional = true) const {
448cb93a386Sopenharmony_ci        SkString* optionValue = fOptionsMap.find(SkString(optionKey));
449cb93a386Sopenharmony_ci        if (optionValue == nullptr) {
450cb93a386Sopenharmony_ci            return optional;
451cb93a386Sopenharmony_ci        }
452cb93a386Sopenharmony_ci        return parse_option_gpu_api(*optionValue, outContextType, outFakeGLESVersion2);
453cb93a386Sopenharmony_ci    }
454cb93a386Sopenharmony_ci
455cb93a386Sopenharmony_ci#ifdef SK_GRAPHITE_ENABLED
456cb93a386Sopenharmony_ci    bool get_option_graphite_api(const char*                               optionKey,
457cb93a386Sopenharmony_ci                                 SkCommandLineConfigGraphite::ContextType* outContextType) const {
458cb93a386Sopenharmony_ci        using ContextType = skiatest::graphite::ContextFactory::ContextType;
459cb93a386Sopenharmony_ci
460cb93a386Sopenharmony_ci        SkString* optionValue = fOptionsMap.find(SkString(optionKey));
461cb93a386Sopenharmony_ci        if (optionValue == nullptr) {
462cb93a386Sopenharmony_ci            return false;
463cb93a386Sopenharmony_ci        }
464cb93a386Sopenharmony_ci#ifdef SK_VULKAN
465cb93a386Sopenharmony_ci        if (optionValue->equals("vulkan")) {
466cb93a386Sopenharmony_ci            *outContextType = ContextType::kVulkan;
467cb93a386Sopenharmony_ci            return true;
468cb93a386Sopenharmony_ci        }
469cb93a386Sopenharmony_ci#endif
470cb93a386Sopenharmony_ci#ifdef SK_METAL
471cb93a386Sopenharmony_ci        if (optionValue->equals("metal")) {
472cb93a386Sopenharmony_ci            *outContextType = ContextType::kMetal;
473cb93a386Sopenharmony_ci            return true;
474cb93a386Sopenharmony_ci        }
475cb93a386Sopenharmony_ci#endif
476cb93a386Sopenharmony_ci#ifdef SK_DIRECT3D
477cb93a386Sopenharmony_ci        if (optionValue->equals("direct3d")) {
478cb93a386Sopenharmony_ci            *outContextType = ContextType::kDirect3D;
479cb93a386Sopenharmony_ci            return true;
480cb93a386Sopenharmony_ci        }
481cb93a386Sopenharmony_ci#endif
482cb93a386Sopenharmony_ci        return false;
483cb93a386Sopenharmony_ci    }
484cb93a386Sopenharmony_ci#endif
485cb93a386Sopenharmony_ci
486cb93a386Sopenharmony_ci    bool get_option_gpu_surf_type(const char*                       optionKey,
487cb93a386Sopenharmony_ci                                  SkCommandLineConfigGpu::SurfType* outSurfType,
488cb93a386Sopenharmony_ci                                  bool                              optional = true) const {
489cb93a386Sopenharmony_ci        SkString* optionValue = fOptionsMap.find(SkString(optionKey));
490cb93a386Sopenharmony_ci        if (optionValue == nullptr) {
491cb93a386Sopenharmony_ci            return optional;
492cb93a386Sopenharmony_ci        }
493cb93a386Sopenharmony_ci        return parse_option_gpu_surf_type(*optionValue, outSurfType);
494cb93a386Sopenharmony_ci    }
495cb93a386Sopenharmony_ci
496cb93a386Sopenharmony_ci    bool get_option_int(const char* optionKey, int* outInt, bool optional = true) const {
497cb93a386Sopenharmony_ci        SkString* optionValue = fOptionsMap.find(SkString(optionKey));
498cb93a386Sopenharmony_ci        if (optionValue == nullptr) {
499cb93a386Sopenharmony_ci            return optional;
500cb93a386Sopenharmony_ci        }
501cb93a386Sopenharmony_ci        return parse_option_int(*optionValue, outInt);
502cb93a386Sopenharmony_ci    }
503cb93a386Sopenharmony_ci
504cb93a386Sopenharmony_ci    bool get_option_bool(const char* optionKey, bool* outBool, bool optional = true) const {
505cb93a386Sopenharmony_ci        SkString* optionValue = fOptionsMap.find(SkString(optionKey));
506cb93a386Sopenharmony_ci        if (optionValue == nullptr) {
507cb93a386Sopenharmony_ci            return optional;
508cb93a386Sopenharmony_ci        }
509cb93a386Sopenharmony_ci        return parse_option_bool(*optionValue, outBool);
510cb93a386Sopenharmony_ci    }
511cb93a386Sopenharmony_ci
512cb93a386Sopenharmony_ciprivate:
513cb93a386Sopenharmony_ci    SkTHashMap<SkString, SkString> fOptionsMap;
514cb93a386Sopenharmony_ci};
515cb93a386Sopenharmony_ci
516cb93a386Sopenharmony_ciSkCommandLineConfigGpu::SkCommandLineConfigGpu(const SkString&           tag,
517cb93a386Sopenharmony_ci                                               const SkTArray<SkString>& viaParts,
518cb93a386Sopenharmony_ci                                               ContextType               contextType,
519cb93a386Sopenharmony_ci                                               bool                      fakeGLESVersion2,
520cb93a386Sopenharmony_ci                                               uint32_t                  surfaceFlags,
521cb93a386Sopenharmony_ci                                               int                       samples,
522cb93a386Sopenharmony_ci                                               SkColorType               colorType,
523cb93a386Sopenharmony_ci                                               SkAlphaType               alphaType,
524cb93a386Sopenharmony_ci                                               bool                      useStencilBuffers,
525cb93a386Sopenharmony_ci                                               bool                      testThreading,
526cb93a386Sopenharmony_ci                                               int                       testPersistentCache,
527cb93a386Sopenharmony_ci                                               bool                      testPrecompile,
528cb93a386Sopenharmony_ci                                               bool                      useDDLSink,
529cb93a386Sopenharmony_ci                                               bool                      OOPRish,
530cb93a386Sopenharmony_ci                                               bool                      reducedShaders,
531cb93a386Sopenharmony_ci                                               SurfType                  surfType)
532cb93a386Sopenharmony_ci        : SkCommandLineConfig(tag, SkString("gpu"), viaParts)
533cb93a386Sopenharmony_ci        , fContextType(contextType)
534cb93a386Sopenharmony_ci        , fContextOverrides(ContextOverrides::kNone)
535cb93a386Sopenharmony_ci        , fSurfaceFlags(surfaceFlags)
536cb93a386Sopenharmony_ci        , fSamples(samples)
537cb93a386Sopenharmony_ci        , fColorType(colorType)
538cb93a386Sopenharmony_ci        , fAlphaType(alphaType)
539cb93a386Sopenharmony_ci        , fTestThreading(testThreading)
540cb93a386Sopenharmony_ci        , fTestPersistentCache(testPersistentCache)
541cb93a386Sopenharmony_ci        , fTestPrecompile(testPrecompile)
542cb93a386Sopenharmony_ci        , fUseDDLSink(useDDLSink)
543cb93a386Sopenharmony_ci        , fOOPRish(OOPRish)
544cb93a386Sopenharmony_ci        , fReducedShaders(reducedShaders)
545cb93a386Sopenharmony_ci        , fSurfType(surfType) {
546cb93a386Sopenharmony_ci    if (!useStencilBuffers) {
547cb93a386Sopenharmony_ci        fContextOverrides |= ContextOverrides::kAvoidStencilBuffers;
548cb93a386Sopenharmony_ci    }
549cb93a386Sopenharmony_ci    if (fakeGLESVersion2) {
550cb93a386Sopenharmony_ci        fContextOverrides |= ContextOverrides::kFakeGLESVersionAs2;
551cb93a386Sopenharmony_ci    }
552cb93a386Sopenharmony_ci    if (reducedShaders) {
553cb93a386Sopenharmony_ci        fContextOverrides |= ContextOverrides ::kReducedShaders;
554cb93a386Sopenharmony_ci    }
555cb93a386Sopenharmony_ci}
556cb93a386Sopenharmony_ci
557cb93a386Sopenharmony_ciSkCommandLineConfigGpu* parse_command_line_config_gpu(const SkString&           tag,
558cb93a386Sopenharmony_ci                                                      const SkTArray<SkString>& vias,
559cb93a386Sopenharmony_ci                                                      const SkString&           options) {
560cb93a386Sopenharmony_ci    // Defaults for GPU backend.
561cb93a386Sopenharmony_ci    SkCommandLineConfigGpu::ContextType contextType         = GrContextFactory::kGL_ContextType;
562cb93a386Sopenharmony_ci    bool                                useDIText           = false;
563cb93a386Sopenharmony_ci    bool                                useDMSAA            = false;
564cb93a386Sopenharmony_ci    int                                 samples             = 1;
565cb93a386Sopenharmony_ci    SkColorType                         colorType           = kRGBA_8888_SkColorType;
566cb93a386Sopenharmony_ci    SkAlphaType                         alphaType           = kPremul_SkAlphaType;
567cb93a386Sopenharmony_ci    bool                                useStencils         = true;
568cb93a386Sopenharmony_ci    bool                                testThreading       = false;
569cb93a386Sopenharmony_ci    int                                 testPersistentCache = 0;
570cb93a386Sopenharmony_ci    bool                                testPrecompile      = false;
571cb93a386Sopenharmony_ci    bool                                useDDLs             = false;
572cb93a386Sopenharmony_ci    bool                                ooprish             = false;
573cb93a386Sopenharmony_ci    bool                                reducedShaders      = false;
574cb93a386Sopenharmony_ci    bool                                fakeGLESVersion2    = false;
575cb93a386Sopenharmony_ci    SkCommandLineConfigGpu::SurfType    surfType = SkCommandLineConfigGpu::SurfType::kDefault;
576cb93a386Sopenharmony_ci
577cb93a386Sopenharmony_ci    bool            parseSucceeded = false;
578cb93a386Sopenharmony_ci    ExtendedOptions extendedOptions(options, &parseSucceeded);
579cb93a386Sopenharmony_ci    if (!parseSucceeded) {
580cb93a386Sopenharmony_ci        return nullptr;
581cb93a386Sopenharmony_ci    }
582cb93a386Sopenharmony_ci
583cb93a386Sopenharmony_ci    bool validOptions =
584cb93a386Sopenharmony_ci            extendedOptions.get_option_gpu_api("api", &contextType, &fakeGLESVersion2, false) &&
585cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("dit", &useDIText) &&
586cb93a386Sopenharmony_ci            extendedOptions.get_option_int("samples", &samples) &&
587cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("dmsaa", &useDMSAA) &&
588cb93a386Sopenharmony_ci            extendedOptions.get_option_gpu_color("color", &colorType, &alphaType) &&
589cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("stencils", &useStencils) &&
590cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("testThreading", &testThreading) &&
591cb93a386Sopenharmony_ci            extendedOptions.get_option_int("testPersistentCache", &testPersistentCache) &&
592cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("testPrecompile", &testPrecompile) &&
593cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("useDDLSink", &useDDLs) &&
594cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("OOPRish", &ooprish) &&
595cb93a386Sopenharmony_ci            extendedOptions.get_option_bool("reducedShaders", &reducedShaders) &&
596cb93a386Sopenharmony_ci            extendedOptions.get_option_gpu_surf_type("surf", &surfType);
597cb93a386Sopenharmony_ci
598cb93a386Sopenharmony_ci    // testing threading and the persistent cache are mutually exclusive.
599cb93a386Sopenharmony_ci    if (!validOptions || (testThreading && (testPersistentCache != 0))) {
600cb93a386Sopenharmony_ci        return nullptr;
601cb93a386Sopenharmony_ci    }
602cb93a386Sopenharmony_ci
603cb93a386Sopenharmony_ci    uint32_t surfaceFlags = 0;
604cb93a386Sopenharmony_ci    if (useDIText) {
605cb93a386Sopenharmony_ci        surfaceFlags |= SkSurfaceProps::kUseDeviceIndependentFonts_Flag;
606cb93a386Sopenharmony_ci    }
607cb93a386Sopenharmony_ci    if (useDMSAA) {
608cb93a386Sopenharmony_ci        surfaceFlags |= SkSurfaceProps::kDynamicMSAA_Flag;
609cb93a386Sopenharmony_ci    }
610cb93a386Sopenharmony_ci
611cb93a386Sopenharmony_ci    return new SkCommandLineConfigGpu(tag,
612cb93a386Sopenharmony_ci                                      vias,
613cb93a386Sopenharmony_ci                                      contextType,
614cb93a386Sopenharmony_ci                                      fakeGLESVersion2,
615cb93a386Sopenharmony_ci                                      surfaceFlags,
616cb93a386Sopenharmony_ci                                      samples,
617cb93a386Sopenharmony_ci                                      colorType,
618cb93a386Sopenharmony_ci                                      alphaType,
619cb93a386Sopenharmony_ci                                      useStencils,
620cb93a386Sopenharmony_ci                                      testThreading,
621cb93a386Sopenharmony_ci                                      testPersistentCache,
622cb93a386Sopenharmony_ci                                      testPrecompile,
623cb93a386Sopenharmony_ci                                      useDDLs,
624cb93a386Sopenharmony_ci                                      ooprish,
625cb93a386Sopenharmony_ci                                      reducedShaders,
626cb93a386Sopenharmony_ci                                      surfType);
627cb93a386Sopenharmony_ci}
628cb93a386Sopenharmony_ci
629cb93a386Sopenharmony_ci#ifdef SK_GRAPHITE_ENABLED
630cb93a386Sopenharmony_ci
631cb93a386Sopenharmony_ciSkCommandLineConfigGraphite* parse_command_line_config_graphite(const SkString&           tag,
632cb93a386Sopenharmony_ci                                                                const SkTArray<SkString>& vias,
633cb93a386Sopenharmony_ci                                                                const SkString&           options) {
634cb93a386Sopenharmony_ci    using ContextType = skiatest::graphite::ContextFactory::ContextType;
635cb93a386Sopenharmony_ci
636cb93a386Sopenharmony_ci    ContextType contextType = ContextType::kMetal;
637cb93a386Sopenharmony_ci    SkColorType colorType = kRGBA_8888_SkColorType;
638cb93a386Sopenharmony_ci    SkAlphaType alphaType = kPremul_SkAlphaType;
639cb93a386Sopenharmony_ci    bool testPrecompile = false;
640cb93a386Sopenharmony_ci
641cb93a386Sopenharmony_ci    bool parseSucceeded = false;
642cb93a386Sopenharmony_ci    ExtendedOptions extendedOptions(options, &parseSucceeded);
643cb93a386Sopenharmony_ci    if (!parseSucceeded) {
644cb93a386Sopenharmony_ci        return nullptr;
645cb93a386Sopenharmony_ci    }
646cb93a386Sopenharmony_ci
647cb93a386Sopenharmony_ci    bool validOptions = extendedOptions.get_option_graphite_api("api", &contextType) &&
648cb93a386Sopenharmony_ci                        extendedOptions.get_option_gpu_color("color", &colorType, &alphaType) &&
649cb93a386Sopenharmony_ci                        extendedOptions.get_option_bool("testPrecompile", &testPrecompile);
650cb93a386Sopenharmony_ci    if (!validOptions) {
651cb93a386Sopenharmony_ci        return nullptr;
652cb93a386Sopenharmony_ci    }
653cb93a386Sopenharmony_ci
654cb93a386Sopenharmony_ci    return new SkCommandLineConfigGraphite(tag,
655cb93a386Sopenharmony_ci                                           vias,
656cb93a386Sopenharmony_ci                                           contextType,
657cb93a386Sopenharmony_ci                                           colorType,
658cb93a386Sopenharmony_ci                                           alphaType,
659cb93a386Sopenharmony_ci                                           testPrecompile);
660cb93a386Sopenharmony_ci}
661cb93a386Sopenharmony_ci
662cb93a386Sopenharmony_ci#endif
663cb93a386Sopenharmony_ci
664cb93a386Sopenharmony_ciSkCommandLineConfigSvg::SkCommandLineConfigSvg(const SkString&           tag,
665cb93a386Sopenharmony_ci                                               const SkTArray<SkString>& viaParts,
666cb93a386Sopenharmony_ci                                               int                       pageIndex)
667cb93a386Sopenharmony_ci        : SkCommandLineConfig(tag, SkString("svg"), viaParts), fPageIndex(pageIndex) {}
668cb93a386Sopenharmony_ci
669cb93a386Sopenharmony_ciSkCommandLineConfigSvg* parse_command_line_config_svg(const SkString&           tag,
670cb93a386Sopenharmony_ci                                                      const SkTArray<SkString>& vias,
671cb93a386Sopenharmony_ci                                                      const SkString&           options) {
672cb93a386Sopenharmony_ci    // Defaults for SVG backend.
673cb93a386Sopenharmony_ci    int pageIndex = 0;
674cb93a386Sopenharmony_ci
675cb93a386Sopenharmony_ci    bool            parseSucceeded = false;
676cb93a386Sopenharmony_ci    ExtendedOptions extendedOptions(options, &parseSucceeded);
677cb93a386Sopenharmony_ci    if (!parseSucceeded) {
678cb93a386Sopenharmony_ci        return nullptr;
679cb93a386Sopenharmony_ci    }
680cb93a386Sopenharmony_ci
681cb93a386Sopenharmony_ci    bool validOptions = extendedOptions.get_option_int("page", &pageIndex);
682cb93a386Sopenharmony_ci
683cb93a386Sopenharmony_ci    if (!validOptions) {
684cb93a386Sopenharmony_ci        return nullptr;
685cb93a386Sopenharmony_ci    }
686cb93a386Sopenharmony_ci
687cb93a386Sopenharmony_ci    return new SkCommandLineConfigSvg(tag, vias, pageIndex);
688cb93a386Sopenharmony_ci}
689cb93a386Sopenharmony_ci
690cb93a386Sopenharmony_civoid ParseConfigs(const CommandLineFlags::StringArray& configs,
691cb93a386Sopenharmony_ci                  SkCommandLineConfigArray*            outResult) {
692cb93a386Sopenharmony_ci    outResult->reset();
693cb93a386Sopenharmony_ci    for (int i = 0; i < configs.count(); ++i) {
694cb93a386Sopenharmony_ci        SkString           extendedBackend;
695cb93a386Sopenharmony_ci        SkString           extendedOptions;
696cb93a386Sopenharmony_ci        SkString           simpleBackend;
697cb93a386Sopenharmony_ci        SkTArray<SkString> vias;
698cb93a386Sopenharmony_ci
699cb93a386Sopenharmony_ci        SkString           tag(configs[i]);
700cb93a386Sopenharmony_ci        SkTArray<SkString> parts;
701cb93a386Sopenharmony_ci        SkStrSplit(tag.c_str(), "[", kStrict_SkStrSplitMode, &parts);
702cb93a386Sopenharmony_ci        if (parts.count() == 2) {
703cb93a386Sopenharmony_ci            SkTArray<SkString> parts2;
704cb93a386Sopenharmony_ci            SkStrSplit(parts[1].c_str(), "]", kStrict_SkStrSplitMode, &parts2);
705cb93a386Sopenharmony_ci            if (parts2.count() == 2 && parts2[1].isEmpty()) {
706cb93a386Sopenharmony_ci                SkStrSplit(parts[0].c_str(), "-", kStrict_SkStrSplitMode, &vias);
707cb93a386Sopenharmony_ci                if (vias.count()) {
708cb93a386Sopenharmony_ci                    extendedBackend = vias[vias.count() - 1];
709cb93a386Sopenharmony_ci                    vias.pop_back();
710cb93a386Sopenharmony_ci                } else {
711cb93a386Sopenharmony_ci                    extendedBackend = parts[0];
712cb93a386Sopenharmony_ci                }
713cb93a386Sopenharmony_ci                extendedOptions = parts2[0];
714cb93a386Sopenharmony_ci                simpleBackend.printf("%s[%s]", extendedBackend.c_str(), extendedOptions.c_str());
715cb93a386Sopenharmony_ci            }
716cb93a386Sopenharmony_ci        }
717cb93a386Sopenharmony_ci
718cb93a386Sopenharmony_ci        if (extendedBackend.isEmpty()) {
719cb93a386Sopenharmony_ci            simpleBackend = tag;
720cb93a386Sopenharmony_ci            SkStrSplit(tag.c_str(), "-", kStrict_SkStrSplitMode, &vias);
721cb93a386Sopenharmony_ci            if (vias.count()) {
722cb93a386Sopenharmony_ci                simpleBackend = vias[vias.count() - 1];
723cb93a386Sopenharmony_ci                vias.pop_back();
724cb93a386Sopenharmony_ci            }
725cb93a386Sopenharmony_ci            for (auto& predefinedConfig : gPredefinedConfigs) {
726cb93a386Sopenharmony_ci                if (simpleBackend.equals(predefinedConfig.predefinedConfig)) {
727cb93a386Sopenharmony_ci                    extendedBackend = predefinedConfig.backend;
728cb93a386Sopenharmony_ci                    extendedOptions = predefinedConfig.options;
729cb93a386Sopenharmony_ci                    break;
730cb93a386Sopenharmony_ci                }
731cb93a386Sopenharmony_ci            }
732cb93a386Sopenharmony_ci        }
733cb93a386Sopenharmony_ci        SkCommandLineConfig* parsedConfig = nullptr;
734cb93a386Sopenharmony_ci        if (extendedBackend.equals("gpu")) {
735cb93a386Sopenharmony_ci            parsedConfig = parse_command_line_config_gpu(tag, vias, extendedOptions);
736cb93a386Sopenharmony_ci        }
737cb93a386Sopenharmony_ci#ifdef SK_GRAPHITE_ENABLED
738cb93a386Sopenharmony_ci        if (extendedBackend.equals("graphite")) {
739cb93a386Sopenharmony_ci            parsedConfig = parse_command_line_config_graphite(tag, vias, extendedOptions);
740cb93a386Sopenharmony_ci        }
741cb93a386Sopenharmony_ci#endif
742cb93a386Sopenharmony_ci        if (extendedBackend.equals("svg")) {
743cb93a386Sopenharmony_ci            parsedConfig = parse_command_line_config_svg(tag, vias, extendedOptions);
744cb93a386Sopenharmony_ci        }
745cb93a386Sopenharmony_ci        if (!parsedConfig) {
746cb93a386Sopenharmony_ci            parsedConfig = new SkCommandLineConfig(tag, simpleBackend, vias);
747cb93a386Sopenharmony_ci        }
748cb93a386Sopenharmony_ci        outResult->emplace_back(parsedConfig);
749cb93a386Sopenharmony_ci    }
750cb93a386Sopenharmony_ci}
751