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