• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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_SECTIONANDPARAMETERHELPER
9 #define SKSL_SECTIONANDPARAMETERHELPER
10 
11 #include "SkSLErrorReporter.h"
12 #include "ir/SkSLProgram.h"
13 #include "ir/SkSLSection.h"
14 #include "ir/SkSLVarDeclarations.h"
15 #include <unordered_map>
16 #include <vector>
17 
18 namespace SkSL {
19 
20 #define CLASS_SECTION              "class"
21 #define CONSTRUCTOR_SECTION        "constructor"
22 #define CONSTRUCTOR_CODE_SECTION   "constructorCode"
23 #define CONSTRUCTOR_PARAMS_SECTION "constructorParams"
24 #define COORD_TRANSFORM_SECTION    "coordTransform"
25 #define CPP_SECTION                "cpp"
26 #define CPP_END_SECTION            "cppEnd"
27 #define HEADER_SECTION             "header"
28 #define HEADER_END_SECTION         "headerEnd"
29 #define EMIT_CODE_SECTION          "emitCode"
30 #define FIELDS_SECTION             "fields"
31 #define INITIALIZERS_SECTION       "initializers"
32 #define MAKE_SECTION               "make"
33 #define OPTIMIZATION_FLAGS_SECTION "optimizationFlags"
34 #define SAMPLER_PARAMS_SECTION     "samplerParams"
35 #define SET_DATA_SECTION           "setData"
36 #define TEST_CODE_SECTION          "test"
37 
38 class SectionAndParameterHelper {
39 public:
SectionAndParameterHelper(const Program & program,ErrorReporter & errors)40     SectionAndParameterHelper(const Program& program, ErrorReporter& errors) {
41         for (const auto& p : program.fElements) {
42             switch (p->fKind) {
43                 case ProgramElement::kVar_Kind: {
44                     const VarDeclarations* decls = (const VarDeclarations*) p.get();
45                     for (const auto& raw : decls->fVars) {
46                         const VarDeclaration& decl = (VarDeclaration&) *raw;
47                         if (IsParameter(*decl.fVar)) {
48                             fParameters.push_back(decl.fVar);
49                         }
50                     }
51                     break;
52                 }
53                 case ProgramElement::kSection_Kind: {
54                     const Section* s = (const Section*) p.get();
55                     if (IsSupportedSection(s->fName.c_str())) {
56                         if (SectionAcceptsArgument(s->fName.c_str())) {
57                             if (!s->fArgument.size()) {
58                                 errors.error(s->fPosition,
59                                              ("section '@" + s->fName +
60                                               "' requires one parameter").c_str());
61                             }
62                         } else if (s->fArgument.size()) {
63                             errors.error(s->fPosition,
64                                          ("section '@" + s->fName + "' has no parameters").c_str());
65                         }
66                     } else {
67                         errors.error(s->fPosition,
68                                      ("unsupported section '@" + s->fName + "'").c_str());
69                     }
70                     if (!SectionPermitsDuplicates(s->fName.c_str()) &&
71                             fSections.find(s->fName) != fSections.end()) {
72                         errors.error(s->fPosition,
73                                      ("duplicate section '@" + s->fName + "'").c_str());
74                     }
75                     fSections[s->fName].push_back(s);
76                     break;
77                 }
78                 default:
79                     break;
80             }
81         }
82     }
83 
getSection(const char * name)84     const Section* getSection(const char* name) {
85         ASSERT(!SectionPermitsDuplicates(name));
86         auto found = fSections.find(name);
87         if (found == fSections.end()) {
88             return nullptr;
89         }
90         ASSERT(found->second.size() == 1);
91         return found->second[0];
92     }
93 
getSections(const char * name)94     std::vector<const Section*> getSections(const char* name) {
95         auto found = fSections.find(name);
96         if (found == fSections.end()) {
97             return std::vector<const Section*>();
98         }
99         return found->second;
100     }
101 
getParameters()102     const std::vector<const Variable*>& getParameters() {
103         return fParameters;
104     }
105 
IsParameter(const Variable & var)106     static bool IsParameter(const Variable& var) {
107         return (var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
108                -1 == var.fModifiers.fLayout.fBuiltin;
109     }
110 
IsSupportedSection(const char * name)111     static bool IsSupportedSection(const char* name) {
112         return !strcmp(name, CLASS_SECTION) ||
113                !strcmp(name, CONSTRUCTOR_SECTION) ||
114                !strcmp(name, CONSTRUCTOR_CODE_SECTION) ||
115                !strcmp(name, CONSTRUCTOR_PARAMS_SECTION) ||
116                !strcmp(name, COORD_TRANSFORM_SECTION) ||
117                !strcmp(name, CPP_SECTION) ||
118                !strcmp(name, CPP_END_SECTION) ||
119                !strcmp(name, EMIT_CODE_SECTION) ||
120                !strcmp(name, FIELDS_SECTION) ||
121                !strcmp(name, HEADER_SECTION) ||
122                !strcmp(name, HEADER_END_SECTION) ||
123                !strcmp(name, INITIALIZERS_SECTION) ||
124                !strcmp(name, MAKE_SECTION) ||
125                !strcmp(name, OPTIMIZATION_FLAGS_SECTION) ||
126                !strcmp(name, SAMPLER_PARAMS_SECTION) ||
127                !strcmp(name, SET_DATA_SECTION) ||
128                !strcmp(name, TEST_CODE_SECTION);
129     }
130 
SectionAcceptsArgument(const char * name)131     static bool SectionAcceptsArgument(const char* name) {
132         return !strcmp(name, COORD_TRANSFORM_SECTION) ||
133                !strcmp(name, SAMPLER_PARAMS_SECTION) ||
134                !strcmp(name, SET_DATA_SECTION) ||
135                !strcmp(name, TEST_CODE_SECTION);
136     }
137 
SectionPermitsDuplicates(const char * name)138     static bool SectionPermitsDuplicates(const char* name) {
139         return !strcmp(name, COORD_TRANSFORM_SECTION) ||
140                !strcmp(name, SAMPLER_PARAMS_SECTION);
141     }
142 
143 private:
144     std::vector<const Variable*> fParameters;
145     std::unordered_map<String, std::vector<const Section*>> fSections;
146 };
147 
148 } // namespace SkSL
149 
150 #endif
151