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_COMPILER 9 #define SKSL_COMPILER 10 11 #include <set> 12 #include <unordered_set> 13 #include <vector> 14 #include "ir/SkSLProgram.h" 15 #include "ir/SkSLSymbolTable.h" 16 #include "SkSLCFGGenerator.h" 17 #include "SkSLContext.h" 18 #include "SkSLErrorReporter.h" 19 #include "SkSLIRGenerator.h" 20 21 #define SK_FRAGCOLOR_BUILTIN 10001 22 #define SK_IN_BUILTIN 10002 23 #define SK_INCOLOR_BUILTIN 10003 24 #define SK_OUTCOLOR_BUILTIN 10004 25 #define SK_TRANSFORMEDCOORDS2D_BUILTIN 10005 26 #define SK_TEXTURESAMPLERS_BUILTIN 10006 27 #define SK_FRAGCOORD_BUILTIN 15 28 #define SK_VERTEXID_BUILTIN 5 29 #define SK_CLIPDISTANCE_BUILTIN 3 30 #define SK_INVOCATIONID_BUILTIN 8 31 32 namespace SkSL { 33 34 class IRGenerator; 35 36 /** 37 * Main compiler entry point. This is a traditional compiler design which first parses the .sksl 38 * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to 39 * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce 40 * compiled output. 41 * 42 * See the README for information about SkSL. 43 */ 44 class Compiler : public ErrorReporter { 45 public: 46 enum Flags { 47 kNone_Flags = 0, 48 // permits static if/switch statements to be used with non-constant tests. This is used when 49 // producing H and CPP code; the static tests don't have to have constant values *yet*, but 50 // the generated code will contain a static test which then does have to be a constant. 51 kPermitInvalidStaticTests_Flag = 1, 52 }; 53 54 Compiler(Flags flags = kNone_Flags); 55 56 ~Compiler() override; 57 58 std::unique_ptr<Program> convertProgram(Program::Kind kind, String text, 59 const Program::Settings& settings); 60 61 bool toSPIRV(const Program& program, OutputStream& out); 62 63 bool toSPIRV(const Program& program, String* out); 64 65 bool toGLSL(const Program& program, OutputStream& out); 66 67 bool toGLSL(const Program& program, String* out); 68 69 bool toCPP(const Program& program, String name, OutputStream& out); 70 71 bool toH(const Program& program, String name, OutputStream& out); 72 73 void error(Position position, String msg) override; 74 75 String errorText(); 76 77 void writeErrorCount(); 78 79 int errorCount() override { 80 return fErrorCount; 81 } 82 83 private: 84 void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr, 85 DefinitionMap* definitions); 86 87 void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions); 88 89 void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList); 90 91 void computeDataFlow(CFG* cfg); 92 93 /** 94 * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if 95 * possible. 96 */ 97 void simplifyExpression(DefinitionMap& definitions, 98 BasicBlock& b, 99 std::vector<BasicBlock::Node>::iterator* iter, 100 std::unordered_set<const Variable*>* undefinedVariables, 101 bool* outUpdated, 102 bool* outNeedsRescan); 103 104 /** 105 * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if 106 * possible. 107 */ 108 void simplifyStatement(DefinitionMap& definitions, 109 BasicBlock& b, 110 std::vector<BasicBlock::Node>::iterator* iter, 111 std::unordered_set<const Variable*>* undefinedVariables, 112 bool* outUpdated, 113 bool* outNeedsRescan); 114 115 void scanCFG(FunctionDefinition& f); 116 117 std::shared_ptr<SymbolTable> fTypes; 118 IRGenerator* fIRGenerator; 119 String fSkiaVertText; // FIXME store parsed version instead 120 int fFlags; 121 122 Context fContext; 123 int fErrorCount; 124 String fErrorText; 125 }; 126 127 } // namespace 128 129 #endif 130