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 }; 52 ModifiersModifiers53 Modifiers() 54 : fLayout(Layout()) 55 , fFlags(0) {} 56 ModifiersModifiers57 Modifiers(const Layout& layout, int flags) 58 : fLayout(layout) 59 , fFlags(flags) {} 60 descriptionModifiers61 String description() const { 62 String result = fLayout.description(); 63 64 // SkSL extensions 65 if (fFlags & kES3_Flag) { 66 result += "$es3 "; 67 } 68 if (fFlags & kHasSideEffects_Flag) { 69 result += "sk_has_side_effects "; 70 } 71 if (fFlags & kNoInline_Flag) { 72 result += "noinline "; 73 } 74 75 // Real GLSL qualifiers (must be specified in order in GLSL 4.1 and below) 76 if (fFlags & kFlat_Flag) { 77 result += "flat "; 78 } 79 if (fFlags & kNoPerspective_Flag) { 80 result += "noperspective "; 81 } 82 if (fFlags & kConst_Flag) { 83 result += "const "; 84 } 85 if (fFlags & kUniform_Flag) { 86 result += "uniform "; 87 } 88 if ((fFlags & kIn_Flag) && (fFlags & kOut_Flag)) { 89 result += "inout "; 90 } else if (fFlags & kIn_Flag) { 91 result += "in "; 92 } else if (fFlags & kOut_Flag) { 93 result += "out "; 94 } 95 if (fFlags & kHighp_Flag) { 96 result += "highp "; 97 } 98 if (fFlags & kMediump_Flag) { 99 result += "mediump "; 100 } 101 if (fFlags & kLowp_Flag) { 102 result += "lowp "; 103 } 104 105 return result; 106 } 107 108 bool operator==(const Modifiers& other) const { 109 return fLayout == other.fLayout && fFlags == other.fFlags; 110 } 111 112 bool operator!=(const Modifiers& other) const { 113 return !(*this == other); 114 } 115 116 /** 117 * Verifies that only permitted modifiers and layout flags are included. Reports errors and 118 * returns false in the event of a violation. 119 */ 120 bool checkPermitted(const Context& context, int line, int permittedModifierFlags, 121 int permittedLayoutFlags) const; 122 123 Layout fLayout; 124 int fFlags; 125 }; 126 127 } // namespace SkSL 128 129 namespace std { 130 131 template <> 132 struct hash<SkSL::Modifiers> { 133 size_t operator()(const SkSL::Modifiers& key) const { 134 return (size_t) key.fFlags ^ ((size_t) key.fLayout.fFlags << 8) ^ 135 ((size_t) key.fLayout.fBuiltin << 16); 136 } 137 }; 138 139 } // namespace std 140 141 #endif 142