1 /* 2 * Copyright 2018 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 SkSLUniformCTypes_DEFINED 9 #define SkSLUniformCTypes_DEFINED 10 11 #include "SkSLString.h" 12 #include "SkSLContext.h" 13 #include "ir/SkSLType.h" 14 #include "ir/SkSLVariable.h" 15 16 namespace SkSL { 17 18 // This uses templates to define dirtyExpression(), saveState() and setUniform(). Each template can 19 // reference token names formatted ${name} that are replaced with the actual values passed into the 20 // functions. 21 // 22 // dirtyExpression() and saveState() support the following tokens: 23 // - ${newVar} replaced with value of newValueVarName (1st argument) 24 // - ${oldVar} replaced with value of oldValueVarName (2nd argument) 25 // 26 // setUniform() supports these tokens: 27 // - ${pdman} replaced with value of pdmanName (1st argument) 28 // - ${uniform} replaced with value of uniformHandleName (2nd argument) 29 // - ${var} replaced with value of valueVarName (3rd argument) 30 // 31 // All templates and C++ snippets should produce valid expressions, but do not need to include 32 // semicolons or newlines, which will be handled by the code generation itself. 33 class UniformCTypeMapper { 34 public: 35 // Create a templated mapper that does not support state tracking 36 UniformCTypeMapper(Layout::CType ctype, const std::vector<String>& skslTypes, 37 const char* setUniformFormat) 38 : UniformCTypeMapper(ctype, skslTypes, setUniformFormat, false, "", "", "") { } 39 40 // Create a templated mapper that provides extra patterns for the state 41 // tracking expressions. 42 UniformCTypeMapper(Layout::CType ctype, const std::vector<String>& skslTypes, 43 const String& setUniformFormat, const String& defaultValue, 44 const String& dirtyExpressionFormat, const String& saveStateFormat) 45 : UniformCTypeMapper(ctype, skslTypes, setUniformFormat, 46 true, defaultValue, dirtyExpressionFormat, saveStateFormat) { } 47 48 // Returns nullptr if the type and layout are not supported; the returned pointer's ownership 49 // is not transfered to the caller. 50 // 51 // The returned mapper can support tracking even if tracking is disabled based on the flags in 52 // the layout. 53 static const UniformCTypeMapper* Get(const Context& context, const Type& type, 54 const Layout& layout); 55 56 static const UniformCTypeMapper* Get(const Context& context, const Variable& variable) { 57 return Get(context, variable.fType, variable.fModifiers.fLayout); 58 } 59 60 // The C++ type name that this mapper applies to 61 Layout::CType ctype() const { 62 return fCType; 63 } 64 65 // The sksl type names that the mapper's ctype can be mapped to 66 const std::vector<String>& supportedTypeNames() const { 67 return fSKSLTypes; 68 } 69 70 // Whether or not this handler knows how to write state tracking code 71 // for the uniform variables 72 bool supportsTracking() const { 73 return fSupportsTracking; 74 } 75 76 // What the C++ class fields are initialized to in the GLSLFragmentProcessor The empty string 77 // implies the no-arg constructor is suitable. This is not used if supportsTracking() returns 78 // false. 79 // 80 // The returned snippet will be a valid as the lhs of an assignment. 81 const String& defaultValue() const { 82 return fDefaultValue; 83 } 84 85 // Return a boolean expression that returns true if the variables specified by newValueVarName 86 // and oldValueVarName have different values. This is ignored if supportsTracking() returns 87 // false. 88 // 89 // The returned snippet will be a valid expression to be inserted into the condition of an 'if' 90 // statement. 91 String dirtyExpression(const String& newValueVarName, const String& oldValueVarName) const; 92 93 // Return a statement that stores the value of newValueVarName into the variable specified by 94 // oldValueVarName. This is ignored if supportsTracking() returns false. 95 // 96 // The returned snippet will be a valid expression. 97 String saveState(const String& newValueVarName, const String& oldValueVarName) const; 98 99 // Return a statement that invokes the appropriate setX method on the GrGLSLProgramDataManager 100 // specified by pdmanName, where the uniform is provided by the expression stored in 101 // uniformHandleName, and valueVarName is the variable name pointing to the ctype instance 102 // holding the new value. 103 // 104 // The returned snippet will be a valid expression. 105 String setUniform(const String& pdmanName, const String& uniformHandleName, 106 const String& valueVarName) const; 107 108 // True if the setUniform() template only uses the value variable once in its expression. The 109 // variable does not necessarily get inlined if this returns true, since a local variable may be 110 // needed if state tracking is employed for a particular uniform. 111 bool canInlineUniformValue() const { 112 return fInlineValue; 113 } 114 115 private: 116 UniformCTypeMapper(Layout::CType ctype, const std::vector<String>& skslTypes, 117 const String& setUniformFormat, bool enableTracking, const String& defaultValue, 118 const String& dirtyExpressionFormat, const String& saveStateFormat); 119 120 Layout::CType fCType; 121 std::vector<String> fSKSLTypes; 122 String fUniformTemplate; 123 bool fInlineValue; // Cached value calculated from fUniformTemplate 124 125 bool fSupportsTracking; 126 String fDefaultValue; 127 String fDirtyExpressionTemplate; 128 String fSaveStateTemplate; 129 }; 130 131 } // namespace 132 133 #endif // SkSLUniformCTypes_DEFINED 134