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