• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_GLSLCODEGENERATOR
9 #define SKSL_GLSLCODEGENERATOR
10 
11 #include <unordered_map>
12 
13 #include "src/sksl/SkSLOperators.h"
14 #include "src/sksl/SkSLStringStream.h"
15 #include "src/sksl/codegen/SkSLCodeGenerator.h"
16 
17 namespace SkSL {
18 
19 class BinaryExpression;
20 class Block;
21 class ConstructorDiagonalMatrix;
22 class ConstructorScalarCast;
23 class DoStatement;
24 class ExpressionStatement;
25 class Extension;
26 class FieldAccess;
27 class ForStatement;
28 class FunctionCall;
29 class FunctionDeclaration;
30 class FunctionDefinition;
31 class FunctionPrototype;
32 class IfStatement;
33 struct IndexExpression;
34 class InterfaceBlock;
35 class Literal;
36 class PostfixExpression;
37 class PrefixExpression;
38 class ReturnStatement;
39 class Setting;
40 class StructDefinition;
41 class SwitchStatement;
42 struct Swizzle;
43 class TernaryExpression;
44 class VarDeclaration;
45 class VariableReference;
46 
47 /**
48  * Converts a Program into GLSL code.
49  */
50 class GLSLCodeGenerator : public CodeGenerator {
51 public:
GLSLCodeGenerator(const Context * context,const Program * program,OutputStream * out)52     GLSLCodeGenerator(const Context* context, const Program* program, OutputStream* out)
53     : INHERITED(context, program, out)
54     , fLineEnding("\n") {}
55 
56     bool generateCode() override;
57 
58 protected:
59     using Precedence = Operator::Precedence;
60 
61     void write(std::string_view s);
62 
63     void writeLine(std::string_view s = std::string_view());
64 
65     void finishLine();
66 
67     virtual void writeHeader();
68 
69     virtual bool usesPrecisionModifiers() const;
70 
71     virtual std::string getTypeName(const Type& type);
72 
73     void writeStructDefinition(const StructDefinition& s);
74 
75     void writeType(const Type& type);
76 
77     void writeExtension(std::string_view name, bool require = true);
78 
79     void writeInterfaceBlock(const InterfaceBlock& intf);
80 
81     void writeFunctionStart(const FunctionDeclaration& f);
82 
83     void writeFunctionDeclaration(const FunctionDeclaration& f);
84 
85     void writeFunctionPrototype(const FunctionPrototype& f);
86 
87     virtual void writeFunction(const FunctionDefinition& f);
88 
89     void writeLayout(const Layout& layout);
90 
91     void writeModifiers(const Modifiers& modifiers, bool globalContext);
92 
93     virtual void writeInputVars();
94 
95     virtual void writeVarInitializer(const Variable& var, const Expression& value);
96 
97     const char* getTypePrecision(const Type& type);
98 
99     void writeTypePrecision(const Type& type);
100 
101     void writeVarDeclaration(const VarDeclaration& var, bool global);
102 
103     void writeFragCoord();
104 
105     virtual void writeVariableReference(const VariableReference& ref);
106 
107     void writeExpression(const Expression& expr, Precedence parentPrecedence);
108 
109     void writeIntrinsicCall(const FunctionCall& c);
110 
111     void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
112 
113     void writeDeterminantHack(const Expression& mat);
114 
115     void writeInverseHack(const Expression& mat);
116 
117     void writeTransposeHack(const Expression& mat);
118 
119     void writeInverseSqrtHack(const Expression& x);
120 
121     void writeMatrixComparisonWorkaround(const BinaryExpression& x);
122 
123     virtual void writeFunctionCall(const FunctionCall& c);
124 
125     void writeConstructorDiagonalMatrix(const ConstructorDiagonalMatrix& c,
126                                         Precedence parentPrecedence);
127 
128     virtual void writeAnyConstructor(const AnyConstructor& c, Precedence parentPrecedence);
129 
130     virtual void writeCastConstructor(const AnyConstructor& c, Precedence parentPrecedence);
131 
132     virtual void writeFieldAccess(const FieldAccess& f);
133 
134     virtual void writeSwizzle(const Swizzle& swizzle);
135 
136     virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
137 
138     void writeShortCircuitWorkaroundExpression(const BinaryExpression& b,
139                                                Precedence parentPrecedence);
140 
141     virtual void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
142 
143     virtual void writeIndexExpression(const IndexExpression& expr);
144 
145     void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
146 
147     void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
148 
149     virtual void writeLiteral(const Literal& l);
150 
151     virtual void writeSetting(const Setting& s);
152 
153     void writeStatement(const Statement& s);
154 
155     void writeBlock(const Block& b);
156 
157     virtual void writeIfStatement(const IfStatement& stmt);
158 
159     void writeForStatement(const ForStatement& f);
160 
161     void writeDoStatement(const DoStatement& d);
162 
163     void writeExpressionStatement(const ExpressionStatement& s);
164 
165     virtual void writeSwitchStatement(const SwitchStatement& s);
166 
167     virtual void writeReturnStatement(const ReturnStatement& r);
168 
169     virtual void writeProgramElement(const ProgramElement& e);
170 
caps()171     const ShaderCaps& caps() const { return fContext.fCaps; }
172 
173     const char* fLineEnding;
174     StringStream fExtensions;
175     StringStream fGlobals;
176     StringStream fExtraFunctions;
177     std::string fFunctionHeader;
178     int fVarCount = 0;
179     int fIndentation = 0;
180     bool fAtLineStart = false;
181     std::set<std::string> fWrittenIntrinsics;
182     // true if we have run into usages of dFdx / dFdy
183     bool fFoundDerivatives = false;
184     bool fFoundExternalSamplerDecl = false;
185     bool fFoundRectSamplerDecl = false;
186     bool fSetupClockwise = false;
187     bool fSetupFragPosition = false;
188     bool fSetupFragCoordWorkaround = false;
189     // if non-empty, replace all texture / texture2D / textureProj / etc. calls with this name
190     std::string fTextureFunctionOverride;
191 
192     // We map function names to function class so we can quickly deal with function calls that need
193     // extra processing
194     enum class FunctionClass {
195         kAbs,
196         kAtan,
197         kDeterminant,
198         kDFdx,
199         kDFdy,
200         kFwidth,
201         kFMA,
202         kFract,
203         kInverse,
204         kInverseSqrt,
205         kMin,
206         kPow,
207         kSaturate,
208         kTexture,
209         kTranspose
210     };
211     static std::unordered_map<std::string_view, FunctionClass>* fFunctionClasses;
212 
213     using INHERITED = CodeGenerator;
214 };
215 
216 }  // namespace SkSL
217 
218 #endif
219