Add Convert/Make factory functions to FieldAccess.
Change-Id: Ib1f5296c017374b833654f988ff89d11d8f78b4d Bug: skia:11342 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/380458 Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
ece1bf0afb
commit
06d600fb9d
@ -105,6 +105,7 @@ skia_sksl_sources = [
|
||||
"$_src/sksl/ir/SkSLExternalFunctionCall.h",
|
||||
"$_src/sksl/ir/SkSLExternalFunctionReference.h",
|
||||
"$_src/sksl/ir/SkSLField.h",
|
||||
"$_src/sksl/ir/SkSLFieldAccess.cpp",
|
||||
"$_src/sksl/ir/SkSLFieldAccess.h",
|
||||
"$_src/sksl/ir/SkSLFloatLiteral.h",
|
||||
"$_src/sksl/ir/SkSLForStatement.cpp",
|
||||
|
@ -821,12 +821,12 @@ std::unique_ptr<Statement> IRGenerator::getNormalizeSkPositionCode() {
|
||||
VariableReference::RefKind::kWrite);
|
||||
};
|
||||
auto Field = [&](const Variable* var, int idx) -> std::unique_ptr<Expression> {
|
||||
return std::make_unique<FieldAccess>(Ref(var), idx,
|
||||
FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
|
||||
return FieldAccess::Make(fContext, Ref(var), idx,
|
||||
FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
|
||||
};
|
||||
auto Pos = [&]() -> std::unique_ptr<Expression> {
|
||||
return std::make_unique<FieldAccess>(WRef(skPerVertex), 0,
|
||||
FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
|
||||
return FieldAccess::Make(fContext, WRef(skPerVertex), 0,
|
||||
FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
|
||||
};
|
||||
auto Adjust = [&]() -> std::unique_ptr<Expression> {
|
||||
return fRTAdjustInterfaceBlock ? Field(fRTAdjustInterfaceBlock, fRTAdjustFieldIndex)
|
||||
@ -1577,9 +1577,8 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(int offset, StringFra
|
||||
const Field* field = &result->as<Field>();
|
||||
auto base = std::make_unique<VariableReference>(offset, &field->owner(),
|
||||
VariableReference::RefKind::kRead);
|
||||
return std::make_unique<FieldAccess>(std::move(base),
|
||||
field->fieldIndex(),
|
||||
FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
|
||||
return FieldAccess::Make(fContext, std::move(base), field->fieldIndex(),
|
||||
FieldAccess::OwnerKind::kAnonymousInterfaceBlock);
|
||||
}
|
||||
case Symbol::Kind::kType: {
|
||||
const Type* t = &result->as<Type>();
|
||||
@ -1837,21 +1836,6 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode&
|
||||
return PrefixExpression::Convert(fContext, expression.getOperator(), std::move(base));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression> base,
|
||||
StringFragment field) {
|
||||
const Type& baseType = base->type();
|
||||
auto fields = baseType.fields();
|
||||
for (size_t i = 0; i < fields.size(); i++) {
|
||||
if (fields[i].fName == field) {
|
||||
return std::unique_ptr<Expression>(new FieldAccess(std::move(base), (int) i));
|
||||
}
|
||||
}
|
||||
this->errorReporter().error(
|
||||
base->fOffset,
|
||||
"type '" + baseType.displayName() + "' does not have a field named '" + field + "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Swizzles are complicated due to constant components. The most difficult case is a mask like
|
||||
// '.x1w0'. A naive approach might turn that into 'float4(base.x, 1, base.w, 0)', but that evaluates
|
||||
// 'base' twice. We instead group the swizzle mask ('xw') and constants ('1, 0') together and use a
|
||||
@ -2045,12 +2029,10 @@ std::unique_ptr<Expression> IRGenerator::convertFieldExpression(const ASTNode& f
|
||||
if (baseType == *fContext.fTypes.fSkCaps) {
|
||||
return Setting::Convert(fContext, fieldNode.fOffset, field);
|
||||
}
|
||||
switch (baseType.typeKind()) {
|
||||
case Type::TypeKind::kStruct:
|
||||
return this->convertField(std::move(base), field);
|
||||
default:
|
||||
return this->convertSwizzle(std::move(base), field);
|
||||
if (baseType.isStruct()) {
|
||||
return FieldAccess::Convert(fContext, std::move(base), field);
|
||||
}
|
||||
return this->convertSwizzle(std::move(base), field);
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::convertScopeExpression(const ASTNode& scopeNode) {
|
||||
|
@ -345,7 +345,7 @@ std::unique_ptr<Expression> Inliner::inlineExpression(int offset,
|
||||
return expression.clone();
|
||||
case Expression::Kind::kFieldAccess: {
|
||||
const FieldAccess& f = expression.as<FieldAccess>();
|
||||
return std::make_unique<FieldAccess>(expr(f.base()), f.fieldIndex(), f.ownerKind());
|
||||
return FieldAccess::Make(*fContext, expr(f.base()), f.fieldIndex(), f.ownerKind());
|
||||
}
|
||||
case Expression::Kind::kFunctionCall: {
|
||||
const FunctionCall& funcCall = expression.as<FunctionCall>();
|
||||
|
@ -469,7 +469,7 @@ std::unique_ptr<Expression> Rehydrator::expression() {
|
||||
std::unique_ptr<Expression> base = this->expression();
|
||||
int index = this->readU8();
|
||||
FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
|
||||
return std::make_unique<FieldAccess>(std::move(base), index, ownerKind);
|
||||
return FieldAccess::Make(fContext, std::move(base), index, ownerKind);
|
||||
}
|
||||
case Rehydrator::kFloatLiteral_Command: {
|
||||
const Type* type = this->type();
|
||||
|
@ -135,7 +135,7 @@ std::unique_ptr<SkSL::Expression> DSLWriter::ConvertBinary(std::unique_ptr<Expre
|
||||
|
||||
std::unique_ptr<SkSL::Expression> DSLWriter::ConvertField(std::unique_ptr<Expression> base,
|
||||
const char* name) {
|
||||
return IRGenerator().convertField(std::move(base), name);
|
||||
return FieldAccess::Convert(Context(), std::move(base), name);
|
||||
}
|
||||
|
||||
std::unique_ptr<SkSL::Expression> DSLWriter::ConvertIndex(std::unique_ptr<Expression> base,
|
||||
|
41
src/sksl/ir/SkSLFieldAccess.cpp
Normal file
41
src/sksl/ir/SkSLFieldAccess.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2021 Google LLC
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "src/sksl/SkSLContext.h"
|
||||
#include "src/sksl/ir/SkSLFieldAccess.h"
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
std::unique_ptr<Expression> FieldAccess::Convert(const Context& context,
|
||||
std::unique_ptr<Expression> base,
|
||||
StringFragment field) {
|
||||
const Type& baseType = base->type();
|
||||
if (baseType.isStruct()) {
|
||||
const std::vector<Type::Field>& fields = baseType.fields();
|
||||
for (size_t i = 0; i < fields.size(); i++) {
|
||||
if (fields[i].fName == field) {
|
||||
return FieldAccess::Make(context, std::move(base), (int) i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.fErrors.error(base->fOffset, "type '" + baseType.displayName() +
|
||||
"' does not have a field named '" + field + "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> FieldAccess::Make(const Context& context,
|
||||
std::unique_ptr<Expression> base,
|
||||
int fieldIndex,
|
||||
OwnerKind ownerKind) {
|
||||
SkASSERT(base->type().isStruct());
|
||||
SkASSERT(fieldIndex >= 0);
|
||||
SkASSERT(fieldIndex < (int) base->type().fields().size());
|
||||
return std::make_unique<FieldAccess>(std::move(base), fieldIndex, ownerKind);
|
||||
}
|
||||
|
||||
} // namespace SkSL
|
@ -36,6 +36,17 @@ public:
|
||||
, fOwnerKind(ownerKind)
|
||||
, fBase(std::move(base)) {}
|
||||
|
||||
// Returns a field-access expression; reports errors via the ErrorReporter.
|
||||
static std::unique_ptr<Expression> Convert(const Context& context,
|
||||
std::unique_ptr<Expression> base,
|
||||
StringFragment field);
|
||||
|
||||
// Returns a field-access expression; reports errors via ASSERT.
|
||||
static std::unique_ptr<Expression> Make(const Context& context,
|
||||
std::unique_ptr<Expression> base,
|
||||
int fieldIndex,
|
||||
OwnerKind ownerKind = OwnerKind::kDefault);
|
||||
|
||||
std::unique_ptr<Expression>& base() {
|
||||
return fBase;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user