Add DSLVar::swap method.

This gives DSLVar the ability to be set up after initial construction.
To do this, we create a plain empty Var, then swap it with the actual
Var we want afterwards. This allows DSL to support Vars which are
`uniform half4` in some cases and `const half4` (or entirely unused) in
other cases.

This technique was adapted from similar code in Ethan's parser CL.

Change-Id: Ic54d037a0102fda77b25d4755caf77a291eaa8c6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/400716
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2021-04-26 09:35:10 -04:00 committed by Skia Commit-Bot
parent c36aae31a4
commit 08771b00eb
3 changed files with 38 additions and 3 deletions

View File

@ -21,6 +21,11 @@ namespace dsl {
class DSLVar {
public:
/**
* Creates an empty, unpopulated DSLVar. Can be replaced with a real DSLVar later via `swap`.
*/
DSLVar() : fType(kVoid_Type), fDeclared(true) {}
/**
* 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
@ -44,6 +49,8 @@ public:
return fName;
}
void swap(DSLVar& other);
DSLExpression x() {
return DSLExpression(*this).x();
}
@ -125,11 +132,11 @@ private:
// 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;
int fUniformHandle = -1;
std::unique_ptr<SkSL::Statement> fDeclaration;
const SkSL::Variable* fVar = nullptr;
const char* fRawName; // for error reporting
const char* fName;
const char* fRawName = nullptr; // for error reporting
const char* fName = nullptr;
DSLExpression fInitialValue;
VariableStorage fStorage;
bool fDeclared = false;

View File

@ -117,6 +117,19 @@ DSLVar::~DSLVar() {
}
}
void DSLVar::swap(DSLVar& other) {
std::swap(fModifiers, other.fModifiers);
std::swap(fType, other.fType);
std::swap(fUniformHandle, other.fUniformHandle);
std::swap(fDeclaration, other.fDeclaration);
std::swap(fVar, other.fVar);
std::swap(fRawName, other.fRawName);
std::swap(fName, other.fName);
std::swap(fInitialValue.fExpression, other.fInitialValue.fExpression);
std::swap(fStorage, other.fStorage);
std::swap(fDeclared, other.fDeclared);
}
DSLPossibleExpression DSLVar::operator[](DSLExpression&& index) {
return DSLExpression(*this)[std::move(index)];
}

View File

@ -1372,6 +1372,21 @@ DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLSwizzle, r, ctxInfo) {
"a.z");
}
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLVarSwap, r, ctxInfo) {
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu(), /*markVarsDeclared=*/false);
// We should be able to convert `a` into a proper var by swapping it, even from within a scope.
Var a;
if (true)
{
Var(kInt_Type, "a").swap(a);
}
EXPECT_EQUAL(Statement(Block(Declare(a), a = 123)),
"{ int a; (a = 123); }");
}
DEF_GPUTEST_FOR_MOCK_CONTEXT(DSLWhile, r, ctxInfo) {
AutoDSLContext context(ctxInfo.directContext()->priv().getGpu());
Statement x = While(true, Block());