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