1 /* 2 * Copyright 2020 Google LLC 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_DSL_VAR 9 #define SKSL_DSL_VAR 10 11 #include "include/sksl/DSLExpression.h" 12 #include "include/sksl/DSLModifiers.h" 13 #include "include/sksl/DSLType.h" 14 15 namespace SkSL { 16 17 class Expression; 18 class IRGenerator; 19 class SPIRVCodeGenerator; 20 class Variable; 21 enum class VariableStorage : int8_t; 22 23 namespace dsl { 24 25 class DSLVarBase { 26 public: 27 /** 28 * Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`. 29 */ DSLVarBase()30 DSLVarBase() : fType(kVoid_Type), fDeclared(true) {} 31 32 /** 33 * Constructs a new variable with the specified type and name. The name is used (in mangled 34 * form) in the resulting shader code; it is not otherwise important. Since mangling prevents 35 * name conflicts and the variable's name is only important when debugging shaders, the name 36 * parameter is optional. 37 */ 38 DSLVarBase(DSLType type, skstd::string_view name, DSLExpression initialValue, PositionInfo pos); 39 40 DSLVarBase(DSLType type, DSLExpression initialValue, PositionInfo pos); 41 42 DSLVarBase(const DSLModifiers& modifiers, DSLType type, skstd::string_view name, 43 DSLExpression initialValue, PositionInfo pos); 44 45 DSLVarBase(const DSLModifiers& modifiers, DSLType type, DSLExpression initialValue, 46 PositionInfo pos); 47 48 DSLVarBase(DSLVarBase&&) = default; 49 50 virtual ~DSLVarBase(); 51 name()52 skstd::string_view name() const { 53 return fName; 54 } 55 modifiers()56 const DSLModifiers& modifiers() const { 57 return fModifiers; 58 } 59 60 virtual VariableStorage storage() const = 0; 61 x()62 DSLExpression x() { 63 return DSLExpression(*this, PositionInfo()).x(); 64 } 65 y()66 DSLExpression y() { 67 return DSLExpression(*this, PositionInfo()).y(); 68 } 69 z()70 DSLExpression z() { 71 return DSLExpression(*this, PositionInfo()).z(); 72 } 73 w()74 DSLExpression w() { 75 return DSLExpression(*this, PositionInfo()).w(); 76 } 77 r()78 DSLExpression r() { 79 return DSLExpression(*this, PositionInfo()).r(); 80 } 81 g()82 DSLExpression g() { 83 return DSLExpression(*this, PositionInfo()).g(); 84 } 85 b()86 DSLExpression b() { 87 return DSLExpression(*this, PositionInfo()).b(); 88 } 89 a()90 DSLExpression a() { 91 return DSLExpression(*this, PositionInfo()).a(); 92 } 93 field(skstd::string_view name)94 DSLExpression field(skstd::string_view name) { 95 return DSLExpression(*this, PositionInfo()).field(name); 96 } 97 98 DSLPossibleExpression operator[](DSLExpression&& index); 99 100 DSLPossibleExpression operator++() { 101 return ++DSLExpression(*this, PositionInfo()); 102 } 103 104 DSLPossibleExpression operator++(int) { 105 return DSLExpression(*this, PositionInfo())++; 106 } 107 108 DSLPossibleExpression operator--() { 109 return --DSLExpression(*this, PositionInfo()); 110 } 111 112 DSLPossibleExpression operator--(int) { 113 return DSLExpression(*this, PositionInfo())--; 114 } 115 116 protected: 117 DSLPossibleExpression assign(DSLExpression other); 118 119 void swap(DSLVarBase& other); 120 121 DSLModifiers fModifiers; 122 // We only need to keep track of the type here so that we can create the SkSL::Variable. For 123 // predefined variables this field is unnecessary, so we don't bother tracking it and just set 124 // it to kVoid; in other words, you shouldn't generally be relying on this field to be correct. 125 // If you need to determine the variable's type, look at DSLWriter::Var(...)->type() instead. 126 DSLType fType; 127 int fUniformHandle = -1; 128 std::unique_ptr<SkSL::Statement> fDeclaration; 129 const SkSL::Variable* fVar = nullptr; 130 skstd::string_view fRawName; // for error reporting 131 skstd::string_view fName; 132 DSLExpression fInitialValue; 133 // true if we have attempted to create the SkSL var 134 bool fInitialized = false; 135 bool fDeclared = false; 136 PositionInfo fPosition; 137 138 friend class DSLCore; 139 friend class DSLExpression; 140 friend class DSLFunction; 141 friend class DSLWriter; 142 friend class ::SkSL::IRGenerator; 143 friend class ::SkSL::SPIRVCodeGenerator; 144 }; 145 146 /** 147 * A local variable. 148 */ 149 class DSLVar : public DSLVarBase { 150 public: 151 DSLVar() = default; 152 153 DSLVar(DSLType type, skstd::string_view name = "var", 154 DSLExpression initialValue = DSLExpression(), 155 PositionInfo pos = PositionInfo::Capture()) INHERITED(type,name,std::move (initialValue),pos)156 : INHERITED(type, name, std::move(initialValue), pos) {} 157 158 DSLVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression(), 159 PositionInfo pos = PositionInfo::Capture()) DSLVar(type,skstd::string_view (name),std::move (initialValue),pos)160 : DSLVar(type, skstd::string_view(name), std::move(initialValue), pos) {} 161 162 DSLVar(DSLType type, DSLExpression initialValue, PositionInfo pos = PositionInfo::Capture()) INHERITED(type,std::move (initialValue),pos)163 : INHERITED(type, std::move(initialValue), pos) {} 164 165 DSLVar(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var", 166 DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture()) INHERITED(modifiers,type,name,std::move (initialValue),pos)167 : INHERITED(modifiers, type, name, std::move(initialValue), pos) {} 168 169 DSLVar(const DSLModifiers& modifiers, DSLType type, const char* name, 170 DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture()) DSLVar(modifiers,type,skstd::string_view (name),std::move (initialValue),pos)171 : DSLVar(modifiers, type, skstd::string_view(name), std::move(initialValue), pos) {} 172 173 DSLVar(DSLVar&&) = default; 174 175 VariableStorage storage() const override; 176 177 void swap(DSLVar& other); 178 179 DSLPossibleExpression operator=(DSLExpression expr); 180 181 DSLPossibleExpression operator=(DSLVar& param) { 182 return this->operator=(DSLExpression(param)); 183 } 184 185 template<class Param> 186 DSLPossibleExpression operator=(Param& param) { 187 return this->operator=(DSLExpression(param)); 188 } 189 190 private: 191 using INHERITED = DSLVarBase; 192 }; 193 194 /** 195 * A global variable. 196 */ 197 class DSLGlobalVar : public DSLVarBase { 198 public: 199 DSLGlobalVar() = default; 200 201 DSLGlobalVar(DSLType type, skstd::string_view name = "var", 202 DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture()) INHERITED(type,name,std::move (initialValue),pos)203 : INHERITED(type, name, std::move(initialValue), pos) {} 204 205 DSLGlobalVar(DSLType type, const char* name, DSLExpression initialValue = DSLExpression(), 206 PositionInfo pos = PositionInfo::Capture()) DSLGlobalVar(type,skstd::string_view (name),std::move (initialValue),pos)207 : DSLGlobalVar(type, skstd::string_view(name), std::move(initialValue), pos) {} 208 209 DSLGlobalVar(DSLType type, DSLExpression initialValue, 210 PositionInfo pos = PositionInfo::Capture()) INHERITED(type,std::move (initialValue),pos)211 : INHERITED(type, std::move(initialValue), pos) {} 212 213 DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var", 214 DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture()) INHERITED(modifiers,type,name,std::move (initialValue),pos)215 : INHERITED(modifiers, type, name, std::move(initialValue), pos) {} 216 217 DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, const char* name, 218 DSLExpression initialValue = DSLExpression(), PositionInfo pos = PositionInfo::Capture()) DSLGlobalVar(modifiers,type,skstd::string_view (name),std::move (initialValue),pos)219 : DSLGlobalVar(modifiers, type, skstd::string_view(name), std::move(initialValue), pos) {} 220 221 DSLGlobalVar(const char* name); 222 223 DSLGlobalVar(DSLGlobalVar&&) = default; 224 225 VariableStorage storage() const override; 226 227 void swap(DSLGlobalVar& other); 228 229 DSLPossibleExpression operator=(DSLExpression expr); 230 231 DSLPossibleExpression operator=(DSLGlobalVar& param) { 232 return this->operator=(DSLExpression(param)); 233 } 234 235 template<class Param> 236 DSLPossibleExpression operator=(Param& param) { 237 return this->operator=(DSLExpression(param)); 238 } 239 240 /** 241 * Implements the following method calls: 242 * half4 shader::eval(float2 coords); 243 * half4 colorFilter::eval(half4 input); 244 */ 245 DSLExpression eval(DSLExpression x, PositionInfo pos = PositionInfo::Capture()); 246 247 /** 248 * Implements the following method call: 249 * half4 blender::eval(half4 src, half4 dst); 250 */ 251 DSLExpression eval(DSLExpression x, DSLExpression y, 252 PositionInfo pos = PositionInfo::Capture()); 253 254 private: 255 DSLExpression eval(ExpressionArray args, PositionInfo pos); 256 257 std::unique_ptr<SkSL::Expression> methodCall(skstd::string_view methodName, PositionInfo pos); 258 259 using INHERITED = DSLVarBase; 260 }; 261 262 /** 263 * A function parameter. 264 */ 265 class DSLParameter : public DSLVarBase { 266 public: 267 DSLParameter() = default; 268 269 DSLParameter(DSLType type, skstd::string_view name = "var", 270 PositionInfo pos = PositionInfo::Capture()) INHERITED(type,name,DSLExpression (),pos)271 : INHERITED(type, name, DSLExpression(), pos) {} 272 273 DSLParameter(DSLType type, const char* name, PositionInfo pos = PositionInfo::Capture()) DSLParameter(type,skstd::string_view (name),pos)274 : DSLParameter(type, skstd::string_view(name), pos) {} 275 276 DSLParameter(const DSLModifiers& modifiers, DSLType type, skstd::string_view name = "var", 277 PositionInfo pos = PositionInfo::Capture()) INHERITED(modifiers,type,name,DSLExpression (),pos)278 : INHERITED(modifiers, type, name, DSLExpression(), pos) {} 279 280 DSLParameter(const DSLModifiers& modifiers, DSLType type, const char* name, 281 PositionInfo pos = PositionInfo::Capture()) DSLParameter(modifiers,type,skstd::string_view (name),pos)282 : DSLParameter(modifiers, type, skstd::string_view(name), pos) {} 283 284 DSLParameter(DSLParameter&&) = default; 285 286 VariableStorage storage() const override; 287 288 void swap(DSLParameter& other); 289 290 DSLPossibleExpression operator=(DSLExpression expr); 291 292 DSLPossibleExpression operator=(DSLParameter& param) { 293 return this->operator=(DSLExpression(param)); 294 } 295 296 template<class Param> 297 DSLPossibleExpression operator=(Param& param) { 298 return this->operator=(DSLExpression(param)); 299 } 300 301 private: 302 using INHERITED = DSLVarBase; 303 }; 304 305 } // namespace dsl 306 307 } // namespace SkSL 308 309 310 #endif 311