• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "src/sksl/SkSLContext.h"
12 #include "src/sksl/SkSLString.h"
13 #include "src/sksl/ir/SkSLType.h"
14 #include "src/sksl/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
UniformCTypeMapper(Layout::CType ctype,const std::vector<String> & skslTypes,const char * setUniformFormat)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.
UniformCTypeMapper(Layout::CType ctype,const std::vector<String> & skslTypes,const String & setUniformFormat,const String & defaultValue,const String & dirtyExpressionFormat,const String & saveStateFormat)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 
Get(const Context & context,const Variable & variable)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
ctype()61     Layout::CType ctype() const {
62         return fCType;
63     }
64 
65     // The sksl type names that the mapper's ctype can be mapped to
supportedTypeNames()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
supportsTracking()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.
defaultValue()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.
canInlineUniformValue()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