[sksg] 4x4 matrix support
Refactor the scene graph transform hierarchy to support 4x4 matrices:
* rename current Transform to TransformEffect (operates as a render tree effect)
* introduce a new Transform abstract base class, to replace current Matrix
* refactor existing Matrix as a Transform specialization
* introduce a new Matrix44 Transform specialization
* refactor the existing composition helper (ComposedMatrix) as Concat,
a Transform specialization (using composition instead of Matrix inheritance)
Change-Id: Ic3c1b499e10a0a229a7a76d4bef3dbc6a8b49194
Reviewed-on: https://skia-review.googlesource.com/c/182666
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/modules/skottie/src/Skottie.cpp b/modules/skottie/src/Skottie.cpp
index 65fed85..516d0eb 100644
--- a/modules/skottie/src/Skottie.cpp
+++ b/modules/skottie/src/Skottie.cpp
@@ -61,13 +61,13 @@
fLogger->log(lvl, buff, jsonstr.c_str());
}
-sk_sp<sksg::Matrix> AnimationBuilder::attachMatrix2D(const skjson::ObjectValue& t,
- AnimatorScope* ascope,
- sk_sp<sksg::Matrix> parentMatrix) const {
+sk_sp<sksg::Transform> AnimationBuilder::attachMatrix2D(const skjson::ObjectValue& t,
+ AnimatorScope* ascope,
+ sk_sp<sksg::Transform> parent) const {
static const VectorValue g_default_vec_0 = { 0, 0},
g_default_vec_100 = {100, 100};
- auto matrix = sksg::Matrix::Make(SkMatrix::I(), parentMatrix);
+ auto matrix = sksg::Matrix::Make(SkMatrix::I());
auto adapter = sk_make_sp<TransformAdapter2D>(matrix);
auto bound = this->bindProperty<VectorValue>(t["a"], ascope,
@@ -104,16 +104,18 @@
const auto dispatched = this->dispatchTransformProperty(adapter);
- return (bound || dispatched) ? matrix : parentMatrix;
+ return (bound || dispatched)
+ ? sksg::Transform::MakeConcat(std::move(parent), std::move(matrix))
+ : parent;
}
-sk_sp<sksg::Matrix> AnimationBuilder::attachMatrix3D(const skjson::ObjectValue& t,
- AnimatorScope* ascope,
- sk_sp<sksg::Matrix> parentMatrix) const {
+sk_sp<sksg::Transform> AnimationBuilder::attachMatrix3D(const skjson::ObjectValue& t,
+ AnimatorScope* ascope,
+ sk_sp<sksg::Transform> parent) const {
static const VectorValue g_default_vec_0 = { 0, 0, 0},
g_default_vec_100 = {100, 100, 100};
- auto matrix = sksg::Matrix::Make(SkMatrix::I(), parentMatrix);
+ auto matrix = sksg::Matrix44::Make(SkMatrix::I());
auto adapter = sk_make_sp<TransformAdapter3D>(matrix);
auto bound = this->bindProperty<VectorValue>(t["a"], ascope,
@@ -156,7 +158,9 @@
// TODO: dispatch 3D transform properties
- return bound ? matrix : parentMatrix;
+ return (bound)
+ ? sksg::Transform::MakeConcat(std::move(parent), std::move(matrix))
+ : parent;
}
sk_sp<sksg::RenderNode> AnimationBuilder::attachOpacity(const skjson::ObjectValue& jtransform,
diff --git a/modules/skottie/src/SkottieAdapter.cpp b/modules/skottie/src/SkottieAdapter.cpp
index 0d53869..805f693 100644
--- a/modules/skottie/src/SkottieAdapter.cpp
+++ b/modules/skottie/src/SkottieAdapter.cpp
@@ -73,12 +73,12 @@
fZ = v.size() > 2 ? v[2] : 0;
}
-TransformAdapter3D::TransformAdapter3D(sk_sp<sksg::Matrix> matrix)
+TransformAdapter3D::TransformAdapter3D(sk_sp<sksg::Matrix44> matrix)
: fMatrixNode(std::move(matrix)) {}
TransformAdapter3D::~TransformAdapter3D() = default;
-SkMatrix TransformAdapter3D::totalMatrix() const {
+SkMatrix44 TransformAdapter3D::totalMatrix() const {
SkMatrix44 t;
t.setTranslate(-fAnchorPoint.fX, -fAnchorPoint.fY, -fAnchorPoint.fZ);
diff --git a/modules/skottie/src/SkottieAdapter.h b/modules/skottie/src/SkottieAdapter.h
index 1ab9a7b..42ea7f8 100644
--- a/modules/skottie/src/SkottieAdapter.h
+++ b/modules/skottie/src/SkottieAdapter.h
@@ -21,6 +21,7 @@
class Group;
class LinearGradient;
class Matrix;
+class Matrix44;
class Path;
class RadialGradient;
class RRect;
@@ -105,7 +106,7 @@
class TransformAdapter3D final : public SkNVRefCnt<TransformAdapter3D> {
public:
- explicit TransformAdapter3D(sk_sp<sksg::Matrix>);
+ explicit TransformAdapter3D(sk_sp<sksg::Matrix44>);
~TransformAdapter3D();
struct Vec3 {
@@ -124,12 +125,12 @@
ADAPTER_PROPERTY(Rotation , Vec3, Vec3({ 0, 0, 0}))
ADAPTER_PROPERTY(Scale , Vec3, Vec3({100, 100, 100}))
- SkMatrix totalMatrix() const;
+ SkMatrix44 totalMatrix() const;
private:
void apply();
- sk_sp<sksg::Matrix> fMatrixNode;
+ sk_sp<sksg::Matrix44> fMatrixNode;
};
class GradientAdapter : public SkRefCnt {
diff --git a/modules/skottie/src/SkottieLayer.cpp b/modules/skottie/src/SkottieLayer.cpp
index 2bb6264..3cc4122 100644
--- a/modules/skottie/src/SkottieLayer.cpp
+++ b/modules/skottie/src/SkottieLayer.cpp
@@ -372,7 +372,7 @@
return std::move(image_node);
}
- return sksg::Transform::Make(std::move(image_node),
+ return sksg::TransformEffect::Make(std::move(image_node),
SkMatrix::MakeRectToRect(SkRect::Make(image->bounds()),
SkRect::Make(asset_size),
SkMatrix::kCenter_ScaleToFit));
@@ -399,13 +399,13 @@
AttachLayerContext(const skjson::ArrayValue& jlayers, AnimatorScope* scope)
: fLayerList(jlayers), fScope(scope) {}
- const skjson::ArrayValue& fLayerList;
- AnimatorScope* fScope;
- SkTHashMap<int, sk_sp<sksg::Matrix>> fLayerMatrixMap;
- sk_sp<sksg::RenderNode> fCurrentMatte;
+ const skjson::ArrayValue& fLayerList;
+ AnimatorScope* fScope;
+ SkTHashMap<int, sk_sp<sksg::Transform>> fLayerMatrixMap;
+ sk_sp<sksg::RenderNode> fCurrentMatte;
- sk_sp<sksg::Matrix> AttachLayerMatrix(const skjson::ObjectValue& jlayer,
- const AnimationBuilder* abuilder) {
+ sk_sp<sksg::Transform> attachLayerTransform(const skjson::ObjectValue& jlayer,
+ const AnimationBuilder* abuilder) {
const auto layer_index = ParseDefault<int>(jlayer["ind"], -1);
if (layer_index < 0)
return nullptr;
@@ -413,13 +413,13 @@
if (auto* m = fLayerMatrixMap.find(layer_index))
return *m;
- return this->AttachLayerMatrixImpl(jlayer, abuilder, layer_index);
+ return this->attachLayerTransformImpl(jlayer, abuilder, layer_index);
}
private:
- sk_sp<sksg::Matrix> AttachParentLayerMatrix(const skjson::ObjectValue& jlayer,
- const AnimationBuilder* abuilder,
- int layer_index) {
+ sk_sp<sksg::Transform> attachParentLayerTransform(const skjson::ObjectValue& jlayer,
+ const AnimationBuilder* abuilder,
+ int layer_index) {
const auto parent_index = ParseDefault<int>(jlayer["parent"], -1);
if (parent_index < 0 || parent_index == layer_index)
return nullptr;
@@ -431,29 +431,29 @@
if (!l) continue;
if (ParseDefault<int>((*l)["ind"], -1) == parent_index) {
- return this->AttachLayerMatrixImpl(*l, abuilder, parent_index);
+ return this->attachLayerTransformImpl(*l, abuilder, parent_index);
}
}
return nullptr;
}
- sk_sp<sksg::Matrix> AttachLayerMatrixImpl(const skjson::ObjectValue& jlayer,
- const AnimationBuilder* abuilder,
- int layer_index) {
+ sk_sp<sksg::Transform> attachLayerTransformImpl(const skjson::ObjectValue& jlayer,
+ const AnimationBuilder* abuilder,
+ int layer_index) {
SkASSERT(!fLayerMatrixMap.find(layer_index));
// Add a stub entry to break recursion cycles.
fLayerMatrixMap.set(layer_index, nullptr);
- auto parent_matrix = this->AttachParentLayerMatrix(jlayer, abuilder, layer_index);
+ auto parent_matrix = this->attachParentLayerTransform(jlayer, abuilder, layer_index);
if (const skjson::ObjectValue* jtransform = jlayer["ks"]) {
- auto matrix_node = (ParseDefault<int>(jlayer["ddd"], 0) == 0)
+ auto transform_node = (ParseDefault<int>(jlayer["ddd"], 0) == 0)
? abuilder->attachMatrix2D(*jtransform, fScope, std::move(parent_matrix))
: abuilder->attachMatrix3D(*jtransform, fScope, std::move(parent_matrix));
- return *fLayerMatrixMap.set(layer_index, std::move(matrix_node));
+ return *fLayerMatrixMap.set(layer_index, std::move(transform_node));
}
return nullptr;
}
@@ -509,8 +509,8 @@
layer = AttachMask((*jlayer)["masksProperties"], this, &layer_animators, std::move(layer));
// Optional layer transform.
- if (auto layerMatrix = layerCtx->AttachLayerMatrix(*jlayer, this)) {
- layer = sksg::Transform::Make(std::move(layer), std::move(layerMatrix));
+ if (auto layer_transform = layerCtx->attachLayerTransform(*jlayer, this)) {
+ layer = sksg::TransformEffect::Make(std::move(layer), std::move(layer_transform));
}
// Optional layer opacity.
diff --git a/modules/skottie/src/SkottiePriv.h b/modules/skottie/src/SkottiePriv.h
index ee41f37..f6cdfa3 100644
--- a/modules/skottie/src/SkottiePriv.h
+++ b/modules/skottie/src/SkottiePriv.h
@@ -33,6 +33,7 @@
class Matrix;
class Path;
class RenderNode;
+class Transform;
} // namespace sksg
namespace skottie {
@@ -71,10 +72,10 @@
sk_sp<sksg::Color> attachColor(const skjson::ObjectValue&, AnimatorScope*,
const char prop_name[]) const;
- sk_sp<sksg::Matrix> attachMatrix2D(const skjson::ObjectValue&, AnimatorScope*,
- sk_sp<sksg::Matrix>) const;
- sk_sp<sksg::Matrix> attachMatrix3D(const skjson::ObjectValue&, AnimatorScope*,
- sk_sp<sksg::Matrix>) const;
+ sk_sp<sksg::Transform> attachMatrix2D(const skjson::ObjectValue&, AnimatorScope*,
+ sk_sp<sksg::Transform>) const;
+ sk_sp<sksg::Transform> attachMatrix3D(const skjson::ObjectValue&, AnimatorScope*,
+ sk_sp<sksg::Transform>) const;
sk_sp<sksg::RenderNode> attachOpacity(const skjson::ObjectValue&, AnimatorScope*,
sk_sp<sksg::RenderNode>) const;
sk_sp<sksg::Path> attachPath(const skjson::Value&, AnimatorScope*) const;
diff --git a/modules/skottie/src/SkottieShapeLayer.cpp b/modules/skottie/src/SkottieShapeLayer.cpp
index 76b5658..2731b75 100644
--- a/modules/skottie/src/SkottieShapeLayer.cpp
+++ b/modules/skottie/src/SkottieShapeLayer.cpp
@@ -587,7 +587,7 @@
shape_wrapper = sksg::Group::Make(std::move(draws));
}
- sk_sp<sksg::Matrix> shape_matrix;
+ sk_sp<sksg::Transform> shape_transform;
if (jtransform) {
const AutoPropertyTracker apt(this, *jtransform);
@@ -596,8 +596,8 @@
// of the dangling/uncommitted ones.
AnimatorScope local_scope;
- if ((shape_matrix = this->attachMatrix2D(*jtransform, &local_scope, nullptr))) {
- shape_wrapper = sksg::Transform::Make(std::move(shape_wrapper), shape_matrix);
+ if ((shape_transform = this->attachMatrix2D(*jtransform, &local_scope, nullptr))) {
+ shape_wrapper = sksg::TransformEffect::Make(std::move(shape_wrapper), shape_transform);
}
shape_wrapper = this->attachOpacity(*jtransform, &local_scope, std::move(shape_wrapper));
@@ -609,8 +609,8 @@
// Push transformed local geometries to parent list, for subsequent paints.
for (auto& geo : geos) {
- ctx->fGeometryStack->push_back(shape_matrix
- ? sksg::GeometryTransform::Make(std::move(geo), shape_matrix)
+ ctx->fGeometryStack->push_back(shape_transform
+ ? sksg::GeometryTransform::Make(std::move(geo), shape_transform)
: std::move(geo));
}
diff --git a/modules/sksg/include/SkSGGeometryTransform.h b/modules/sksg/include/SkSGGeometryTransform.h
index fe7e026..a0c45ac 100644
--- a/modules/sksg/include/SkSGGeometryTransform.h
+++ b/modules/sksg/include/SkSGGeometryTransform.h
@@ -13,8 +13,6 @@
#include "SkPath.h"
#include "SkSGTransform.h"
-class SkMatrix;
-
namespace sksg {
/**
@@ -22,9 +20,10 @@
*/
class GeometryTransform final : public GeometryNode {
public:
- static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, sk_sp<Matrix> matrix) {
- return child && matrix
- ? sk_sp<GeometryTransform>(new GeometryTransform(std::move(child), std::move(matrix)))
+ static sk_sp<GeometryTransform> Make(sk_sp<GeometryNode> child, sk_sp<Transform> transform) {
+ return child && transform
+ ? sk_sp<GeometryTransform>(new GeometryTransform(std::move(child),
+ std::move(transform)))
: nullptr;
}
@@ -34,7 +33,7 @@
~GeometryTransform() override;
- const sk_sp<Matrix>& getMatrix() const { return fMatrix; }
+ const sk_sp<Transform>& getTransform() const { return fTransform; }
protected:
void onClip(SkCanvas*, bool antiAlias) const override;
@@ -44,11 +43,11 @@
SkPath onAsPath() const override;
private:
- GeometryTransform(sk_sp<GeometryNode>, sk_sp<Matrix>);
+ GeometryTransform(sk_sp<GeometryNode>, sk_sp<Transform>);
const sk_sp<GeometryNode> fChild;
- const sk_sp<Matrix> fMatrix;
- SkPath fTransformed;
+ const sk_sp<Transform> fTransform;
+ SkPath fTransformedPath;
using INHERITED = GeometryNode;
};
diff --git a/modules/sksg/include/SkSGTransform.h b/modules/sksg/include/SkSGTransform.h
index 790373b..e08f4ec 100644
--- a/modules/sksg/include/SkSGTransform.h
+++ b/modules/sksg/include/SkSGTransform.h
@@ -11,21 +11,40 @@
#include "SkSGEffectNode.h"
#include "SkMatrix.h"
+#include "SkMatrix44.h"
namespace sksg {
/**
- * Concrete node, wrapping an SkMatrix, with an optional parent Matrix (to allow chaining):
- *
- * M' = parent x M
+ * Transformations base class.
*/
-class Matrix : public Node {
+class Transform : public Node {
public:
- static sk_sp<Matrix> Make(const SkMatrix& m, sk_sp<Matrix> parent = nullptr);
+ // Compose T = A x B
+ static sk_sp<Transform> MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b);
+
+ // TODO: hide these from public API?
+ virtual SkMatrix asMatrix () const = 0;
+ virtual SkMatrix44 asMatrix44() const = 0;
+
+protected:
+ Transform();
+
+private:
+ using INHERITED = Node;
+};
+
+/**
+ * Concrete, SkMatrix-backed transformation.
+ */
+class Matrix final : public Transform {
+public:
+ static sk_sp<Matrix> Make(const SkMatrix& m);
SG_ATTRIBUTE(Matrix, SkMatrix, fMatrix)
- virtual const SkMatrix& getTotalMatrix() const;
+ SkMatrix asMatrix () const override;
+ SkMatrix44 asMatrix44() const override;
protected:
explicit Matrix(const SkMatrix&);
@@ -35,27 +54,50 @@
private:
SkMatrix fMatrix;
- typedef Node INHERITED;
+ using INHERITED = Transform;
};
/**
- * Concrete Effect node, binding a Matrix to a RenderNode.
+ * Concrete, SkMatrix44-backed transformation.
*/
-class Transform final : public EffectNode {
+class Matrix44 final : public Transform {
public:
- static sk_sp<Transform> Make(sk_sp<RenderNode> child, sk_sp<Matrix> matrix) {
- return child && matrix
- ? sk_sp<Transform>(new Transform(std::move(child), std::move(matrix)))
+ static sk_sp<Matrix44> Make(const SkMatrix44& m);
+
+ SG_ATTRIBUTE(Matrix, SkMatrix44, fMatrix)
+
+ SkMatrix asMatrix () const override;
+ SkMatrix44 asMatrix44() const override;
+
+protected:
+ explicit Matrix44(const SkMatrix44&);
+
+ SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+
+private:
+ SkMatrix44 fMatrix;
+
+ using INHERITED = Transform;
+};
+
+/**
+ * Concrete Effect node, binding a Transform to a RenderNode.
+ */
+class TransformEffect final : public EffectNode {
+public:
+ static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, sk_sp<Transform> transform) {
+ return child && transform
+ ? sk_sp<TransformEffect>(new TransformEffect(std::move(child), std::move(transform)))
: nullptr;
}
- static sk_sp<Transform> Make(sk_sp<RenderNode> child, const SkMatrix& m) {
+ static sk_sp<TransformEffect> Make(sk_sp<RenderNode> child, const SkMatrix& m) {
return Make(std::move(child), Matrix::Make(m));
}
- ~Transform() override;
+ ~TransformEffect() override;
- const sk_sp<Matrix>& getMatrix() const { return fMatrix; }
+ const sk_sp<Transform>& getTransform() const { return fTransform; }
protected:
void onRender(SkCanvas*, const RenderContext*) const override;
@@ -63,9 +105,9 @@
SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
private:
- Transform(sk_sp<RenderNode>, sk_sp<Matrix>);
+ TransformEffect(sk_sp<RenderNode>, sk_sp<Transform>);
- const sk_sp<Matrix> fMatrix;
+ const sk_sp<Transform> fTransform;
typedef EffectNode INHERITED;
};
diff --git a/modules/sksg/samples/SampleSVGPong.cpp b/modules/sksg/samples/SampleSVGPong.cpp
index 15a1afe..a849add 100644
--- a/modules/sksg/samples/SampleSVGPong.cpp
+++ b/modules/sksg/samples/SampleSVGPong.cpp
@@ -144,7 +144,7 @@
SkMatrix::MakeRectToRect(SkRect::MakeWH(1, 1),
SkRect::MakeIWH(this->width(), this->height()),
SkMatrix::kFill_ScaleToFit));
- auto root = sksg::Transform::Make(std::move(group), fContentMatrix);
+ auto root = sksg::TransformEffect::Make(std::move(group), fContentMatrix);
fScene = sksg::Scene::Make(std::move(root), sksg::AnimatorList());
// Off we go.
diff --git a/modules/sksg/src/SkSGGeometryTransform.cpp b/modules/sksg/src/SkSGGeometryTransform.cpp
index 220b056..5630099 100644
--- a/modules/sksg/src/SkSGGeometryTransform.cpp
+++ b/modules/sksg/src/SkSGGeometryTransform.cpp
@@ -11,44 +11,44 @@
namespace sksg {
-GeometryTransform::GeometryTransform(sk_sp<GeometryNode> child, sk_sp<Matrix> matrix)
+GeometryTransform::GeometryTransform(sk_sp<GeometryNode> child, sk_sp<Transform> transform)
: fChild(std::move(child))
- , fMatrix(std::move(matrix)) {
+ , fTransform(std::move(transform)) {
this->observeInval(fChild);
- this->observeInval(fMatrix);
+ this->observeInval(fTransform);
}
GeometryTransform::~GeometryTransform() {
this->unobserveInval(fChild);
- this->unobserveInval(fMatrix);
+ this->unobserveInval(fTransform);
}
void GeometryTransform::onClip(SkCanvas* canvas, bool antiAlias) const {
- canvas->clipPath(fTransformed, SkClipOp::kIntersect, antiAlias);
+ canvas->clipPath(fTransformedPath, SkClipOp::kIntersect, antiAlias);
}
void GeometryTransform::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
- canvas->drawPath(fTransformed, paint);
+ canvas->drawPath(fTransformedPath, paint);
}
SkRect GeometryTransform::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
SkASSERT(this->hasInval());
// We don't care about matrix reval results.
- fMatrix->revalidate(ic, ctm);
- const auto& m = fMatrix->getMatrix();
+ fTransform->revalidate(ic, ctm);
+ const auto m = fTransform->asMatrix();
auto bounds = fChild->revalidate(ic, ctm);
- fTransformed = fChild->asPath();
- fTransformed.transform(m);
- fTransformed.shrinkToFit();
+ fTransformedPath = fChild->asPath();
+ fTransformedPath.transform(m);
+ fTransformedPath.shrinkToFit();
m.mapRect(&bounds);
return bounds;
}
SkPath GeometryTransform::onAsPath() const {
- return fTransformed;
+ return fTransformedPath;
}
} // namespace sksg
diff --git a/modules/sksg/src/SkSGTransform.cpp b/modules/sksg/src/SkSGTransform.cpp
index 76b180a..ddfabd9 100644
--- a/modules/sksg/src/SkSGTransform.cpp
+++ b/modules/sksg/src/SkSGTransform.cpp
@@ -10,53 +10,75 @@
#include "SkCanvas.h"
namespace sksg {
+
namespace {
-class ComposedMatrix final : public Matrix {
+// Always compose in 4x4 for now.
+class Concat final : public Transform {
public:
- ComposedMatrix(const SkMatrix& m, sk_sp<Matrix> parent)
- : INHERITED(m)
- , fParent(std::move(parent)) {
- SkASSERT(fParent);
- this->observeInval(fParent);
+ Concat(sk_sp<Transform> a, sk_sp<Transform> b)
+ : fA(std::move(a)), fB(std::move(b)) {
+ SkASSERT(fA);
+ SkASSERT(fB);
+
+ this->observeInval(fA);
+ this->observeInval(fB);
}
- ~ComposedMatrix() override {
- this->unobserveInval(fParent);
+ ~Concat() override {
+ this->unobserveInval(fA);
+ this->unobserveInval(fB);
}
- const SkMatrix& getTotalMatrix() const override {
- SkASSERT(!this->hasInval());
- return fTotalMatrix;
+ SkMatrix asMatrix() const override {
+ return fComposed;
+ }
+
+ SkMatrix44 asMatrix44() const override {
+ return fComposed;
}
protected:
SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
- fParent->revalidate(ic, ctm);
- fTotalMatrix = SkMatrix::Concat(fParent->getTotalMatrix(), this->getMatrix());
+ fA->revalidate(ic, ctm);
+ fB->revalidate(ic, ctm);
+
+ fComposed.setConcat(fA->asMatrix44(), fB->asMatrix44());
return SkRect::MakeEmpty();
}
private:
- const sk_sp<Matrix> fParent;
- SkMatrix fTotalMatrix; // cached during revalidation.
+ const sk_sp<Transform> fA, fB;
+ SkMatrix44 fComposed;
- using INHERITED = Matrix;
+ using INHERITED = Transform;
};
} // namespace
-sk_sp<Matrix> Matrix::Make(const SkMatrix& m, sk_sp<Matrix> parent) {
- return sk_sp<Matrix>(parent ? new ComposedMatrix(m, std::move(parent))
- : new Matrix(m));
+// Transform nodes don't generate damage on their own, but via ancestor TransformEffects.
+Transform::Transform() : INHERITED(kBubbleDamage_Trait) {}
+
+sk_sp<Transform> Transform::MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b) {
+ if (!a) {
+ return b;
+ }
+
+ return b ? sk_make_sp<Concat>(std::move(a), std::move(b))
+ : a;
}
-// 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) {}
+sk_sp<Matrix> Matrix::Make(const SkMatrix& m) {
+ return sk_sp<Matrix>(new Matrix(m));
+}
-const SkMatrix& Matrix::getTotalMatrix() const {
+Matrix::Matrix(const SkMatrix& m) : fMatrix(m) {}
+
+SkMatrix Matrix::asMatrix() const {
+ return fMatrix;
+}
+
+SkMatrix44 Matrix::asMatrix44() const {
return fMatrix;
}
@@ -64,30 +86,48 @@
return SkRect::MakeEmpty();
}
-Transform::Transform(sk_sp<RenderNode> child, sk_sp<Matrix> matrix)
+sk_sp<Matrix44> Matrix44::Make(const SkMatrix44& m) {
+ return sk_sp<Matrix44>(new Matrix44(m));
+}
+
+Matrix44::Matrix44(const SkMatrix44& m) : fMatrix(m) {}
+
+SkMatrix Matrix44::asMatrix() const {
+ return fMatrix;
+}
+
+SkMatrix44 Matrix44::asMatrix44() const {
+ return fMatrix;
+}
+
+SkRect Matrix44::onRevalidate(InvalidationController*, const SkMatrix&) {
+ return SkRect::MakeEmpty();
+}
+
+TransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform)
: INHERITED(std::move(child))
- , fMatrix(std::move(matrix)) {
- this->observeInval(fMatrix);
+ , fTransform(std::move(transform)) {
+ this->observeInval(fTransform);
}
-Transform::~Transform() {
- this->unobserveInval(fMatrix);
+TransformEffect::~TransformEffect() {
+ this->unobserveInval(fTransform);
}
-void Transform::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
- const auto& m = fMatrix->getTotalMatrix();
+void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
+ const auto m = fTransform->asMatrix();
SkAutoCanvasRestore acr(canvas, !m.isIdentity());
canvas->concat(m);
this->INHERITED::onRender(canvas, ctx);
}
-SkRect Transform::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
+SkRect TransformEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
SkASSERT(this->hasInval());
// We don't care about matrix reval results.
- fMatrix->revalidate(ic, ctm);
+ fTransform->revalidate(ic, ctm);
- const auto& m = fMatrix->getTotalMatrix();
+ const auto m = fTransform->asMatrix();
auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
m.mapRect(&bounds);
diff --git a/modules/sksg/tests/SGTest.cpp b/modules/sksg/tests/SGTest.cpp
index 1b6e4f9..0d614ff 100644
--- a/modules/sksg/tests/SGTest.cpp
+++ b/modules/sksg/tests/SGTest.cpp
@@ -61,7 +61,7 @@
r2 = sksg::Rect::Make(SkRect::MakeWH(100, 100));
auto grp = sksg::Group::Make();
auto matrix = sksg::Matrix::Make(SkMatrix::I());
- auto root = sksg::Transform::Make(grp, matrix);
+ auto root = sksg::TransformEffect::Make(grp, matrix);
grp->addChild(sksg::Draw::Make(r1, color));
grp->addChild(sksg::Draw::Make(r2, color));
@@ -129,9 +129,10 @@
auto color = sksg::Color::Make(0xff000000);
auto rect = sksg::Rect::Make(SkRect::MakeWH(100, 100));
auto m1 = sksg::Matrix::Make(SkMatrix::I()),
- m2 = sksg::Matrix::Make(SkMatrix::I(), m1);
- auto t1 = sksg::Transform::Make(sksg::Draw::Make(rect, color), m2),
- t2 = sksg::Transform::Make(sksg::Draw::Make(rect, color), m1);
+ m2 = sksg::Matrix::Make(SkMatrix::I());
+ auto t1 = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color),
+ sksg::Transform::MakeConcat(m1, m2)),
+ t2 = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color), m1);
auto root = sksg::Group::Make();
root->addChild(t1);
root->addChild(t2);
diff --git a/src/core/SkMatrix44.cpp b/src/core/SkMatrix44.cpp
index 1b08987..07aba07 100644
--- a/src/core/SkMatrix44.cpp
+++ b/src/core/SkMatrix44.cpp
@@ -998,7 +998,7 @@
SkMatrix44::operator SkMatrix() const {
SkMatrix dst;
- dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]);
+ dst[SkMatrix::kMScaleX] = SkMScalarToScalar(fMat[0][0]);
dst[SkMatrix::kMSkewX] = SkMScalarToScalar(fMat[1][0]);
dst[SkMatrix::kMTransX] = SkMScalarToScalar(fMat[3][0]);
diff --git a/tools/viewer/SlideDir.cpp b/tools/viewer/SlideDir.cpp
index 09ecd7c..54db653 100644
--- a/tools/viewer/SlideDir.cpp
+++ b/tools/viewer/SlideDir.cpp
@@ -101,9 +101,10 @@
} // namespace
struct SlideDir::Rec {
- sk_sp<Slide> fSlide;
- sk_sp<sksg::Transform> fTransform;
- SkRect fRect;
+ sk_sp<Slide> fSlide;
+ sk_sp<sksg::RenderNode> fSlideRoot;
+ sk_sp<sksg::Matrix> fMatrix;
+ SkRect fRect;
};
class SlideDir::FocusController final : public sksg::Animator {
@@ -128,9 +129,9 @@
fTarget = target;
// Move the shade & slide to front.
- fDir->fRoot->removeChild(fTarget->fTransform);
+ fDir->fRoot->removeChild(fTarget->fSlideRoot);
fDir->fRoot->addChild(fShade);
- fDir->fRoot->addChild(fTarget->fTransform);
+ fDir->fRoot->addChild(fTarget->fSlideRoot);
fM0 = SlideMatrix(fTarget->fSlide, fTarget->fRect);
fM1 = SlideMatrix(fTarget->fSlide, fRect);
@@ -197,7 +198,7 @@
}
SkASSERT(fTarget);
- fTarget->fTransform->getMatrix()->setMatrix(m);
+ fTarget->fMatrix->setMatrix(m);
const auto shadeOpacity = fOpacity0 + map_t * (fOpacity1 - fOpacity0);
fShadePaint->setOpacity(shadeOpacity);
@@ -305,7 +306,7 @@
fCellSize.height()),
slideRect = cell.makeInset(kPadding.width(), kPadding.height());
- auto slideMatrix = SlideMatrix(slide, slideRect);
+ auto slideMatrix = sksg::Matrix::Make(SlideMatrix(slide, slideRect));
auto adapter = sk_make_sp<SlideAdapter>(slide);
auto slideGrp = sksg::Group::Make();
slideGrp->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeIWH(slideSize.width(),
@@ -314,13 +315,13 @@
slideGrp->addChild(adapter);
slideGrp->addChild(MakeLabel(slide->getName(),
SkPoint::Make(slideSize.width() / 2, slideSize.height()),
- slideMatrix));
- auto slideTransform = sksg::Transform::Make(std::move(slideGrp), slideMatrix);
+ slideMatrix->getMatrix()));
+ auto slideRoot = sksg::TransformEffect::Make(std::move(slideGrp), slideMatrix);
sceneAnimators.push_back(adapter->makeForwardingAnimator());
- fRoot->addChild(slideTransform);
- fRecs.push_back({ slide, slideTransform, slideRect });
+ fRoot->addChild(slideRoot);
+ fRecs.push_back({ slide, slideRoot, slideMatrix, slideRect });
}
fScene = sksg::Scene::Make(fRoot, std::move(sceneAnimators));