xref: /aosp_15_r20/external/skia/tests/SkSLPipelineStageTestbed.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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