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