diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2017-04-25 14:42:11 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-04-25 19:39:13 +0000 |
commit | 3deaeb2dc0cfddfdf2e3b64736c860132619a051 (patch) | |
tree | 9349c336d5d6802de58e326dc89557047f631739 /src/sksl/ir/SkSLConstructor.h | |
parent | 7ab6a7f40b23610577bd64fbcb6121a2a715469b (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.h | 83 |
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; |