Home | History | Annotate | Download | only in sksl
      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 <stack>
     12 #include <tuple>
     13 #include <unordered_map>
     14 
     15 #include "SkSLCodeGenerator.h"
     16 #include "SkSLStringStream.h"
     17 #include "ir/SkSLBinaryExpression.h"
     18 #include "ir/SkSLBoolLiteral.h"
     19 #include "ir/SkSLConstructor.h"
     20 #include "ir/SkSLDoStatement.h"
     21 #include "ir/SkSLExtension.h"
     22 #include "ir/SkSLFloatLiteral.h"
     23 #include "ir/SkSLIfStatement.h"
     24 #include "ir/SkSLIndexExpression.h"
     25 #include "ir/SkSLInterfaceBlock.h"
     26 #include "ir/SkSLIntLiteral.h"
     27 #include "ir/SkSLFieldAccess.h"
     28 #include "ir/SkSLForStatement.h"
     29 #include "ir/SkSLFunctionCall.h"
     30 #include "ir/SkSLFunctionDeclaration.h"
     31 #include "ir/SkSLFunctionDefinition.h"
     32 #include "ir/SkSLPrefixExpression.h"
     33 #include "ir/SkSLPostfixExpression.h"
     34 #include "ir/SkSLProgramElement.h"
     35 #include "ir/SkSLReturnStatement.h"
     36 #include "ir/SkSLSetting.h"
     37 #include "ir/SkSLStatement.h"
     38 #include "ir/SkSLSwitchStatement.h"
     39 #include "ir/SkSLSwizzle.h"
     40 #include "ir/SkSLTernaryExpression.h"
     41 #include "ir/SkSLVarDeclarations.h"
     42 #include "ir/SkSLVarDeclarationsStatement.h"
     43 #include "ir/SkSLVariableReference.h"
     44 #include "ir/SkSLWhileStatement.h"
     45 
     46 namespace SkSL {
     47 
     48 #define kLast_Capability SpvCapabilityMultiViewport
     49 
     50 /**
     51  * Converts a Program into GLSL code.
     52  */
     53 class GLSLCodeGenerator : public CodeGenerator {
     54 public:
     55     enum Precedence {
     56         kParentheses_Precedence    =  1,
     57         kPostfix_Precedence        =  2,
     58         kPrefix_Precedence         =  3,
     59         kMultiplicative_Precedence =  4,
     60         kAdditive_Precedence       =  5,
     61         kShift_Precedence          =  6,
     62         kRelational_Precedence     =  7,
     63         kEquality_Precedence       =  8,
     64         kBitwiseAnd_Precedence     =  9,
     65         kBitwiseXor_Precedence     = 10,
     66         kBitwiseOr_Precedence      = 11,
     67         kLogicalAnd_Precedence     = 12,
     68         kLogicalXor_Precedence     = 13,
     69         kLogicalOr_Precedence      = 14,
     70         kTernary_Precedence        = 15,
     71         kAssignment_Precedence     = 16,
     72         kSequence_Precedence       = 17,
     73         kTopLevel_Precedence       = kSequence_Precedence
     74     };
     75 
     76     GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
     77                       OutputStream* out)
     78     : INHERITED(program, errors, out)
     79     , fLineEnding("\n")
     80     , fContext(*context)
     81     , fProgramKind(program->fKind) {}
     82 
     83     bool generateCode() override;
     84 
     85 protected:
     86     void write(const char* s);
     87 
     88     void writeLine();
     89 
     90     void writeLine(const char* s);
     91 
     92     void write(const String& s);
     93 
     94     void write(StringFragment s);
     95 
     96     void writeLine(const String& s);
     97 
     98     virtual void writeHeader();
     99 
    100     virtual bool usesPrecisionModifiers() const;
    101 
    102     virtual String getTypeName(const Type& type);
    103 
    104     void writeType(const Type& type);
    105 
    106     void writeExtension(const String& name);
    107 
    108     void writeExtension(const String& name, bool require);
    109 
    110     void writeInterfaceBlock(const InterfaceBlock& intf);
    111 
    112     void writeFunctionStart(const FunctionDeclaration& f);
    113 
    114     void writeFunctionDeclaration(const FunctionDeclaration& f);
    115 
    116     virtual void writeFunction(const FunctionDefinition& f);
    117 
    118     void writeLayout(const Layout& layout);
    119 
    120     void writeModifiers(const Modifiers& modifiers, bool globalContext);
    121 
    122     virtual void writeInputVars();
    123 
    124     virtual void writeVarInitializer(const Variable& var, const Expression& value);
    125 
    126     const char* getTypePrecision(const Type& type);
    127 
    128     void writeTypePrecision(const Type& type);
    129 
    130     void writeVarDeclarations(const VarDeclarations& decl, bool global);
    131 
    132     void writeFragCoord();
    133 
    134     virtual void writeVariableReference(const VariableReference& ref);
    135 
    136     void writeExpression(const Expression& expr, Precedence parentPrecedence);
    137 
    138     void writeIntrinsicCall(const FunctionCall& c);
    139 
    140     void writeMinAbsHack(Expression& absExpr, Expression& otherExpr);
    141 
    142     void writeDeterminantHack(const Expression& mat);
    143 
    144     void writeInverseHack(const Expression& mat);
    145 
    146     void writeTransposeHack(const Expression& mat);
    147 
    148     void writeInverseSqrtHack(const Expression& x);
    149 
    150     virtual void writeFunctionCall(const FunctionCall& c);
    151 
    152     void writeConstructor(const Constructor& c, Precedence parentPrecedence);
    153 
    154     virtual void writeFieldAccess(const FieldAccess& f);
    155 
    156     virtual void writeSwizzle(const Swizzle& swizzle);
    157 
    158     static Precedence GetBinaryPrecedence(Token::Kind op);
    159 
    160     virtual void writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
    161     void writeShortCircuitWorkaroundExpression(const BinaryExpression& b,
    162                                                Precedence parentPrecedence);
    163 
    164     void writeTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
    165 
    166     virtual void writeIndexExpression(const IndexExpression& expr);
    167 
    168     void writePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
    169 
    170     void writePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
    171 
    172     void writeBoolLiteral(const BoolLiteral& b);
    173 
    174     virtual void writeIntLiteral(const IntLiteral& i);
    175 
    176     void writeFloatLiteral(const FloatLiteral& f);
    177 
    178     virtual void writeSetting(const Setting& s);
    179 
    180     void writeStatement(const Statement& s);
    181 
    182     void writeStatements(const std::vector<std::unique_ptr<Statement>>& statements);
    183 
    184     void writeBlock(const Block& b);
    185 
    186     virtual void writeIfStatement(const IfStatement& stmt);
    187 
    188     void writeForStatement(const ForStatement& f);
    189 
    190     void writeWhileStatement(const WhileStatement& w);
    191 
    192     void writeDoStatement(const DoStatement& d);
    193 
    194     virtual void writeSwitchStatement(const SwitchStatement& s);
    195 
    196     virtual void writeReturnStatement(const ReturnStatement& r);
    197 
    198     virtual void writeProgramElement(const ProgramElement& e);
    199 
    200     const char* fLineEnding;
    201     const Context& fContext;
    202     StringStream fExtensions;
    203     StringStream fGlobals;
    204     StringStream fExtraFunctions;
    205     String fFunctionHeader;
    206     Program::Kind fProgramKind;
    207     int fVarCount = 0;
    208     int fIndentation = 0;
    209     bool fAtLineStart = false;
    210     // Keeps track of which struct types we have written. Given that we are unlikely to ever write
    211     // more than one or two structs per shader, a simple linear search will be faster than anything
    212     // fancier.
    213     std::vector<const Type*> fWrittenStructs;
    214     std::set<String> fWrittenIntrinsics;
    215     // true if we have run into usages of dFdx / dFdy
    216     bool fFoundDerivatives = false;
    217     bool fFoundImageDecl = false;
    218     bool fFoundExternalSamplerDecl = false;
    219     bool fFoundGSInvocations = false;
    220     bool fSetupFragPositionGlobal = false;
    221     bool fSetupFragPositionLocal = false;
    222     bool fSetupFragCoordWorkaround = false;
    223 
    224     // We map function names to function class so we can quickly deal with function calls that need
    225     // extra processing
    226     enum class FunctionClass {
    227         kAbs,
    228         kAtan,
    229         kDeterminant,
    230         kDFdx,
    231         kDFdy,
    232         kFwidth,
    233         kFMA,
    234         kFract,
    235         kInverse,
    236         kInverseSqrt,
    237         kMin,
    238         kPow,
    239         kSaturate,
    240         kTexture,
    241         kTranspose
    242     };
    243     static std::unordered_map<StringFragment, FunctionClass>* fFunctionClasses;
    244 
    245     typedef CodeGenerator INHERITED;
    246 };
    247 
    248 }
    249 
    250 #endif
    251