blob: 0f35c8dfd653ad74ddf11b634de9fd555eda8461 [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SKSL_CONSTRUCTOR
#define SKSL_CONSTRUCTOR
#include "include/private/SkTArray.h"
#include "src/sksl/SkSLIRGenerator.h"
#include "src/sksl/ir/SkSLExpression.h"
namespace SkSL {
/**
* Represents the construction of a compound type, such as "float2(x, y)".
*
* Vector constructors will always consist of either exactly 1 scalar, or a collection of vectors
* and scalars totalling exactly the right number of scalar components.
*
* Matrix constructors will always consist of either exactly 1 scalar, exactly 1 matrix, or a
* collection of vectors and scalars totalling exactly the right number of scalar components.
*/
class Constructor final : public Expression {
public:
static constexpr Kind kExpressionKind = Kind::kConstructor;
// Use Constructor::Make to create constructor expressions.
Constructor(int offset, const Type& type, ExpressionArray arguments)
: INHERITED(offset, kExpressionKind, &type)
, fArguments(std::move(arguments)) {}
static std::unique_ptr<Expression> Make(const Context& context,
int offset,
const Type& type,
ExpressionArray args);
ExpressionArray& arguments() {
return fArguments;
}
const ExpressionArray& arguments() const {
return fArguments;
}
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override;
// If the passed-in expression is a literal, performs a constructor-conversion of the literal
// value to the constructor's type and returns that converted value as a new literal. e.g., the
// constructor expression `short(3.14)` would be represented as `FloatLiteral(3.14)` along with
// type `Short`, and this would result in `IntLiteral(3, type=Short)`. Returns nullptr if the
// expression is not a literal or the conversion cannot be made.
static std::unique_ptr<Expression> SimplifyConversion(const Type& constructorType,
const Expression& expr);
bool hasProperty(Property property) const override {
for (const std::unique_ptr<Expression>& arg: this->arguments()) {
if (arg->hasProperty(property)) {
return true;
}
}
return false;
}
std::unique_ptr<Expression> clone() const override {
ExpressionArray cloned;
cloned.reserve_back(this->arguments().size());
for (const std::unique_ptr<Expression>& arg: this->arguments()) {
cloned.push_back(arg->clone());
}
return std::make_unique<Constructor>(fOffset, this->type(), std::move(cloned));
}
String description() const override {
String result = this->type().description() + "(";
const char* separator = "";
for (const std::unique_ptr<Expression>& arg: this->arguments()) {
result += separator;
result += arg->description();
separator = ", ";
}
result += ")";
return result;
}
const Type& componentType() const {
// Returns `float` for constructors of type `float(...)` or `floatN(...)`.
const Type& type = this->type();
return type.columns() == 1 ? type : type.componentType();
}
bool isCompileTimeConstant() const override {
for (const std::unique_ptr<Expression>& arg: this->arguments()) {
if (!arg->isCompileTimeConstant()) {
return false;
}
}
return true;
}
bool isConstantOrUniform() const override {
for (const std::unique_ptr<Expression>& arg: this->arguments()) {
if (!arg->isConstantOrUniform()) {
return false;
}
}
return true;
}
ComparisonResult compareConstant(const Expression& other) const override;
template <typename ResultType>
ResultType getVecComponent(int index) const;
/**
* For a literal vector expression, return the float value of the n'th vector component. It is
* an error to call this method on an expression which is not a compile-time constant vector of
* floating-point type.
*/
SKSL_FLOAT getFVecComponent(int n) const override {
return this->getVecComponent<SKSL_FLOAT>(n);
}
/**
* For a literal vector expression, return the integer value of the n'th vector component. It is
* an error to call this method on an expression which is not a compile-time constant vector of
* integer type.
*/
SKSL_INT getIVecComponent(int n) const override {
return this->getVecComponent<SKSL_INT>(n);
}
/**
* For a literal vector expression, return the boolean value of the n'th vector component. It is
* an error to call this method on an expression which is not a compile-time constant vector of
* Boolean type.
*/
bool getBVecComponent(int n) const override {
return this->getVecComponent<bool>(n);
}
SKSL_FLOAT getMatComponent(int col, int row) const override;
SKSL_INT getConstantInt() const override;
SKSL_FLOAT getConstantFloat() const override;
bool getConstantBool() const override;
private:
static std::unique_ptr<Expression> MakeScalarConstructor(const Context& context,
int offset,
const Type& type,
ExpressionArray args);
static std::unique_ptr<Expression> MakeCompoundConstructor(const Context& context,
int offset,
const Type& type,
ExpressionArray args);
static std::unique_ptr<Expression> MakeArrayConstructor(const Context& context,
int offset,
const Type& type,
ExpressionArray args);
template <typename ResultType> ResultType getConstantValue(const Expression& expr) const;
template <typename ResultType>
ResultType getInnerVecComponent(const Expression& expr, int position) const;
ExpressionArray fArguments;
using INHERITED = Expression;
};
} // namespace SkSL
#endif