aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/SkSLFPTest.cpp
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2017-06-27 09:56:09 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-27 14:20:05 +0000
commitccf59917d3fe7aaf59de714acfbd0596503f324f (patch)
treecc97719c47276c9dcbf0ec09effd580c4e7450dd /tests/SkSLFPTest.cpp
parentc3aef18419c1bb16951370e11758c7ef131fa10b (diff)
sksl fragment processor support
Bug: skia: Change-Id: Ia3b0305c2b0c78074303831f628fb01852b90d34 Reviewed-on: https://skia-review.googlesource.com/17843 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Ben Wagner <benjaminwagner@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'tests/SkSLFPTest.cpp')
-rw-r--r--tests/SkSLFPTest.cpp381
1 files changed, 381 insertions, 0 deletions
diff --git a/tests/SkSLFPTest.cpp b/tests/SkSLFPTest.cpp
new file mode 100644
index 0000000000..6f1326d6f7
--- /dev/null
+++ b/tests/SkSLFPTest.cpp
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSLCompiler.h"
+
+#include "Test.h"
+
+#if SK_SUPPORT_GPU
+
+static void test(skiatest::Reporter* r, const char* src, const GrShaderCaps& caps,
+ std::vector<const char*> expectedH, std::vector<const char*> expectedCPP) {
+ SkSL::Program::Settings settings;
+ settings.fCaps = &caps;
+ SkSL::Compiler compiler;
+ SkSL::StringStream output;
+ std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
+ SkSL::Program::kFragmentProcessor_Kind,
+ SkString(src),
+ settings);
+ if (!program) {
+ SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
+ return;
+ }
+ REPORTER_ASSERT(r, program);
+ bool success = compiler.toH(*program, "Test", output);
+ if (!success) {
+ SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
+ }
+ REPORTER_ASSERT(r, success);
+ if (success) {
+ for (const char* expected : expectedH) {
+ bool found = strstr(output.str().c_str(), expected);
+ if (!found) {
+ SkDebugf("HEADER MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
+ expected, output.str().c_str());
+ }
+ REPORTER_ASSERT(r, found);
+ }
+ }
+ output.reset();
+ success = compiler.toCPP(*program, "Test", output);
+ if (!success) {
+ SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
+ }
+ REPORTER_ASSERT(r, success);
+ if (success) {
+ for (const char* expected : expectedCPP) {
+ bool found = strstr(output.str().c_str(), expected);
+ if (!found) {
+ SkDebugf("CPP MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src,
+ expected, output.str().c_str());
+ }
+ REPORTER_ASSERT(r, found);
+ }
+ }
+}
+
+DEF_TEST(SkSLFPHelloWorld, r) {
+ test(r,
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "/*\n"
+ " * This file was autogenerated from GrTest.fp.\n"
+ " */\n"
+ "#ifndef GrTest_DEFINED\n"
+ "#define GrTest_DEFINED\n"
+ "#include \"GrFragmentProcessor.h\"\n"
+ "#include \"GrCoordTransform.h\"\n"
+ "#include \"effects/GrProxyMove.h\"\n"
+ "class GrTest : public GrFragmentProcessor {\n"
+ "public:\n"
+ " static sk_sp<GrFragmentProcessor> Make() {\n"
+ " return sk_sp<GrFragmentProcessor>(new GrTest());\n"
+ " }\n"
+ " const char* name() const override { return \"Test\"; }\n"
+ "private:\n"
+ " GrTest()\n"
+ " : INHERITED(kNone_OptimizationFlags) {\n"
+ " this->initClassID<GrTest>();\n"
+ " }\n"
+ " GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;\n"
+ " void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) "
+ "const override;\n"
+ " bool onIsEqual(const GrFragmentProcessor&) const override;\n"
+ " GR_DECLARE_FRAGMENT_PROCESSOR_TEST;\n"
+ " typedef GrFragmentProcessor INHERITED;\n"
+ "};\n"
+ "#endif\n"
+ },
+ {
+ "/*\n"
+ " * This file was autogenerated from GrTest.fp.\n"
+ " */\n"
+ "#include \"GrTest.h\"\n"
+ "#include \"glsl/GrGLSLColorSpaceXformHelper.h\"\n"
+ "#include \"glsl/GrGLSLFragmentProcessor.h\"\n"
+ "#include \"glsl/GrGLSLFragmentShaderBuilder.h\"\n"
+ "#include \"glsl/GrGLSLProgramBuilder.h\"\n"
+ "#include \"GrResourceProvider.h\"\n"
+ "#include \"SkSLCPP.h\"\n"
+ "#include \"SkSLUtil.h\"\n"
+ "class GrGLSLTest : public GrGLSLFragmentProcessor {\n"
+ "public:\n"
+ " GrGLSLTest() {}\n"
+ " void emitCode(EmitArgs& args) override {\n"
+ " GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n"
+ " const GrTest& _outer = args.fFp.cast<GrTest>();\n"
+ " (void) _outer;\n"
+ " fragBuilder->codeAppendf(\"%s = vec4(1.0);\\n\", args.fOutputColor);\n"
+ " }\n"
+ "private:\n"
+ " void onSetData(const GrGLSLProgramDataManager& pdman, "
+ "const GrFragmentProcessor& _proc) override {\n"
+ " }\n"
+ "};\n"
+ "GrGLSLFragmentProcessor* GrTest::onCreateGLSLInstance() const {\n"
+ " return new GrGLSLTest();\n"
+ "}\n"
+ "void GrTest::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
+ "GrProcessorKeyBuilder* b) const {\n"
+ "}\n"
+ "bool GrTest::onIsEqual(const GrFragmentProcessor& other) const {\n"
+ " const GrTest& that = other.cast<GrTest>();\n"
+ " (void) that;\n"
+ " return true;\n"
+ "}\n"
+ });
+}
+
+DEF_TEST(SkSLFPInput, r) {
+ test(r,
+ "in vec2 point;"
+ "void main() {"
+ "sk_OutColor = vec4(point, point);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "SkPoint point() const { return fPoint; }",
+ "static sk_sp<GrFragmentProcessor> Make(SkPoint point) {",
+ "return sk_sp<GrFragmentProcessor>(new GrTest(point));",
+ "GrTest(SkPoint point)",
+ ", fPoint(point)"
+ },
+ {
+ "fragBuilder->codeAppendf(\"%s = vec4(vec2(%f, %f), vec2(%f, %f));\\n\", "
+ "args.fOutputColor, _outer.point().fX, _outer.point().fY, "
+ "_outer.point().fX, _outer.point().fY);",
+ "if (fPoint != that.fPoint) return false;"
+ });
+}
+
+DEF_TEST(SkSLFPUniform, r) {
+ test(r,
+ "uniform vec4 color;"
+ "void main() {"
+ "sk_OutColor = color;"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "static sk_sp<GrFragmentProcessor> Make()"
+ },
+ {
+ "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
+ "kDefault_GrSLPrecision, \"color\");",
+ });
+}
+
+DEF_TEST(SkSLFPInUniform, r) {
+ test(r,
+ "in uniform vec4 color;"
+ "void main() {"
+ "sk_OutColor = color;"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "static sk_sp<GrFragmentProcessor> Make(SkRect color) {",
+ },
+ {
+ "fColorVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, "
+ "kDefault_GrSLPrecision, \"color\");",
+ "const SkRect colorValue = _outer.color();",
+ "pdman.set4fv(fColorVar, 4, (float*) &colorValue);"
+ });
+}
+
+DEF_TEST(SkSLFPSections, r) {
+ test(r,
+ "@header { header section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "header section class GrTest",
+ },
+ {});
+ test(r,
+ "@class { class section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "class GrTest : public GrFragmentProcessor {\n"
+ "public:\n"
+ " class section"
+ },
+ {});
+ test(r,
+ "@cpp { cpp section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {},
+ {"cpp section"});
+ test(r,
+ "@constructorParams { int x, float y, std::vector<float> z }"
+ "in float w;"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "Make(float w, int x, float y, std::vector<float> z )",
+ "return sk_sp<GrFragmentProcessor>(new GrTest(w, x, y, z));",
+ "GrTest(float w, int x, float y, std::vector<float> z )",
+ ", fW(w) {"
+ },
+ {});
+ test(r,
+ "@constructor { constructor section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "private:\n constructor section"
+ },
+ {});
+ test(r,
+ "@initializers { initializers section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ ": INHERITED(kNone_OptimizationFlags)\n , initializers section"
+ },
+ {});
+ test(r,
+ "float x = 10;"
+ "@emitCode { fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2); }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {},
+ {
+ "x = 10.0;\n"
+ " fragBuilder->codeAppendf(\"float y = %d\\n\", x * 2);"
+ });
+ test(r,
+ "@fields { fields section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "GR_DECLARE_FRAGMENT_PROCESSOR_TEST;\n"
+ " fields section typedef GrFragmentProcessor INHERITED;"
+ },
+ {});
+ test(r,
+ "@make { make section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "public:\n"
+ " make section"
+ },
+ {});
+ test(r,
+ "uniform float calculated;"
+ "in float provided;"
+ "@setData(varName) { varName.set1f(calculated, provided * 2); }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {},
+ {
+ "void onSetData(const GrGLSLProgramDataManager& varName, "
+ "const GrFragmentProcessor& _proc) override {\n",
+ "UniformHandle& calculated = fCalculatedVar;",
+ "auto provided = _outer.provided();",
+ "varName.set1f(calculated, provided * 2);"
+ });
+ test(r,
+ "@test(testDataName) { testDataName section }"
+ "void main() {"
+ "sk_OutColor = vec4(1);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {},
+ {
+ "#if GR_TEST_UTILS\n"
+ "sk_sp<GrFragmentProcessor> GrTest::TestCreate(GrProcessorTestData* testDataName) {\n"
+ " testDataName section }\n"
+ "#endif"
+ });
+}
+
+DEF_TEST(SkSLFPColorSpaceXform, r) {
+ test(r,
+ "in uniform sampler2D image;"
+ "in uniform colorSpaceXform colorXform;"
+ "void main() {"
+ "sk_OutColor = sk_InColor * texture(image, vec2(0, 0), colorXform);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {
+ "sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }",
+ "GrTest(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform)",
+ "this->addTextureSampler(&fImage);",
+ "sk_sp<GrColorSpaceXform> fColorXform;"
+ },
+ {
+ "fragBuilder->codeAppendf(\"vec4 _tmp0;\\n%s = %s * "
+ "(_tmp0 = texture(%s, vec2(0.0, 0.0)) , %s != mat4(1.0) ? "
+ "vec4(clamp((%s * vec4(_tmp0.xyz, 1.0)).xyz, 0.0, _tmp0.w), _tmp0.w) : "
+ "_tmp0);\\n\", args.fOutputColor, args.fInputColor ? args.fInputColor : "
+ "\"vec4(1)\", fragBuilder->getProgramBuilder()->samplerVariable("
+ "args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? "
+ "args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "
+ "\"mat4(1.0)\", fColorSpaceHelper.isValid() ? "
+ "args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "
+ "\"mat4(1.0)\");"
+ });
+}
+
+DEF_TEST(SkSLFPTransformedCoords, r) {
+ test(r,
+ "void main() {"
+ "sk_OutColor = vec4(sk_TransformedCoords2D[0], sk_TransformedCoords2D[0]);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {},
+ {
+ "SkSL::String sk_TransformedCoords2D_0 = "
+ "fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);",
+ "fragBuilder->codeAppendf(\"%s = vec4(%s, %s);\\n\", args.fOutputColor, "
+ "sk_TransformedCoords2D_0.c_str(), sk_TransformedCoords2D_0.c_str());"
+ });
+
+}
+
+DEF_TEST(SkSLFPLayoutWhen, r) {
+ test(r,
+ "layout(when=someExpression(someOtherExpression())) uniform float sometimes;"
+ "void main() {"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ {},
+ {
+ "if (someExpression(someOtherExpression())) {\n"
+ " fSometimesVar = args.fUniformHandler->addUniform"
+ });
+
+}
+
+#endif