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 "SkSLLexer.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_INSTANCEID_BUILTIN              6
     30 #define SK_CLIPDISTANCE_BUILTIN            3
     31 #define SK_INVOCATIONID_BUILTIN            8
     32 #define SK_POSITION_BUILTIN                0
     33 
     34 namespace SkSL {
     35 
     36 class IRGenerator;
     37 
     38 /**
     39  * Main compiler entry point. This is a traditional compiler design which first parses the .sksl
     40  * file into an abstract syntax tree (a tree of ASTNodes), then performs semantic analysis to
     41  * produce a Program (a tree of IRNodes), then feeds the Program into a CodeGenerator to produce
     42  * compiled output.
     43  *
     44  * See the README for information about SkSL.
     45  */
     46 class Compiler : public ErrorReporter {
     47 public:
     48     static constexpr const char* RTADJUST_NAME  = "sk_RTAdjust";
     49     static constexpr const char* PERVERTEX_NAME = "sk_PerVertex";
     50 
     51     enum Flags {
     52         kNone_Flags = 0,
     53         // permits static if/switch statements to be used with non-constant tests. This is used when
     54         // producing H and CPP code; the static tests don't have to have constant values *yet*, but
     55         // the generated code will contain a static test which then does have to be a constant.
     56         kPermitInvalidStaticTests_Flag = 1,
     57     };
     58 
     59     Compiler(Flags flags = kNone_Flags);
     60 
     61     ~Compiler() override;
     62 
     63     std::unique_ptr<Program> convertProgram(Program::Kind kind, String text,
     64                                             const Program::Settings& settings);
     65 
     66     bool toSPIRV(const Program& program, OutputStream& out);
     67 
     68     bool toSPIRV(const Program& program, String* out);
     69 
     70     bool toGLSL(const Program& program, OutputStream& out);
     71 
     72     bool toGLSL(const Program& program, String* out);
     73 
     74     bool toMetal(const Program& program, OutputStream& out);
     75 
     76     bool toCPP(const Program& program, String name, OutputStream& out);
     77 
     78     bool toH(const Program& program, String name, OutputStream& out);
     79 
     80     void error(int offset, String msg) override;
     81 
     82     String errorText();
     83 
     84     void writeErrorCount();
     85 
     86     int errorCount() override {
     87         return fErrorCount;
     88     }
     89 
     90     static const char* OperatorName(Token::Kind token);
     91 
     92     static bool IsAssignment(Token::Kind token);
     93 
     94 private:
     95     void addDefinition(const Expression* lvalue, std::unique_ptr<Expression>* expr,
     96                        DefinitionMap* definitions);
     97 
     98     void addDefinitions(const BasicBlock::Node& node, DefinitionMap* definitions);
     99 
    100     void scanCFG(CFG* cfg, BlockId block, std::set<BlockId>* workList);
    101 
    102     void computeDataFlow(CFG* cfg);
    103 
    104     /**
    105      * Simplifies the expression pointed to by iter (in both the IR and CFG structures), if
    106      * possible.
    107      */
    108     void simplifyExpression(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     /**
    116      * Simplifies the statement pointed to by iter (in both the IR and CFG structures), if
    117      * possible.
    118      */
    119     void simplifyStatement(DefinitionMap& definitions,
    120                            BasicBlock& b,
    121                            std::vector<BasicBlock::Node>::iterator* iter,
    122                            std::unordered_set<const Variable*>* undefinedVariables,
    123                            bool* outUpdated,
    124                            bool* outNeedsRescan);
    125 
    126     void scanCFG(FunctionDefinition& f);
    127 
    128     Position position(int offset);
    129 
    130     std::shared_ptr<SymbolTable> fTypes;
    131     IRGenerator* fIRGenerator;
    132     String fSkiaVertText; // FIXME store parsed version instead
    133     int fFlags;
    134 
    135     const String* fSource;
    136     Context fContext;
    137     int fErrorCount;
    138     String fErrorText;
    139 };
    140 
    141 } // namespace
    142 
    143 #endif
    144