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