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/private/SkSLStatement.h" 12 #include "include/sksl/DSLExpression.h" 13 #include "include/sksl/DSLModifiers.h" 14 #include "include/sksl/DSLType.h" 15 #include "include/sksl/SkSLPosition.h" 16 17 #include <cstdint> 18 #include <memory> 19 #include <string_view> 20 #include <utility> 21 22 namespace SkSL { 23 24 class Expression; 25 class ExpressionArray; 26 class Variable; 27 enum class VariableStorage : int8_t; 28 29 namespace dsl { 30 31 class DSLVarBase { 32 public: 33 /** 34 * Constructs a new variable with the specified type and name. 35 */ 36 DSLVarBase(VariableStorage storage, DSLType type, std::string_view name, 37 DSLExpression initialValue, Position pos, Position namePos); 38 39 DSLVarBase(VariableStorage storage, const DSLModifiers& modifiers, DSLType type, 40 std::string_view name, DSLExpression initialValue, Position pos, Position namePos); 41 42 DSLVarBase(DSLVarBase&&) = default; 43 name()44 std::string_view name() const { 45 return fName; 46 } 47 modifiers()48 const DSLModifiers& modifiers() const { 49 return fModifiers; 50 } 51 storage()52 VariableStorage storage() const { 53 return fStorage; 54 } 55 x()56 DSLExpression x() { 57 return DSLExpression(*this).x(); 58 } 59 y()60 DSLExpression y() { 61 return DSLExpression(*this).y(); 62 } 63 z()64 DSLExpression z() { 65 return DSLExpression(*this).z(); 66 } 67 w()68 DSLExpression w() { 69 return DSLExpression(*this).w(); 70 } 71 r()72 DSLExpression r() { 73 return DSLExpression(*this).r(); 74 } 75 g()76 DSLExpression g() { 77 return DSLExpression(*this).g(); 78 } 79 b()80 DSLExpression b() { 81 return DSLExpression(*this).b(); 82 } 83 a()84 DSLExpression a() { 85 return DSLExpression(*this).a(); 86 } 87 field(std::string_view name)88 DSLExpression field(std::string_view name) { 89 return DSLExpression(*this).field(name); 90 } 91 92 DSLExpression operator[](DSLExpression&& index); 93 94 DSLExpression operator++() { 95 return ++DSLExpression(*this); 96 } 97 98 DSLExpression operator++(int) { 99 return DSLExpression(*this)++; 100 } 101 102 DSLExpression operator--() { 103 return --DSLExpression(*this); 104 } 105 106 DSLExpression operator--(int) { 107 return DSLExpression(*this)--; 108 } 109 assign(T && param)110 template <class T> DSLExpression assign(T&& param) { 111 return this->assignExpression(DSLExpression(std::forward<T>(param))); 112 } 113 114 protected: 115 /** 116 * Creates an empty, unpopulated var. Can be replaced with a real var later via `swap`. 117 */ DSLVarBase(VariableStorage storage)118 DSLVarBase(VariableStorage storage) : fType(kVoid_Type), fStorage(storage) {} 119 120 DSLExpression assignExpression(DSLExpression other); 121 122 void swap(DSLVarBase& other); 123 124 DSLModifiers fModifiers; 125 // We only need to keep track of the type here so that we can create the SkSL::Variable. For 126 // predefined variables this field is unnecessary, so we don't bother tracking it and just set 127 // it to kVoid; in other words, you shouldn't generally be relying on this field to be correct. 128 // If you need to determine the variable's type, look at DSLWriter::Var(...)->type() instead. 129 DSLType fType; 130 std::unique_ptr<SkSL::Statement> fDeclaration; 131 SkSL::Variable* fVar = nullptr; 132 Position fNamePosition; 133 std::string_view fName; 134 DSLExpression fInitialValue; 135 Position fPosition; 136 VariableStorage fStorage; 137 bool fInitialized = false; 138 139 friend class DSLCore; 140 friend class DSLFunction; 141 friend class DSLWriter; 142 }; 143 144 /** 145 * A local variable. 146 */ 147 class DSLVar : public DSLVarBase { 148 public: 149 DSLVar(); 150 151 DSLVar(DSLType type, std::string_view name, DSLExpression initialValue = DSLExpression(), 152 Position pos = {}, Position namePos = {}); 153 154 DSLVar(const DSLModifiers& modifiers, DSLType type, std::string_view name, 155 DSLExpression initialValue = DSLExpression(), Position pos = {}, Position namePos = {}); 156 157 DSLVar(DSLVar&&) = default; 158 159 void swap(DSLVar& other); 160 161 private: 162 using INHERITED = DSLVarBase; 163 }; 164 165 /** 166 * A global variable. 167 */ 168 class DSLGlobalVar : public DSLVarBase { 169 public: 170 DSLGlobalVar(); 171 172 DSLGlobalVar(DSLType type, std::string_view name, DSLExpression initialValue = DSLExpression(), 173 Position pos = {}, Position namePos = {}); 174 175 DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, std::string_view name, 176 DSLExpression initialValue = DSLExpression(), 177 Position pos = {}, Position namePos = {}); 178 179 DSLGlobalVar(const char* name); 180 181 DSLGlobalVar(DSLGlobalVar&&) = default; 182 183 void swap(DSLGlobalVar& other); 184 185 /** 186 * Implements the following method calls: 187 * half4 shader::eval(float2 coords); 188 * half4 colorFilter::eval(half4 input); 189 */ 190 DSLExpression eval(DSLExpression x, Position pos = {}); 191 192 /** 193 * Implements the following method call: 194 * half4 blender::eval(half4 src, half4 dst); 195 */ 196 DSLExpression eval(DSLExpression x, DSLExpression y, Position pos = {}); 197 198 private: 199 DSLExpression eval(ExpressionArray args, Position pos); 200 201 std::unique_ptr<SkSL::Expression> methodCall(std::string_view methodName, Position pos); 202 203 using INHERITED = DSLVarBase; 204 }; 205 206 /** 207 * A function parameter. 208 */ 209 class DSLParameter : public DSLVarBase { 210 public: 211 DSLParameter(); 212 213 DSLParameter(DSLType type, std::string_view name, Position pos = {}, Position namePos = {}); 214 215 DSLParameter(const DSLModifiers& modifiers, DSLType type, std::string_view name, 216 Position pos = {}, Position namePos = {}); 217 218 DSLParameter(DSLParameter&&) = default; 219 220 void swap(DSLParameter& other); 221 222 private: 223 using INHERITED = DSLVarBase; 224 }; 225 226 } // namespace dsl 227 228 } // namespace SkSL 229 230 231 #endif 232