• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 "SkSLCompiler.h"
9 
10 #include "Test.h"
11 
12 #if SK_SUPPORT_GPU
13 
test(skiatest::Reporter * r,const char * src,const GrShaderCaps & caps,std::vector<const char * > expectedH,std::vector<const char * > expectedCPP)14 static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
15                  std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
16     SkSL::Program::Settings settings;
17     settings.fCaps = &caps;
18     SkSL::Compiler compiler;
19     SkSL::StringStream output;
20     std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
21                                                              SkSL::Program::kFragmentProcessor_Kind,
22                                                              SkString(src),
23                                                              settings);
24     if (!program) {
25         SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
26         return;
27     }
28     REPORTER_ASSERT(r, program);
29     bool success = compiler.toH(*program, "Test", output);
30     if (!success) {
31         SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
32     }
33     REPORTER_ASSERT(r, success);
34     if (success) {
35         for (const char* expected : expectedH) {
36             bool found = strstr(output.str().c_str(), expected);
37             if (!found) {
38                 SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
39                          expected, output.str().c_str());
40             }
41             REPORTER_ASSERT(r, found);
42         }
43     }
44     output.reset();
45     success = compiler.toCPP(*program, "Test", output);
46     if (!success) {
47         SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
48     }
49     REPORTER_ASSERT(r, success);
50     if (success) {
51         for (const char* expected : expectedCPP) {
52             bool found = strstr(output.str().c_str(), expected);
53             if (!found) {
54                 SkDebugf("CPP MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
55                          expected, output.str().c_str());
56             }
57             REPORTER_ASSERT(r, found);
58         }
59     }
60 }
61 
DEF_TEST(SkSLFPHelloWorld,r)62 DEF_TEST(SkSLFPHelloWorld, r) {
63     test(r,
64          "void main() {"
65          "sk_OutColor = vec4(1);"
66          "}",
67          *SkSL::ShaderCapsFactory::Default(),
68          {
69              "/*\n"
70              " * Copyright 2017 Google Inc.\n"
71              " *\n"
72              " * Use of this source code is governed by a BSD-style license that can be\n"
73              " * found in the LICENSE file.\n"
74              " */\n"
75              "\n"
76              "/*\n"
77              " * This file was autogenerated from GrTest.fp; do not modify.\n"
78              " */\n"
79              "#ifndef GrTest_DEFINED\n"
80              "#define GrTest_DEFINED\n"
81              "#include \"SkTypes.h\"\n"
82              "#if SK_SUPPORT_GPU\n"
83              "#include \"GrFragmentProcessor.h\"\n"
84              "#include \"GrCoordTransform.h\"\n"
85              "#include \"GrColorSpaceXform.h\"\n"
86              "#include \"effects/GrProxyMove.h\"\n"
87              "class GrTest : public GrFragmentProcessor {\n"
88              "public:\n"
89              "    static sk_sp<GrFragmentProcessor> Make() {\n"
90              "        return sk_sp<GrFragmentProcessor>(new GrTest());\n"
91              "    }\n"
92              "    const char* name() const override { return \"Test\"; }\n"
93              "private:\n"
94              "    GrTest()\n"
95              "    : INHERITED(kNone_OptimizationFlags) {\n"
96              "        this->initClassID<GrTest>();\n"
97              "    }\n"
98              "    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
99              "    void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) "
100                     "const override;\n"
101              "    bool onIsEqual(const GrFragmentProcessor&) const override;\n"
102              "    GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
103              "    typedef GrFragmentProcessor INHERITED;\n"
104              "};\n"
105              "#endif\n"
106              "#endif\n"
107          },
108          {
109              "/*\n"
110              " * Copyright 2017 Google Inc.\n"
111              " *\n"
112              " * Use of this source code is governed by a BSD-style license that can be\n"
113              " * found in the LICENSE file.\n"
114              " */\n"
115              "\n"
116              "/*\n"
117              " * This file was autogenerated from GrTest.fp; do not modify.\n"
118              " */\n"
119              "#include \"GrTest.h\"\n"
120              "#if SK_SUPPORT_GPU\n"
121              "#include \"glsl/GrGLSLColorSpaceXformHelper.h\"\n"
122              "#include \"glsl/GrGLSLFragmentProcessor.h\"\n"
123              "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n"
124              "#include \"glsl/GrGLSLProgramBuilder.h\"\n"
125              "#include \"SkSLCPP.h\"\n"
126              "#include \"SkSLUtil.h\"\n"
127              "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
128              "public:\n"
129              "    GrGLSLTest() {}\n"
130              "    void emitCode(EmitArgs& args) override {\n"
131              "        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
132              "        const GrTest& _outer = args.fFp.cast<GrTest>();\n"
133              "        (void) _outer;\n"
134              "        fragBuilder->codeAppendf(\"%s = vec4(1.0);\\n\", args.fOutputColor);\n"
135              "    }\n"
136              "private:\n"
137              "    void onSetData(const GrGLSLProgramDataManager& pdman, "
138                                 "const GrFragmentProcessor& _proc) override {\n"
139              "    }\n"
140              "};\n"
141              "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
142              "    return new GrGLSLTest();\n"
143              "}\n"
144              "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
145                                                 "GrProcessorKeyBuilder* b) const {\n"
146              "}\n"
147              "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
148              "    const GrTest& that = other.cast<GrTest>();\n"
149              "    (void) that;\n"
150              "    return true;\n"
151              "}\n"
152              "#endif\n"
153          });
154 }
155 
DEF_TEST(SkSLFPInput,r)156 DEF_TEST(SkSLFPInput, r) {
157     test(r,
158          "in vec2 point;"
159          "void main() {"
160          "sk_OutColor = vec4(point, point);"
161          "}",
162          *SkSL::ShaderCapsFactory::Default(),
163          {
164              "SkPoint point() const { return fPoint; }",
165              "static sk_sp<GrFragmentProcessor> Make(SkPoint point) {",
166              "return sk_sp<GrFragmentProcessor>(new GrTest(point));",
167              "GrTest(SkPoint point)",
168              ", fPoint(point)"
169          },
170          {
171              "fragBuilder->codeAppendf(\"%s = vec4(vec2(%f, %f), vec2(%f, %f));\\n\", "
172                                       "args.fOutputColor, _outer.point().fX, _outer.point().fY, "
173                                       "_outer.point().fX, _outer.point().fY);",
174              "if (fPoint != that.fPoint) return false;"
175          });
176 }
177 
DEF_TEST(SkSLFPUniform,r)178 DEF_TEST(SkSLFPUniform, r) {
179     test(r,
180          "uniform vec4 color;"
181          "void main() {"
182          "sk_OutColor = color;"
183          "}",
184          *SkSL::ShaderCapsFactory::Default(),
185          {
186              "static sk_sp<GrFragmentProcessor> Make()"
187          },
188          {
189             "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
190                                                          "kDefault_GrSLPrecision, \"color\");",
191          });
192 }
193 
DEF_TEST(SkSLFPInUniform,r)194 DEF_TEST(SkSLFPInUniform, r) {
195     test(r,
196          "in uniform vec4 color;"
197          "void main() {"
198          "sk_OutColor = color;"
199          "}",
200          *SkSL::ShaderCapsFactory::Default(),
201          {
202              "static sk_sp<GrFragmentProcessor> Make(SkRect color) {",
203          },
204          {
205             "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
206                                                          "kDefault_GrSLPrecision, \"color\");",
207             "const SkRect colorValue = _outer.color();",
208             "pdman.set4fv(fColorVar, 1, (float*) &colorValue);"
209          });
210 }
211 
DEF_TEST(SkSLFPSections,r)212 DEF_TEST(SkSLFPSections, r) {
213     test(r,
214          "@header { header section }"
215          "void main() {"
216          "sk_OutColor = vec4(1);"
217          "}",
218          *SkSL::ShaderCapsFactory::Default(),
219          {
220              "#if SK_SUPPORT_GPU\n header section"
221          },
222          {});
223     test(r,
224          "@class { class section }"
225          "void main() {"
226          "sk_OutColor = vec4(1);"
227          "}",
228          *SkSL::ShaderCapsFactory::Default(),
229          {
230              "class GrTest : public GrFragmentProcessor {\n"
231              "public:\n"
232              " class section"
233          },
234          {});
235     test(r,
236          "@cpp { cpp section }"
237          "void main() {"
238          "sk_OutColor = vec4(1);"
239          "}",
240          *SkSL::ShaderCapsFactory::Default(),
241          {},
242          {"cpp section"});
243     test(r,
244          "@constructorParams { int x, float y, std::vector<float> z }"
245          "in float w;"
246          "void main() {"
247          "sk_OutColor = vec4(1);"
248          "}",
249          *SkSL::ShaderCapsFactory::Default(),
250          {
251              "Make(float w,  int x, float y, std::vector<float> z )",
252              "return sk_sp<GrFragmentProcessor>(new GrTest(w, x, y, z));",
253              "GrTest(float w,  int x, float y, std::vector<float> z )",
254              ", fW(w) {"
255          },
256          {});
257     test(r,
258          "@constructor { constructor section }"
259          "void main() {"
260          "sk_OutColor = vec4(1);"
261          "}",
262          *SkSL::ShaderCapsFactory::Default(),
263          {
264              "private:\n constructor section"
265          },
266          {});
267     test(r,
268          "@initializers { initializers section }"
269          "void main() {"
270          "sk_OutColor = vec4(1);"
271          "}",
272          *SkSL::ShaderCapsFactory::Default(),
273          {
274              ": INHERITED(kNone_OptimizationFlags)\n    ,  initializers section"
275          },
276          {});
277     test(r,
278          "float x = 10;"
279          "@emitCode { fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2); }"
280          "void main() {"
281          "sk_OutColor = vec4(1);"
282          "}",
283          *SkSL::ShaderCapsFactory::Default(),
284          {},
285          {
286             "x = 10.0;\n"
287             " fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2);"
288          });
289     test(r,
290          "@fields { fields section }"
291          "void main() {"
292          "sk_OutColor = vec4(1);"
293          "}",
294          *SkSL::ShaderCapsFactory::Default(),
295          {
296             "GR_DECLARE_FRAGMENT_PROCESSOR_TEST\n"
297             " fields section     typedef GrFragmentProcessor INHERITED;"
298          },
299          {});
300     test(r,
301          "@make { make section }"
302          "void main() {"
303          "sk_OutColor = vec4(1);"
304          "}",
305          *SkSL::ShaderCapsFactory::Default(),
306          {
307             "public:\n"
308             " make section"
309          },
310          {});
311     test(r,
312          "uniform float calculated;"
313          "in float provided;"
314          "@setData(varName) { varName.set1f(calculated, provided * 2); }"
315          "void main() {"
316          "sk_OutColor = vec4(1);"
317          "}",
318          *SkSL::ShaderCapsFactory::Default(),
319          {},
320          {
321              "void onSetData(const GrGLSLProgramDataManager& varName, "
322                             "const GrFragmentProcessor& _proc) override {\n",
323              "UniformHandle& calculated = fCalculatedVar;",
324              "auto provided = _outer.provided();",
325              "varName.set1f(calculated, provided * 2);"
326          });
327     test(r,
328          "@test(testDataName) { testDataName section }"
329          "void main() {"
330          "sk_OutColor = vec4(1);"
331          "}",
332          *SkSL::ShaderCapsFactory::Default(),
333          {},
334          {
335              "#if GR_TEST_UTILS\n"
336              "sk_sp<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
337              " testDataName section }\n"
338              "#endif"
339          });
340 }
341 
DEF_TEST(SkSLFPColorSpaceXform,r)342 DEF_TEST(SkSLFPColorSpaceXform, r) {
343     test(r,
344          "in uniform sampler2D image;"
345          "in uniform colorSpaceXform colorXform;"
346          "void main() {"
347          "sk_OutColor = sk_InColor * texture(image, vec2(0, 0), colorXform);"
348          "}",
349          *SkSL::ShaderCapsFactory::Default(),
350          {
351              "sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }",
352              "GrTest(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform)",
353              "this->addTextureSampler(&fImage);",
354              "sk_sp<GrColorSpaceXform> fColorXform;"
355          },
356          {
357              "fragBuilder->codeAppendf(\"vec4 _tmpVar1;%s = %s * %stexture(%s, "
358              "vec2(0.0, 0.0)).%s%s;\\n\", args.fOutputColor, args.fInputColor ? args.fInputColor : "
359              "\"vec4(1)\", fColorSpaceHelper.isValid() ? \"(_tmpVar1 = \" : \"\", "
360              "fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), "
361              "fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), "
362              "fColorSpaceHelper.isValid() ? SkStringPrintf(\", vec4(clamp((%s * vec4(_tmpVar1.rgb, "
363              "1.0)).rgb, 0.0, _tmpVar1.a), _tmpVar1.a))\", args.fUniformHandler->getUniformCStr("
364              "fColorSpaceHelper.gamutXformUniform())).c_str() : \"\");"
365          });
366 }
367 
DEF_TEST(SkSLFPTransformedCoords,r)368 DEF_TEST(SkSLFPTransformedCoords, r) {
369     test(r,
370          "void main() {"
371          "sk_OutColor = vec4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
372          "}",
373          *SkSL::ShaderCapsFactory::Default(),
374          {},
375          {
376             "SkSL::String sk_TransformedCoords2D_0 = "
377                                          "fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);",
378             "fragBuilder->codeAppendf(\"%s = vec4(%s, %s);\\n\", args.fOutputColor, "
379                               "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
380          });
381 
382 }
383 
DEF_TEST(SkSLFPLayoutWhen,r)384 DEF_TEST(SkSLFPLayoutWhen, r) {
385     test(r,
386          "layout(when=someExpression(someOtherExpression())) uniform float sometimes;"
387          "void main() {"
388          "}",
389          *SkSL::ShaderCapsFactory::Default(),
390          {},
391          {
392             "if (someExpression(someOtherExpression())) {\n"
393             "            fSometimesVar = args.fUniformHandler->addUniform"
394          });
395 
396 }
397 
398 #endif
399