• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MODIFIERS
9 #define SKSL_MODIFIERS
10 
11 #include "include/private/SkSLLayout.h"
12 
13 #include <vector>
14 
15 namespace SkSL {
16 
17 class Context;
18 
19 /**
20  * A set of modifier keywords (in, out, uniform, etc.) appearing before a declaration.
21  */
22 struct Modifiers {
23     /**
24      * OpenGL requires modifiers to be in a strict order:
25      * - invariant-qualifier:     (invariant)
26      * - interpolation-qualifier: flat, noperspective, (smooth)
27      * - storage-qualifier:       const, uniform
28      * - parameter-qualifier:     in, out, inout
29      * - precision-qualifier:     highp, mediump, lowp
30      *
31      * SkSL does not have `invariant` or `smooth`.
32      */
33 
34     enum Flag {
35         kNo_Flag             =       0,
36         // Real GLSL modifiers
37         kFlat_Flag           = 1 <<  0,
38         kNoPerspective_Flag  = 1 <<  1,
39         kConst_Flag          = 1 <<  2,
40         kUniform_Flag        = 1 <<  3,
41         kIn_Flag             = 1 <<  4,
42         kOut_Flag            = 1 <<  5,
43         kHighp_Flag          = 1 <<  6,
44         kMediump_Flag        = 1 <<  7,
45         kLowp_Flag           = 1 <<  8,
46         // SkSL extensions, not present in GLSL
47         kES3_Flag            = 1 <<  9,
48         kHasSideEffects_Flag = 1 <<  10,
49         kInline_Flag         = 1 <<  11,
50         kNoInline_Flag       = 1 <<  12,
51 #ifdef SKSL_EXT
52         kReadOnly_Flag       = 1 <<  13,
53         kWriteOnly_Flag      = 1 <<  14,
54         kBuffer_Flag         = 1 <<  15,
55 #endif
56     };
57 
ModifiersModifiers58     Modifiers()
59     : fLayout(Layout())
60     , fFlags(0) {}
61 
ModifiersModifiers62     Modifiers(const Layout& layout, int flags)
63     : fLayout(layout)
64     , fFlags(flags) {}
65 
descriptionModifiers66     String description() const {
67         String result = fLayout.description();
68 
69         // SkSL extensions
70         if (fFlags & kES3_Flag) {
71             result += "$es3 ";
72         }
73         if (fFlags & kHasSideEffects_Flag) {
74             result += "sk_has_side_effects ";
75         }
76         if (fFlags & kNoInline_Flag) {
77             result += "noinline ";
78         }
79 
80         // Real GLSL qualifiers (must be specified in order in GLSL 4.1 and below)
81         if (fFlags & kFlat_Flag) {
82             result += "flat ";
83         }
84         if (fFlags & kNoPerspective_Flag) {
85             result += "noperspective ";
86         }
87         if (fFlags & kConst_Flag) {
88             result += "const ";
89         }
90         if (fFlags & kUniform_Flag) {
91             result += "uniform ";
92         }
93         if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) {
94             result += "inout ";
95         } else if (fFlags & kIn_Flag) {
96             result += "in ";
97         } else if (fFlags & kOut_Flag) {
98             result += "out ";
99         }
100         if (fFlags & kHighp_Flag) {
101             result += "highp ";
102         }
103         if (fFlags & kMediump_Flag) {
104             result += "mediump ";
105         }
106         if (fFlags & kLowp_Flag) {
107             result += "lowp ";
108         }
109 #ifdef SKSL_EXT
110         if (fFlags & kReadOnly_Flag) {
111             result += "readonly ";
112         }
113         if (fFlags & kWriteOnly_Flag) {
114             result += "writeonly ";
115         }
116         if (fFlags & kBuffer_Flag) {
117             result += "buffer ";
118         }
119 #endif
120 
121         return result;
122     }
123 
124     bool operator==(const Modifiers& other) const {
125         return fLayout == other.fLayout && fFlags == other.fFlags;
126     }
127 
128     bool operator!=(const Modifiers& other) const {
129         return !(*this == other);
130     }
131 
132     /**
133      * Verifies that only permitted modifiers and layout flags are included. Reports errors and
134      * returns false in the event of a violation.
135      */
136     bool checkPermitted(const Context& context, int line, int permittedModifierFlags,
137             int permittedLayoutFlags) const;
138 
139     Layout fLayout;
140     int fFlags;
141 };
142 
143 } // namespace SkSL
144 
145 namespace std {
146 
147 template <>
148 struct hash<SkSL::Modifiers> {
149     size_t operator()(const SkSL::Modifiers& key) const {
150         return (size_t) key.fFlags ^ ((size_t) key.fLayout.fFlags << 8) ^
151                ((size_t) key.fLayout.fBuiltin << 16);
152     }
153 };
154 
155 } // namespace std
156 
157 #endif
158