[sksg] Add 3x3 Concat Transform specialization
When both inputs are 3x3, use 3x3 Concat.
TBR=
Change-Id: Ife6a98792c2ed57a2a987fe5d0bdf265aeb64b0a
Reviewed-on: https://skia-review.googlesource.com/c/182968
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/sksg/include/SkSGTransform.h b/modules/sksg/include/SkSGTransform.h
index c3ba6c2..9f0fd77 100644
--- a/modules/sksg/include/SkSGTransform.h
+++ b/modules/sksg/include/SkSGTransform.h
@@ -26,6 +26,8 @@
protected:
Transform();
+ virtual bool is44() const = 0;
+
virtual SkMatrix asMatrix () const = 0;
virtual SkMatrix44 asMatrix44() const = 0;
@@ -49,6 +51,8 @@
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+ bool is44() const override { return false; }
+
SkMatrix asMatrix () const override;
SkMatrix44 asMatrix44() const override;
@@ -72,6 +76,8 @@
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+ bool is44() const override { return true; }
+
SkMatrix asMatrix () const override;
SkMatrix44 asMatrix44() const override;
diff --git a/modules/sksg/src/SkSGGeometryTransform.cpp b/modules/sksg/src/SkSGGeometryTransform.cpp
index f338236..2602a46 100644
--- a/modules/sksg/src/SkSGGeometryTransform.cpp
+++ b/modules/sksg/src/SkSGGeometryTransform.cpp
@@ -37,7 +37,7 @@
// We don't care about matrix reval results.
fTransform->revalidate(ic, ctm);
- const auto m = TransformPriv::AsMatrix(fTransform);
+ const auto m = TransformPriv::As<SkMatrix>(fTransform);
auto bounds = fChild->revalidate(ic, ctm);
fTransformedPath = fChild->asPath();
diff --git a/modules/sksg/src/SkSGTransform.cpp b/modules/sksg/src/SkSGTransform.cpp
index e869c3a..c36205d 100644
--- a/modules/sksg/src/SkSGTransform.cpp
+++ b/modules/sksg/src/SkSGTransform.cpp
@@ -14,9 +14,11 @@
namespace {
-// Always compose in 4x4 for now.
+template <typename T>
class Concat final : public Transform {
public:
+ template <typename = std::enable_if<std::is_same<T, SkMatrix >::value ||
+ std::is_same<T, SkMatrix44>::value >>
Concat(sk_sp<Transform> a, sk_sp<Transform> b)
: fA(std::move(a)), fB(std::move(b)) {
SkASSERT(fA);
@@ -36,11 +38,13 @@
fA->revalidate(ic, ctm);
fB->revalidate(ic, ctm);
- fComposed.setConcat(TransformPriv::AsMatrix44(fA),
- TransformPriv::AsMatrix44(fB));
+ fComposed.setConcat(TransformPriv::As<T>(fA),
+ TransformPriv::As<T>(fB));
return SkRect::MakeEmpty();
}
+ bool is44() const override { return std::is_same<T, SkMatrix44>::value; }
+
SkMatrix asMatrix() const override {
return fComposed;
}
@@ -51,7 +55,7 @@
private:
const sk_sp<Transform> fA, fB;
- SkMatrix44 fComposed;
+ T fComposed;
using INHERITED = Transform;
};
@@ -66,8 +70,13 @@
return b;
}
- return b ? sk_make_sp<Concat>(std::move(a), std::move(b))
- : a;
+ if (!b) {
+ return a;
+ }
+
+ return TransformPriv::Is44(a) || TransformPriv::Is44(b)
+ ? sk_sp<Transform>(new Concat<SkMatrix44>(std::move(a), std::move(b)))
+ : sk_sp<Transform>(new Concat<SkMatrix >(std::move(a), std::move(b)));
}
sk_sp<Matrix> Matrix::Make(const SkMatrix& m) {
@@ -117,7 +126,7 @@
}
void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
- const auto m = TransformPriv::AsMatrix(fTransform);
+ const auto m = TransformPriv::As<SkMatrix>(fTransform);
SkAutoCanvasRestore acr(canvas, !m.isIdentity());
canvas->concat(m);
this->INHERITED::onRender(canvas, ctx);
@@ -129,7 +138,7 @@
// We don't care about matrix reval results.
fTransform->revalidate(ic, ctm);
- const auto m = TransformPriv::AsMatrix(fTransform);
+ const auto m = TransformPriv::As<SkMatrix>(fTransform);
auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
m.mapRect(&bounds);
diff --git a/modules/sksg/src/SkSGTransformPriv.h b/modules/sksg/src/SkSGTransformPriv.h
index 6582938..20441c1 100644
--- a/modules/sksg/src/SkSGTransformPriv.h
+++ b/modules/sksg/src/SkSGTransformPriv.h
@@ -15,13 +15,27 @@
// Helper for accessing implementation-private Transform methods.
class TransformPriv final {
public:
- static SkMatrix AsMatrix (const sk_sp<Transform>& t) { return t->asMatrix(); }
- static SkMatrix44 AsMatrix44(const sk_sp<Transform>& t) { return t->asMatrix44(); }
+
+ static bool Is44(const sk_sp<Transform>&t) { return t->is44(); }
+
+ template <typename T, typename = std::enable_if<std::is_same<T, SkMatrix >::value ||
+ std::is_same<T, SkMatrix44>::value >>
+ static T As(const sk_sp<Transform>&);
private:
TransformPriv() = delete;
};
+template <>
+inline SkMatrix TransformPriv::As<SkMatrix>(const sk_sp<Transform>& t) {
+ return t->asMatrix();
+}
+
+template <>
+inline SkMatrix44 TransformPriv::As<SkMatrix44>(const sk_sp<Transform>& t) {
+ return t->asMatrix44();
+}
+
} // namespace sksg
#endif // SkSGTransformPriv_DEFINED