blob: 02fc69c299416edf332a747b0253acb631bd97d3 [file] [log] [blame]
* 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/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/ir/SkSLConstructorArray.h"
#include "src/sksl/ir/SkSLConstructorCompoundCast.h"
#include "src/sksl/ir/SkSLConstructorScalarCast.h"
namespace SkSL {
static std::unique_ptr<Expression> cast_constant_array(const Context& context,
const Type& destType,
std::unique_ptr<Expression> constCtor) {
const Type& scalarType = destType.componentType();
// Create a ConstructorArray(...) which typecasts each argument inside.
auto inputArgs = constCtor->as<ConstructorArray>().argumentSpan();
ExpressionArray typecastArgs;
for (std::unique_ptr<Expression>& arg : inputArgs) {
int line = arg->fLine;
if (arg->type().isScalar()) {
typecastArgs.push_back(ConstructorScalarCast::Make(context, line, scalarType,
} else {
typecastArgs.push_back(ConstructorCompoundCast::Make(context, line, scalarType,
return ConstructorArray::Make(context, constCtor->fLine, destType, std::move(typecastArgs));
std::unique_ptr<Expression> ConstructorArrayCast::Make(const Context& context,
int line,
const Type& type,
std::unique_ptr<Expression> arg) {
// Only arrays of the same size are allowed.
SkASSERT(type.columns() == arg->type().columns());
// If this is a no-op cast, return the expression as-is.
if (type == arg->type()) {
return arg;
// When optimization is on, look up the value of constant variables. This allows expressions
// like `myArray` to be replaced with the compile-time constant `int[2](0, 1)`.
if (context.fConfig->fSettings.fOptimize) {
arg = ConstantFolder::MakeConstantValueForVariable(std::move(arg));
// We can cast a vector of compile-time constants at compile-time.
if (arg->isCompileTimeConstant()) {
return cast_constant_array(context, type, std::move(arg));
return std::make_unique<ConstructorArrayCast>(line, type, std::move(arg));
} // namespace SkSL