xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLProgram.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2016 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SKSL_PROGRAM
9*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_PROGRAM
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/ir/SkSLType.h"
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
14*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
15*c8dee2aaSAndroid Build Coastguard Worker #include <string>
16*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker // name of the uniform used to handle features that are sensitive to whether Y is flipped.
19*c8dee2aaSAndroid Build Coastguard Worker #define SKSL_RTFLIP_NAME "u_skRTFlip"
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL {
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker class Context;
24*c8dee2aaSAndroid Build Coastguard Worker class FunctionDeclaration;
25*c8dee2aaSAndroid Build Coastguard Worker class Pool;
26*c8dee2aaSAndroid Build Coastguard Worker class ProgramElement;
27*c8dee2aaSAndroid Build Coastguard Worker class ProgramUsage;
28*c8dee2aaSAndroid Build Coastguard Worker class SymbolTable;
29*c8dee2aaSAndroid Build Coastguard Worker struct ProgramConfig;
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker /** Represents a list the Uniforms contained within a Program. */
32*c8dee2aaSAndroid Build Coastguard Worker struct UniformInfo {
33*c8dee2aaSAndroid Build Coastguard Worker     struct Uniform {
34*c8dee2aaSAndroid Build Coastguard Worker         std::string fName;
35*c8dee2aaSAndroid Build Coastguard Worker         SkSL::Type::NumberKind fKind;
36*c8dee2aaSAndroid Build Coastguard Worker         int fColumns;
37*c8dee2aaSAndroid Build Coastguard Worker         int fRows;
38*c8dee2aaSAndroid Build Coastguard Worker         int fSlot;
39*c8dee2aaSAndroid Build Coastguard Worker     };
40*c8dee2aaSAndroid Build Coastguard Worker     std::vector<Uniform> fUniforms;
41*c8dee2aaSAndroid Build Coastguard Worker     int fUniformSlotCount = 0;
42*c8dee2aaSAndroid Build Coastguard Worker };
43*c8dee2aaSAndroid Build Coastguard Worker 
44*c8dee2aaSAndroid Build Coastguard Worker /** A program's inputs and outputs. */
45*c8dee2aaSAndroid Build Coastguard Worker struct ProgramInterface {
46*c8dee2aaSAndroid Build Coastguard Worker     enum RTFlip : uint8_t {
47*c8dee2aaSAndroid Build Coastguard Worker         kRTFlip_None       = 0b0000'0000,
48*c8dee2aaSAndroid Build Coastguard Worker         kRTFlip_FragCoord  = 0b0000'0001,
49*c8dee2aaSAndroid Build Coastguard Worker         kRTFlip_Clockwise  = 0b0000'0010,
50*c8dee2aaSAndroid Build Coastguard Worker         kRTFlip_Derivative = 0b0000'0100,
51*c8dee2aaSAndroid Build Coastguard Worker     };
52*c8dee2aaSAndroid Build Coastguard Worker     uint8_t fRTFlipUniform = kRTFlip_None;
53*c8dee2aaSAndroid Build Coastguard Worker     bool fUseLastFragColor = false;
54*c8dee2aaSAndroid Build Coastguard Worker     bool fOutputSecondaryColor = false;
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     bool operator==(const ProgramInterface& that) const {
57*c8dee2aaSAndroid Build Coastguard Worker         return fRTFlipUniform == that.fRTFlipUniform &&
58*c8dee2aaSAndroid Build Coastguard Worker                fUseLastFragColor == that.fUseLastFragColor &&
59*c8dee2aaSAndroid Build Coastguard Worker                fOutputSecondaryColor == that.fOutputSecondaryColor;
60*c8dee2aaSAndroid Build Coastguard Worker     }
61*c8dee2aaSAndroid Build Coastguard Worker     bool operator!=(const ProgramInterface& that) const { return !(*this == that); }
62*c8dee2aaSAndroid Build Coastguard Worker };
63*c8dee2aaSAndroid Build Coastguard Worker 
64*c8dee2aaSAndroid Build Coastguard Worker /** Represents a fully-digested program, ready for code generation. */
65*c8dee2aaSAndroid Build Coastguard Worker struct Program {
66*c8dee2aaSAndroid Build Coastguard Worker     Program(std::unique_ptr<std::string> source,
67*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<ProgramConfig> config,
68*c8dee2aaSAndroid Build Coastguard Worker             std::shared_ptr<Context> context,
69*c8dee2aaSAndroid Build Coastguard Worker             std::vector<std::unique_ptr<ProgramElement>> elements,
70*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<SymbolTable> symbols,
71*c8dee2aaSAndroid Build Coastguard Worker             std::unique_ptr<Pool> pool);
72*c8dee2aaSAndroid Build Coastguard Worker 
73*c8dee2aaSAndroid Build Coastguard Worker     ~Program();
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker     class ElementsCollection {
76*c8dee2aaSAndroid Build Coastguard Worker     public:
77*c8dee2aaSAndroid Build Coastguard Worker         class iterator {
78*c8dee2aaSAndroid Build Coastguard Worker         public:
79*c8dee2aaSAndroid Build Coastguard Worker             const ProgramElement* operator*() {
80*c8dee2aaSAndroid Build Coastguard Worker                 if (fShared != fSharedEnd) {
81*c8dee2aaSAndroid Build Coastguard Worker                     return *fShared;
82*c8dee2aaSAndroid Build Coastguard Worker                 } else {
83*c8dee2aaSAndroid Build Coastguard Worker                     return fOwned->get();
84*c8dee2aaSAndroid Build Coastguard Worker                 }
85*c8dee2aaSAndroid Build Coastguard Worker             }
86*c8dee2aaSAndroid Build Coastguard Worker 
87*c8dee2aaSAndroid Build Coastguard Worker             iterator& operator++() {
88*c8dee2aaSAndroid Build Coastguard Worker                 if (fShared != fSharedEnd) {
89*c8dee2aaSAndroid Build Coastguard Worker                     ++fShared;
90*c8dee2aaSAndroid Build Coastguard Worker                 } else {
91*c8dee2aaSAndroid Build Coastguard Worker                     ++fOwned;
92*c8dee2aaSAndroid Build Coastguard Worker                 }
93*c8dee2aaSAndroid Build Coastguard Worker                 return *this;
94*c8dee2aaSAndroid Build Coastguard Worker             }
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker             bool operator==(const iterator& other) const {
97*c8dee2aaSAndroid Build Coastguard Worker                 return fOwned == other.fOwned && fShared == other.fShared;
98*c8dee2aaSAndroid Build Coastguard Worker             }
99*c8dee2aaSAndroid Build Coastguard Worker 
100*c8dee2aaSAndroid Build Coastguard Worker             bool operator!=(const iterator& other) const {
101*c8dee2aaSAndroid Build Coastguard Worker                 return !(*this == other);
102*c8dee2aaSAndroid Build Coastguard Worker             }
103*c8dee2aaSAndroid Build Coastguard Worker 
104*c8dee2aaSAndroid Build Coastguard Worker         private:
105*c8dee2aaSAndroid Build Coastguard Worker             using Owned  = std::vector<std::unique_ptr<ProgramElement>>::const_iterator;
106*c8dee2aaSAndroid Build Coastguard Worker             using Shared = std::vector<const ProgramElement*>::const_iterator;
107*c8dee2aaSAndroid Build Coastguard Worker             friend class ElementsCollection;
108*c8dee2aaSAndroid Build Coastguard Worker 
iteratorProgram109*c8dee2aaSAndroid Build Coastguard Worker             iterator(Owned owned, Owned ownedEnd, Shared shared, Shared sharedEnd)
110*c8dee2aaSAndroid Build Coastguard Worker                     : fOwned(owned), fOwnedEnd(ownedEnd), fShared(shared), fSharedEnd(sharedEnd) {}
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker             Owned  fOwned;
113*c8dee2aaSAndroid Build Coastguard Worker             Owned  fOwnedEnd;
114*c8dee2aaSAndroid Build Coastguard Worker             Shared fShared;
115*c8dee2aaSAndroid Build Coastguard Worker             Shared fSharedEnd;
116*c8dee2aaSAndroid Build Coastguard Worker         };
117*c8dee2aaSAndroid Build Coastguard Worker 
beginProgram118*c8dee2aaSAndroid Build Coastguard Worker         iterator begin() const {
119*c8dee2aaSAndroid Build Coastguard Worker             return iterator(fProgram.fOwnedElements.begin(), fProgram.fOwnedElements.end(),
120*c8dee2aaSAndroid Build Coastguard Worker                             fProgram.fSharedElements.begin(), fProgram.fSharedElements.end());
121*c8dee2aaSAndroid Build Coastguard Worker         }
122*c8dee2aaSAndroid Build Coastguard Worker 
endProgram123*c8dee2aaSAndroid Build Coastguard Worker         iterator end() const {
124*c8dee2aaSAndroid Build Coastguard Worker             return iterator(fProgram.fOwnedElements.end(), fProgram.fOwnedElements.end(),
125*c8dee2aaSAndroid Build Coastguard Worker                             fProgram.fSharedElements.end(), fProgram.fSharedElements.end());
126*c8dee2aaSAndroid Build Coastguard Worker         }
127*c8dee2aaSAndroid Build Coastguard Worker 
128*c8dee2aaSAndroid Build Coastguard Worker     private:
129*c8dee2aaSAndroid Build Coastguard Worker         friend struct Program;
130*c8dee2aaSAndroid Build Coastguard Worker 
ElementsCollectionProgram131*c8dee2aaSAndroid Build Coastguard Worker         ElementsCollection(const Program& program) : fProgram(program) {}
132*c8dee2aaSAndroid Build Coastguard Worker         const Program& fProgram;
133*c8dee2aaSAndroid Build Coastguard Worker     };
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     /**
136*c8dee2aaSAndroid Build Coastguard Worker      * Iterates over *all* elements in this Program, both owned and shared (builtin). The iterator's
137*c8dee2aaSAndroid Build Coastguard Worker      * value type is `const ProgramElement*`, so it's clear that you *must not* modify anything (as
138*c8dee2aaSAndroid Build Coastguard Worker      * you might be mutating shared data).
139*c8dee2aaSAndroid Build Coastguard Worker      */
elementsProgram140*c8dee2aaSAndroid Build Coastguard Worker     ElementsCollection elements() const { return ElementsCollection(*this); }
141*c8dee2aaSAndroid Build Coastguard Worker 
142*c8dee2aaSAndroid Build Coastguard Worker     /**
143*c8dee2aaSAndroid Build Coastguard Worker      * Returns a function declaration with the given name; null is returned if the function doesn't
144*c8dee2aaSAndroid Build Coastguard Worker      * exist or has no definition. If the function might have overloads, you can use nextOverload()
145*c8dee2aaSAndroid Build Coastguard Worker      * to search for the function with the expected parameter list.
146*c8dee2aaSAndroid Build Coastguard Worker      */
147*c8dee2aaSAndroid Build Coastguard Worker     const FunctionDeclaration* getFunction(const char* functionName) const;
148*c8dee2aaSAndroid Build Coastguard Worker 
149*c8dee2aaSAndroid Build Coastguard Worker     std::string description() const;
usageProgram150*c8dee2aaSAndroid Build Coastguard Worker     const ProgramUsage* usage() const { return fUsage.get(); }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<std::string> fSource;
153*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<ProgramConfig> fConfig;
154*c8dee2aaSAndroid Build Coastguard Worker     std::shared_ptr<Context> fContext;
155*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<ProgramUsage> fUsage;
156*c8dee2aaSAndroid Build Coastguard Worker     // it's important to keep fOwnedElements defined after (and thus destroyed before) fSymbols,
157*c8dee2aaSAndroid Build Coastguard Worker     // because an IR element might access the symbol table during its destruction
158*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SymbolTable> fSymbols;
159*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<Pool> fPool;
160*c8dee2aaSAndroid Build Coastguard Worker     // Contains *only* elements owned exclusively by this program.
161*c8dee2aaSAndroid Build Coastguard Worker     std::vector<std::unique_ptr<ProgramElement>> fOwnedElements;
162*c8dee2aaSAndroid Build Coastguard Worker     // Contains *only* elements owned by a built-in module that are included in this program.
163*c8dee2aaSAndroid Build Coastguard Worker     // Use elements() to iterate over the combined set of owned + shared elements.
164*c8dee2aaSAndroid Build Coastguard Worker     std::vector<const ProgramElement*> fSharedElements;
165*c8dee2aaSAndroid Build Coastguard Worker     ProgramInterface fInterface;
166*c8dee2aaSAndroid Build Coastguard Worker 
167*c8dee2aaSAndroid Build Coastguard Worker     using Interface = ProgramInterface;
168*c8dee2aaSAndroid Build Coastguard Worker };
169*c8dee2aaSAndroid Build Coastguard Worker 
170*c8dee2aaSAndroid Build Coastguard Worker }  // namespace SkSL
171*c8dee2aaSAndroid Build Coastguard Worker 
172*c8dee2aaSAndroid Build Coastguard Worker #endif
173