41 std::optional<SwizzleDomain> domain;
43 for (int8_t field : fields) {
44 SwizzleDomain fieldDomain;
50 fieldDomain = kCoordinate;
77 if (!domain.has_value()) {
79 }
else if (domain != fieldDomain) {
123 auto baseArguments =
base.argumentSpan();
124 std::unique_ptr<Expression> replacement;
127 int swizzleSize = components.
size();
142 struct ConstructorArgMap {
147 int numConstructorArgs =
base.type().columns();
148 ConstructorArgMap argMap[4] = {};
150 for (
int argIdx = 0; argIdx < (
int)baseArguments.size(); ++argIdx) {
151 const Expression& arg = *baseArguments[argIdx];
159 for (
int componentIdx = 0; componentIdx < argSlots; ++componentIdx) {
160 argMap[writeIdx].fArgIndex = argIdx;
161 argMap[writeIdx].fComponent = componentIdx;
165 SkASSERT(writeIdx == numConstructorArgs);
171 int8_t exprUsed[4] = {};
172 for (int8_t c : components) {
173 exprUsed[argMap[c].fArgIndex]++;
176 for (
int index = 0; index < numConstructorArgs; ++index) {
177 int8_t constructorArgIndex = argMap[index].fArgIndex;
178 const Expression& baseArg = *baseArguments[constructorArgIndex];
190 struct ReorderedArgument {
195 for (int8_t c : components) {
196 const ConstructorArgMap& argument = argMap[c];
197 const Expression& baseArg = *baseArguments[argument.fArgIndex];
202 reorderedArgs.
push_back({argument.fArgIndex,
208 if (reorderedArgs.
empty() ||
209 reorderedArgs.
back().fArgIndex != argument.fArgIndex) {
211 reorderedArgs.
push_back({argument.fArgIndex,
218 reorderedArgs.
back().fComponents.push_back(argument.fComponent);
227 for (
const ReorderedArgument& reorderedArg : reorderedArgs) {
228 std::unique_ptr<Expression> newArg = baseArguments[reorderedArg.fArgIndex]->clone();
230 if (reorderedArg.fComponents.empty()) {
234 reorderedArg.fComponents));
241 componentType.
toCompound(context, swizzleSize, 1),
248 std::unique_ptr<Expression>
base,
249 std::string_view maskString) {
251 for (
size_t i = 0; i < maskString.length(); ++i) {
252 char field = maskString[i];
290 std::unique_ptr<Expression>
base,
292 if (inComponents.
size() > 4) {
295 "too many components in swizzle mask");
304 const Type& baseType =
base->type().scalarTypeForLiteral();
313 bool foundXYZW =
false;
314 for (
int i = 0; i < inComponents.
size(); ++i) {
315 switch (inComponents[i]) {
368 context.
fErrors->
error(maskPos,
"swizzle must refer to base expression");
383 std::unique_ptr<Expression> expr =
Swizzle::Make(context,
pos, std::move(
base), maskComponents);
386 if (maskComponents.
size() == inComponents.
size()) {
399 constructorArgs.
push_back(std::move(expr));
408 int maskFieldIdx = 0;
409 int constantFieldIdx = maskComponents.
size();
410 int constantZeroIdx = -1, constantOneIdx = -1;
412 for (
int i = 0; i < inComponents.
size(); i++) {
413 switch (inComponents[i]) {
415 if (constantZeroIdx == -1) {
418 constantZeroIdx = constantFieldIdx++;
420 swizzleComponents.
push_back(constantZeroIdx);
423 if (constantOneIdx == -1) {
426 constantOneIdx = constantFieldIdx++;
428 swizzleComponents.
push_back(constantOneIdx);
432 swizzleComponents.
push_back(maskFieldIdx++);
438 scalarType->
toCompound(context, constantFieldIdx, 1),
439 std::move(constructorArgs));
447 std::unique_ptr<Expression> expr,
449 const Type& exprType = expr->type();
451 "cannot swizzle type '%s'", exprType.
description().c_str());
458 return component >= SwizzleComponent::X &&
459 component <= SwizzleComponent::W;
472 bool identity =
true;
480 expr->fPosition =
pos;
520 return (castType.columns() > 1)
534 return std::make_unique<Swizzle>(context,
pos, std::move(expr),
components);
#define SkASSERTF(cond, fmt,...)
Type::kYUV Type::kRGBA() int(0.7 *637)
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)
virtual 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 std::unique_ptr< Expression > Convert(const Context &context, Position pos, Position maskPos, std::unique_ptr< Expression > base, ComponentArray inComponents)
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)
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)