42 std::optional<SwizzleDomain> domain;
44 for (int8_t field : fields) {
45 SwizzleDomain fieldDomain;
51 fieldDomain = kCoordinate;
78 if (!domain.has_value()) {
80 }
else if (domain != fieldDomain) {
124 auto baseArguments =
base.argumentSpan();
125 std::unique_ptr<Expression> replacement;
128 int swizzleSize = components.
size();
143 struct ConstructorArgMap {
148 int numConstructorArgs =
base.type().columns();
149 ConstructorArgMap argMap[4] = {};
151 for (
int argIdx = 0; argIdx < (
int)baseArguments.size(); ++argIdx) {
152 const Expression& arg = *baseArguments[argIdx];
160 for (
int componentIdx = 0; componentIdx < argSlots; ++componentIdx) {
161 argMap[writeIdx].fArgIndex = argIdx;
162 argMap[writeIdx].fComponent = componentIdx;
166 SkASSERT(writeIdx == numConstructorArgs);
172 int8_t exprUsed[4] = {};
173 for (int8_t c : components) {
174 exprUsed[argMap[c].fArgIndex]++;
177 for (
int index = 0; index < numConstructorArgs; ++index) {
178 int8_t constructorArgIndex = argMap[index].fArgIndex;
179 const Expression& baseArg = *baseArguments[constructorArgIndex];
191 struct ReorderedArgument {
196 for (int8_t c : components) {
197 const ConstructorArgMap& argument = argMap[c];
198 const Expression& baseArg = *baseArguments[argument.fArgIndex];
203 reorderedArgs.
push_back({argument.fArgIndex,
209 if (reorderedArgs.
empty() ||
210 reorderedArgs.
back().fArgIndex != argument.fArgIndex) {
212 reorderedArgs.
push_back({argument.fArgIndex,
219 reorderedArgs.
back().fComponents.push_back(argument.fComponent);
228 for (
const ReorderedArgument& reorderedArg : reorderedArgs) {
229 std::unique_ptr<Expression> newArg = baseArguments[reorderedArg.fArgIndex]->clone();
231 if (reorderedArg.fComponents.empty()) {
235 reorderedArg.fComponents));
242 componentType.
toCompound(context, swizzleSize, 1),
249 std::unique_ptr<Expression>
base,
250 std::string_view componentString) {
251 if (componentString.size() > 4) {
254 "too many components in swizzle mask");
260 for (
size_t i = 0;
i < componentString.length(); ++
i) {
261 char field = componentString[
i];
294 const Type& baseType =
base->type().scalarTypeForLiteral();
303 bool foundXYZW =
false;
358 context.
fErrors->
error(maskPos,
"swizzle must refer to base expression");
379 std::unique_ptr<Expression> expr =
Swizzle::Make(context,
pos, std::move(
base), maskComponents);
395 constructorArgs.
push_back(std::move(expr));
404 int maskFieldIdx = 0;
405 int constantFieldIdx = maskComponents.
size();
406 int constantZeroIdx = -1, constantOneIdx = -1;
411 if (constantZeroIdx == -1) {
414 constantZeroIdx = constantFieldIdx++;
416 swizzleComponents.
push_back(constantZeroIdx);
419 if (constantOneIdx == -1) {
422 constantOneIdx = constantFieldIdx++;
424 swizzleComponents.
push_back(constantOneIdx);
428 swizzleComponents.
push_back(maskFieldIdx++);
434 scalarType->
toCompound(context, constantFieldIdx, 1),
435 std::move(constructorArgs));
452 std::unique_ptr<Expression> expr,
454 const Type& exprType = expr->type();
456 "cannot swizzle type '%s'", exprType.
description().c_str());
463 return component >= SwizzleComponent::X &&
464 component <= SwizzleComponent::W;
477 expr->fPosition =
pos;
516 return (castType.columns() > 1)
530 return std::make_unique<Swizzle>(context,
pos, std::move(expr),
components);
#define SkASSERTF(cond, fmt,...)
static const Expression * GetConstantValueForVariable(const Expression &value)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, ExpressionArray args)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
void error(Position position, std::string_view msg)
const Type & type() const
std::string description() const final
static std::unique_ptr< Literal > Make(Position pos, double value, const Type *type)
static Position Range(int startOffset, int endOffset)
std::unique_ptr< Expression > & argument()
std::unique_ptr< Expression > & base()
static bool IsIdentity(const ComponentArray &components)
const ComponentArray & components() const
static std::unique_ptr< Expression > Make(const Context &context, Position pos, std::unique_ptr< Expression > expr, ComponentArray inComponents)
static std::string MaskString(const ComponentArray &inComponents)
static std::unique_ptr< Expression > Convert(const Context &context, Position pos, Position maskPos, std::unique_ptr< Expression > base, std::string_view componentString)
virtual bool isVector() const
std::unique_ptr< Expression > coerceExpression(std::unique_ptr< Expression > expr, const Context &context) const
virtual const Type & componentType() const
virtual int columns() const
virtual size_t slotCount() const
virtual bool isScalar() const
std::string description() const override
std::string displayName() const
const Type & toCompound(const Context &context, int columns, int rows) const
void reserve_exact(int n)
bool IsTrivialExpression(const Expression &expr)
bool HasSideEffects(const Expression &expr)
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
static bool validate_swizzle_domain(const ComponentArray &fields)
static char mask_char(int8_t component)
static std::unique_ptr< Expression > optimize_constructor_swizzle(const Context &context, Position pos, const ConstructorCompound &base, ComponentArray components)