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