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 "src/sksl/SkSLErrorReporter.h"
12#include "src/sksl/ir/SkSLProgram.h"
13#include "src/sksl/ir/SkSLSection.h"
14#include "src/sksl/ir/SkSLVarDeclarations.h"
15#include <unordered_map>
16#include <vector>
17
18namespace SkSL {
19
20#define CLASS_SECTION "class"
21#define CLONE_SECTION "clone"
22#define CONSTRUCTOR_SECTION "constructor"
23#define CONSTRUCTOR_CODE_SECTION "constructorCode"
24#define CONSTRUCTOR_PARAMS_SECTION "constructorParams"
25#define COORD_TRANSFORM_SECTION "coordTransform"
26#define CPP_SECTION "cpp"
27#define CPP_END_SECTION "cppEnd"
28#define HEADER_SECTION "header"
29#define HEADER_END_SECTION "headerEnd"
30#define EMIT_CODE_SECTION "emitCode"
31#define FIELDS_SECTION "fields"
32#define INITIALIZERS_SECTION "initializers"
33#define MAKE_SECTION "make"
34#define OPTIMIZATION_FLAGS_SECTION "optimizationFlags"
35#define SAMPLER_PARAMS_SECTION "samplerParams"
36#define SET_DATA_SECTION "setData"
37#define TEST_CODE_SECTION "test"
38
39class SectionAndParameterHelper {
40public:
41 SectionAndParameterHelper(const Program* program, ErrorReporter& errors);
42
43 const Section* getSection(const char* name) {
44 SkASSERT(!SectionPermitsDuplicates(name));
45 auto found = fSections.find(name);
46 if (found == fSections.end()) {
47 return nullptr;
48 }
49 SkASSERT(found->second.size() == 1);
50 return found->second[0];
51 }
52
53 std::vector<const Section*> getSections(const char* name) {
54 auto found = fSections.find(name);
55 if (found == fSections.end()) {
56 return std::vector<const Section*>();
57 }
58 return found->second;
59 }
60
61 const std::vector<const Variable*>& getParameters() {
62 return fParameters;
63 }
64
65 bool hasCoordOverrides(const Variable& fp);
66
67 static bool IsParameter(const Variable& var) {
68 return (var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
69 -1 == var.fModifiers.fLayout.fBuiltin;
70 }
71
72 static bool IsSupportedSection(const char* name) {
73 return !strcmp(name, CLASS_SECTION) ||
74 !strcmp(name, CLONE_SECTION) ||
75 !strcmp(name, CONSTRUCTOR_SECTION) ||
76 !strcmp(name, CONSTRUCTOR_CODE_SECTION) ||
77 !strcmp(name, CONSTRUCTOR_PARAMS_SECTION) ||
78 !strcmp(name, COORD_TRANSFORM_SECTION) ||
79 !strcmp(name, CPP_SECTION) ||
80 !strcmp(name, CPP_END_SECTION) ||
81 !strcmp(name, EMIT_CODE_SECTION) ||
82 !strcmp(name, FIELDS_SECTION) ||
83 !strcmp(name, HEADER_SECTION) ||
84 !strcmp(name, HEADER_END_SECTION) ||
85 !strcmp(name, INITIALIZERS_SECTION) ||
86 !strcmp(name, MAKE_SECTION) ||
87 !strcmp(name, OPTIMIZATION_FLAGS_SECTION) ||
88 !strcmp(name, SAMPLER_PARAMS_SECTION) ||
89 !strcmp(name, SET_DATA_SECTION) ||
90 !strcmp(name, TEST_CODE_SECTION);
91 }
92
93 static bool SectionAcceptsArgument(const char* name) {
94 return !strcmp(name, COORD_TRANSFORM_SECTION) ||
95 !strcmp(name, SAMPLER_PARAMS_SECTION) ||
96 !strcmp(name, SET_DATA_SECTION) ||
97 !strcmp(name, TEST_CODE_SECTION);
98 }
99
100 static bool SectionRequiresArgument(const char* name) {
101 return !strcmp(name, SAMPLER_PARAMS_SECTION) ||
102 !strcmp(name, SET_DATA_SECTION) ||
103 !strcmp(name, TEST_CODE_SECTION);
104 }
105
106 static bool SectionPermitsDuplicates(const char* name) {
107 return !strcmp(name, COORD_TRANSFORM_SECTION) ||
108 !strcmp(name, SAMPLER_PARAMS_SECTION);
109 }
110
111private:
112 bool hasCoordOverrides(const Statement& s, const Variable& fp);
113
114 bool hasCoordOverrides(const Expression& e, const Variable& fp);
115
116 bool hasCoordOverrides(const ProgramElement& p, const Variable& fp);
117
118 const Program& fProgram;
119 std::vector<const Variable*> fParameters;
120 std::unordered_map<String, std::vector<const Section*>> fSections;
121};
122
123} // namespace SkSL
124
125#endif
126