aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl/ir/SkSLConstructor.h
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2017-04-25 14:42:11 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-04-25 19:39:13 +0000
commit3deaeb2dc0cfddfdf2e3b64736c860132619a051 (patch)
tree9349c336d5d6802de58e326dc89557047f631739 /src/sksl/ir/SkSLConstructor.h
parent7ab6a7f40b23610577bd64fbcb6121a2a715469b (diff)
sksl can now fold constant vector or matrix equality expressions
Bug: skia: Change-Id: Icaddae68e53ed3629bcdc04b5f0b541d9e4398e2 Reviewed-on: https://skia-review.googlesource.com/14260 Commit-Queue: Ethan Nicholas <ethannicholas@google.com> Reviewed-by: Ben Wagner <benjaminwagner@google.com>
Diffstat (limited to 'src/sksl/ir/SkSLConstructor.h')
-rw-r--r--src/sksl/ir/SkSLConstructor.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/sksl/ir/SkSLConstructor.h b/src/sksl/ir/SkSLConstructor.h
index 208031abba..05f409649a 100644
--- a/src/sksl/ir/SkSLConstructor.h
+++ b/src/sksl/ir/SkSLConstructor.h
@@ -81,6 +81,44 @@ struct Constructor : public Expression {
return true;
}
+ bool compareConstant(const Context& context, const Expression& other) const override {
+ ASSERT(other.fKind == Expression::kConstructor_Kind && other.fType == fType);
+ Constructor& c = (Constructor&) other;
+ if (c.fType.kind() == Type::kVector_Kind) {
+ for (int i = 0; i < fType.columns(); i++) {
+ if (!this->getVecComponent(i).compareConstant(context, c.getVecComponent(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ // shouldn't be possible to have a constant constructor that isn't a vector or matrix;
+ // a constant scalar constructor should have been collapsed down to the appropriate
+ // literal
+ ASSERT(fType.kind() == Type::kMatrix_Kind);
+ const FloatLiteral fzero(context, Position(), 0);
+ const IntLiteral izero(context, Position(), 0);
+ const Expression* zero;
+ if (fType.componentType() == *context.fFloat_Type) {
+ zero = &fzero;
+ } else {
+ ASSERT(fType.componentType() == *context.fInt_Type);
+ zero = &izero;
+ }
+ for (int col = 0; col < fType.columns(); col++) {
+ for (int row = 0; row < fType.rows(); row++) {
+ const Expression* component1 = getMatComponent(col, row);
+ const Expression* component2 = c.getMatComponent(col, row);
+ if (!(component1 ? component1 : zero)->compareConstant(
+ context,
+ component2 ? *component2 : *zero)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
const Expression& getVecComponent(int index) const {
ASSERT(fType.kind() == Type::kVector_Kind);
if (fArguments.size() == 1 && fArguments[0]->fType.kind() == Type::kScalar_Kind) {
@@ -118,6 +156,51 @@ struct Constructor : public Expression {
return ((IntLiteral&) c).fValue;
}
+ // null return should be interpreted as zero
+ const Expression* getMatComponent(int col, int row) const {
+ ASSERT(this->isConstant());
+ ASSERT(fType.kind() == Type::kMatrix_Kind);
+ ASSERT(col < fType.columns() && row < fType.rows());
+ if (fArguments.size() == 1) {
+ if (fArguments[0]->fType.kind() == Type::kScalar_Kind) {
+ // single scalar argument, so matrix is of the form:
+ // x 0 0
+ // 0 x 0
+ // 0 0 x
+ // return x if col == row
+ return col == row ? fArguments[0].get() : nullptr;
+ }
+ if (fArguments[0]->fType.kind() == Type::kMatrix_Kind) {
+ ASSERT(fArguments[0]->fKind == Expression::kConstructor_Kind);
+ // single matrix argument. make sure we're within the argument's bounds.
+ const Type& argType = ((Constructor&) *fArguments[0]).fType;
+ if (col < argType.columns() && row < argType.rows()) {
+ // within bounds, defer to argument
+ return ((Constructor&) *fArguments[0]).getMatComponent(col, row);
+ }
+ // out of bounds, return 0
+ return nullptr;
+ }
+ }
+ int currentIndex = 0;
+ int targetIndex = col * fType.rows() + row;
+ for (const auto& arg : fArguments) {
+ ASSERT(targetIndex >= currentIndex);
+ ASSERT(arg->fType.rows() == 1);
+ if (currentIndex + arg->fType.columns() > targetIndex) {
+ if (arg->fType.columns() == 1) {
+ return arg.get();
+ } else {
+ ASSERT(arg->fType.kind() == Type::kVector_Kind);
+ ASSERT(arg->fKind == Expression::kConstructor_Kind);
+ return &((Constructor&) *arg).getVecComponent(targetIndex - currentIndex);
+ }
+ }
+ currentIndex += arg->fType.columns();
+ }
+ ABORT("can't happen, matrix component out of bounds");
+ }
+
std::vector<std::unique_ptr<Expression>> fArguments;
typedef Expression INHERITED;