Home | History | Annotate | Download | only in sksl
      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