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_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