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