skia2/include/sksl/DSLVar.h
Ethan Nicholas 707d31578c Refactored DSL variable creation
Prior to this change, we were creating the SkSL variable and declaration
immediately on DSLVar creation. This causes problems with function
parameters, which are sometimes supposed to be tagged
SK_MAIN_COORDS_BUILTIN. If we have already created the variable and
inserted it into the symbol table, then by the time we determine the
variable is supposed to be SK_MAIN_COORDS_BUILTIN, it is too late to
modify the (now-const) variable.

We are not yet doing this tagging, but refactoring the creation in this
fashion paves the way to making it possible.

Change-Id: I031170502c5e7c1fff5ecfac01bea470ff4e61ce
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/389216
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
2021-03-25 23:02:04 +00:00

151 lines
3.7 KiB
C++

/*
* Copyright 2020 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_DSL_VAR
#define SKSL_DSL_VAR
#include "include/sksl/DSLExpression.h"
#include "include/sksl/DSLModifiers.h"
#include "include/sksl/DSLType.h"
namespace SkSL {
class Variable;
enum class VariableStorage : int8_t;
namespace dsl {
class DSLVar {
public:
/**
* Constructs a new variable with the specified type and name. The name is used (in mangled
* form) in the resulting shader code; it is not otherwise important. Since mangling prevents
* name conflicts and the variable's name is only important when debugging shaders, the name
* parameter is optional.
*/
DSLVar(DSLType type, const char* name = "var", DSLExpression initialValue = DSLExpression());
DSLVar(DSLType type, DSLExpression initialValue);
DSLVar(DSLModifiers modifiers, DSLType type, const char* name = "var",
DSLExpression initialValue = DSLExpression());
DSLVar(DSLModifiers modifiers, DSLType type, DSLExpression initialValue);
DSLVar(DSLVar&&) = delete;
~DSLVar();
DSLExpression x() {
return DSLExpression(*this).x();
}
DSLExpression y() {
return DSLExpression(*this).y();
}
DSLExpression z() {
return DSLExpression(*this).z();
}
DSLExpression w() {
return DSLExpression(*this).w();
}
DSLExpression r() {
return DSLExpression(*this).r();
}
DSLExpression g() {
return DSLExpression(*this).g();
}
DSLExpression b() {
return DSLExpression(*this).b();
}
DSLExpression a() {
return DSLExpression(*this).a();
}
DSLExpression field(const char* name) {
return DSLExpression(*this).field(name);
}
DSLPossibleExpression operator=(DSLVar& var) {
return this->operator=(DSLExpression(var));
}
DSLPossibleExpression operator=(DSLExpression expr);
DSLPossibleExpression operator=(int expr) {
return this->operator=(DSLExpression(expr));
}
DSLPossibleExpression operator=(float expr) {
return this->operator=(DSLExpression(expr));
}
DSLPossibleExpression operator[](DSLExpression&& index);
DSLPossibleExpression operator++() {
return ++DSLExpression(*this);
}
DSLPossibleExpression operator++(int) {
return DSLExpression(*this)++;
}
DSLPossibleExpression operator--() {
return --DSLExpression(*this);
}
DSLPossibleExpression operator--(int) {
return DSLExpression(*this)--;
}
private:
/**
* Constructs a reference to a variable that already exists in the symbol table. This is used
* internally to reference built-in vars.
*/
DSLVar(const char* name);
const char* name() const {
return fName;
}
DSLModifiers fModifiers;
// We only need to keep track of the type here so that we can create the SkSL::Variable. For
// predefined variables this field is unnecessary, so we don't bother tracking it and just set
// it to kVoid; in other words, you shouldn't generally be relying on this field to be correct.
// If you need to determine the variable's type, look at DSLWriter::Var(...).type() instead.
DSLType fType;
int fUniformHandle;
std::unique_ptr<SkSL::Statement> fDeclaration;
const SkSL::Variable* fVar = nullptr;
const char* fRawName; // for error reporting
const char* fName;
DSLExpression fInitialValue;
VariableStorage fStorage;
bool fDeclared = false;
friend DSLVar sk_SampleCoord();
friend class DSLCore;
friend class DSLExpression;
friend class DSLFunction;
friend class DSLWriter;
};
} // namespace dsl
} // namespace SkSL
#endif