diff --git a/modules/sksg/include/SkSGTransform.h b/modules/sksg/include/SkSGTransform.h index c878773d32..790373b762 100644 --- a/modules/sksg/include/SkSGTransform.h +++ b/modules/sksg/include/SkSGTransform.h @@ -21,25 +21,19 @@ namespace sksg { */ class Matrix : public Node { public: - static sk_sp Make(const SkMatrix& m, sk_sp parent = nullptr) { - return sk_sp(new Matrix(m, std::move(parent))); - } + static sk_sp Make(const SkMatrix& m, sk_sp parent = nullptr); - ~Matrix() override; + SG_ATTRIBUTE(Matrix, SkMatrix, fMatrix) - SG_ATTRIBUTE(Matrix, SkMatrix, fLocalMatrix) - - const SkMatrix& getTotalMatrix() const { return fTotalMatrix; } + virtual const SkMatrix& getTotalMatrix() const; protected: - Matrix(const SkMatrix&, sk_sp); + explicit Matrix(const SkMatrix&); SkRect onRevalidate(InvalidationController*, const SkMatrix&) override; private: - sk_sp fParent; - SkMatrix fLocalMatrix, - fTotalMatrix; // cached during revalidation + SkMatrix fMatrix; typedef Node INHERITED; }; diff --git a/modules/sksg/src/SkSGTransform.cpp b/modules/sksg/src/SkSGTransform.cpp index 41b6a35882..76b180a096 100644 --- a/modules/sksg/src/SkSGTransform.cpp +++ b/modules/sksg/src/SkSGTransform.cpp @@ -10,30 +10,57 @@ #include "SkCanvas.h" namespace sksg { -// Matrix nodes don't generate damage on their own, but via aggregation ancestor Transform nodes. -Matrix::Matrix(const SkMatrix& m, sk_sp parent) - : INHERITED(kBubbleDamage_Trait) - , fParent(std::move(parent)) - , fLocalMatrix(m) { - if (fParent) { +namespace { + +class ComposedMatrix final : public Matrix { +public: + ComposedMatrix(const SkMatrix& m, sk_sp parent) + : INHERITED(m) + , fParent(std::move(parent)) { + SkASSERT(fParent); this->observeInval(fParent); } -} -Matrix::~Matrix() { - if (fParent) { + ~ComposedMatrix() override { this->unobserveInval(fParent); } -} -SkRect Matrix::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) { - fTotalMatrix = fLocalMatrix; - - if (fParent) { - fParent->revalidate(ic, ctm); - fTotalMatrix.postConcat(fParent->getTotalMatrix()); + const SkMatrix& getTotalMatrix() const override { + SkASSERT(!this->hasInval()); + return fTotalMatrix; } +protected: + SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override { + fParent->revalidate(ic, ctm); + fTotalMatrix = SkMatrix::Concat(fParent->getTotalMatrix(), this->getMatrix()); + return SkRect::MakeEmpty(); + } + +private: + const sk_sp fParent; + SkMatrix fTotalMatrix; // cached during revalidation. + + using INHERITED = Matrix; +}; + +} // namespace + +sk_sp Matrix::Make(const SkMatrix& m, sk_sp parent) { + return sk_sp(parent ? new ComposedMatrix(m, std::move(parent)) + : new Matrix(m)); +} + +// Matrix nodes don't generate damage on their own, but via aggregation ancestor Transform nodes. +Matrix::Matrix(const SkMatrix& m) + : INHERITED(kBubbleDamage_Trait) + , fMatrix(m) {} + +const SkMatrix& Matrix::getTotalMatrix() const { + return fMatrix; +} + +SkRect Matrix::onRevalidate(InvalidationController*, const SkMatrix&) { return SkRect::MakeEmpty(); }