1 /*
2 * Copyright 2024 Google LLC
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 "include/core/SkTypes.h"
9 #include "src/sksl/SkSLCompiler.h"
10 #include "src/sksl/SkSLProgramKind.h"
11 #include "src/sksl/SkSLProgramSettings.h"
12 #include "src/sksl/SkSLUtil.h"
13 #include "src/sksl/codegen/SkSLPipelineStageCodeGenerator.h"
14 #include "src/sksl/ir/SkSLProgram.h"
15 #include "src/sksl/ir/SkSLVarDeclarations.h"
16 #include "tests/Test.h"
17
18 #include <memory>
19 #include <string>
20
test(skiatest::Reporter * r,const char * src,SkSL::ProgramKind kind=SkSL::ProgramKind::kPrivateRuntimeShader)21 static void test(skiatest::Reporter* r,
22 const char* src,
23 SkSL::ProgramKind kind = SkSL::ProgramKind::kPrivateRuntimeShader) {
24 // These callbacks match the behavior of skslc when given a .stage file.
25 class Callbacks : public SkSL::PipelineStage::Callbacks {
26 public:
27 std::string getMangledName(const char* name) override {
28 return std::string(name) + "_0";
29 }
30
31 std::string declareUniform(const SkSL::VarDeclaration* decl) override {
32 fOutput += decl->description();
33 return std::string(decl->var()->name());
34 }
35
36 void defineFunction(const char* decl, const char* body, bool /*isMain*/) override {
37 fOutput += std::string(decl) + '{' + body + '}';
38 }
39
40 void declareFunction(const char* decl) override { fOutput += decl; }
41
42 void defineStruct(const char* definition) override { fOutput += definition; }
43
44 void declareGlobal(const char* declaration) override { fOutput += declaration; }
45
46 std::string sampleShader(int index, std::string coords) override {
47 return "child_" + std::to_string(index) + ".eval(" + coords + ')';
48 }
49
50 std::string sampleColorFilter(int index, std::string color) override {
51 return "child_" + std::to_string(index) + ".eval(" + color + ')';
52 }
53
54 std::string sampleBlender(int index, std::string src, std::string dst) override {
55 return "child_" + std::to_string(index) + ".eval(" + src + ", " + dst + ')';
56 }
57
58 std::string toLinearSrgb(std::string color) override {
59 return "toLinearSrgb(" + color + ')';
60 }
61 std::string fromLinearSrgb(std::string color) override {
62 return "fromLinearSrgb(" + color + ')';
63 }
64
65 std::string fOutput;
66 };
67
68 SkSL::Compiler compiler;
69 SkSL::ProgramSettings settings;
70 std::unique_ptr<SkSL::Program> program = compiler.convertProgram(kind, std::string(src),
71 settings);
72 if (!program) {
73 SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
74 REPORTER_ASSERT(r, program);
75 } else {
76 Callbacks callbacks;
77 SkSL::PipelineStage::ConvertProgram(*program, "_coords", "_inColor",
78 "_canvasColor", &callbacks);
79 REPORTER_ASSERT(r, !callbacks.fOutput.empty());
80 // SkDebugf("Pipeline stage output:\n\n%s", callbacks.fOutput.c_str());
81 }
82 }
83
DEF_TEST(SkSLPipelineStageTestbed,r)84 DEF_TEST(SkSLPipelineStageTestbed, r) {
85 // Add in your SkSL here.
86 test(r,
87 R"__SkSL__(
88 half4 main(float2) {
89 return half4(0);
90 }
91 )__SkSL__");
92 }
93