• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 <fstream>
9 #include "src/sksl/SkSLCompiler.h"
10 #include "src/sksl/SkSLFileOutputStream.h"
11 
12 // Given the path to a file (e.g. src/gpu/effects/GrFooFragmentProcessor.fp) and the expected
13 // filename prefix and suffix (e.g. "Gr" and ".fp"), returns the "base name" of the
14 // file (in this case, 'FooFragmentProcessor'). If no match, returns the empty string.
base_name(const char * fpPath,const char * prefix,const char * suffix)15 static SkSL::String base_name(const char* fpPath, const char* prefix, const char* suffix) {
16     SkSL::String result;
17     const char* end = fpPath + strlen(fpPath);
18     const char* fileName = end;
19     // back up until we find a slash
20     while (fileName != fpPath && '/' != *(fileName - 1) && '\\' != *(fileName - 1)) {
21         --fileName;
22     }
23     if (!strncmp(fileName, prefix, strlen(prefix)) &&
24         !strncmp(end - strlen(suffix), suffix, strlen(suffix))) {
25         result.append(fileName + strlen(prefix), end - fileName - strlen(prefix) - strlen(suffix));
26     }
27     return result;
28 }
29 
30 /**
31  * Very simple standalone executable to facilitate testing.
32  */
main(int argc,const char ** argv)33 int main(int argc, const char** argv) {
34     if (argc != 3) {
35         printf("usage: skslc <input> <output>\n");
36         exit(1);
37     }
38     SkSL::Program::Kind kind;
39     SkSL::String input(argv[1]);
40     if (input.endsWith(".vert")) {
41         kind = SkSL::Program::kVertex_Kind;
42     } else if (input.endsWith(".frag")) {
43         kind = SkSL::Program::kFragment_Kind;
44     } else if (input.endsWith(".geom")) {
45         kind = SkSL::Program::kGeometry_Kind;
46     } else if (input.endsWith(".fp")) {
47         kind = SkSL::Program::kFragmentProcessor_Kind;
48     } else if (input.endsWith(".stage")) {
49         kind = SkSL::Program::kPipelineStage_Kind;
50     } else {
51         printf("input filename must end in '.vert', '.frag', '.geom', '.fp', or '.stage'\n");
52         exit(1);
53     }
54 
55     std::ifstream in(argv[1]);
56     std::string stdText((std::istreambuf_iterator<char>(in)),
57                         std::istreambuf_iterator<char>());
58     SkSL::String text(stdText.c_str());
59     if (in.rdstate()) {
60         printf("error reading '%s'\n", argv[1]);
61         exit(2);
62     }
63     SkSL::Program::Settings settings;
64     settings.fArgs.insert(std::make_pair("gpImplementsDistanceVector", 1));
65     SkSL::String name(argv[2]);
66     if (name.endsWith(".spirv")) {
67         SkSL::FileOutputStream out(argv[2]);
68         SkSL::Compiler compiler;
69         if (!out.isValid()) {
70             printf("error writing '%s'\n", argv[2]);
71             exit(4);
72         }
73         std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
74         if (!program || !compiler.toSPIRV(*program, out)) {
75             printf("%s", compiler.errorText().c_str());
76             exit(3);
77         }
78         if (!out.close()) {
79             printf("error writing '%s'\n", argv[2]);
80             exit(4);
81         }
82     } else if (name.endsWith(".glsl")) {
83         SkSL::FileOutputStream out(argv[2]);
84         SkSL::Compiler compiler;
85         if (!out.isValid()) {
86             printf("error writing '%s'\n", argv[2]);
87             exit(4);
88         }
89         std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
90         if (!program || !compiler.toGLSL(*program, out)) {
91             printf("%s", compiler.errorText().c_str());
92             exit(3);
93         }
94         if (!out.close()) {
95             printf("error writing '%s'\n", argv[2]);
96             exit(4);
97         }
98     } else if (name.endsWith(".metal")) {
99         SkSL::FileOutputStream out(argv[2]);
100         SkSL::Compiler compiler;
101         if (!out.isValid()) {
102             printf("error writing '%s'\n", argv[2]);
103             exit(4);
104         }
105         std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
106         if (!program || !compiler.toMetal(*program, out)) {
107             printf("%s", compiler.errorText().c_str());
108             exit(3);
109         }
110         if (!out.close()) {
111             printf("error writing '%s'\n", argv[2]);
112             exit(4);
113         }
114     } else if (name.endsWith(".h")) {
115         SkSL::FileOutputStream out(argv[2]);
116         SkSL::Compiler compiler(SkSL::Compiler::kPermitInvalidStaticTests_Flag);
117         if (!out.isValid()) {
118             printf("error writing '%s'\n", argv[2]);
119             exit(4);
120         }
121         settings.fReplaceSettings = false;
122         std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
123         if (!program || !compiler.toH(*program, base_name(argv[1], "Gr", ".fp"), out)) {
124             printf("%s", compiler.errorText().c_str());
125             exit(3);
126         }
127         if (!out.close()) {
128             printf("error writing '%s'\n", argv[2]);
129             exit(4);
130         }
131     } else if (name.endsWith(".cpp")) {
132         SkSL::FileOutputStream out(argv[2]);
133         SkSL::Compiler compiler(SkSL::Compiler::kPermitInvalidStaticTests_Flag);
134         if (!out.isValid()) {
135             printf("error writing '%s'\n", argv[2]);
136             exit(4);
137         }
138         settings.fReplaceSettings = false;
139         std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, text, settings);
140         if (!program || !compiler.toCPP(*program, base_name(argv[1], "Gr", ".fp"), out)) {
141             printf("%s", compiler.errorText().c_str());
142             exit(3);
143         }
144         if (!out.close()) {
145             printf("error writing '%s'\n", argv[2]);
146             exit(4);
147         }
148     } else {
149         printf("expected output filename to end with '.spirv', '.glsl', '.cpp', '.h', or '.metal'");
150         exit(1);
151     }
152 }
153