[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>
This commit is contained in:
Florin Malita 2019-01-09 15:37:57 -05:00 committed by Skia Commit-Bot
parent d2fa7e3379
commit 919e209d1a
14 changed files with 222 additions and 133 deletions

View File

@ -61,13 +61,13 @@ void AnimationBuilder::log(Logger::Level lvl, const skjson::Value* json,
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 @@ sk_sp<sksg::Matrix> AnimationBuilder::attachMatrix2D(const skjson::ObjectValue&
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 @@ sk_sp<sksg::Matrix> AnimationBuilder::attachMatrix3D(const skjson::ObjectValue&
// 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,

View File

@ -73,12 +73,12 @@ TransformAdapter3D::Vec3::Vec3(const VectorValue& v) {
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);

View File

@ -21,6 +21,7 @@ class Gradient;
class Group;
class LinearGradient;
class Matrix;
class Matrix44;
class Path;
class RadialGradient;
class RRect;
@ -105,7 +106,7 @@ private:
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 @@ public:
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 {

View File

@ -372,7 +372,7 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachImageAsset(const skjson::ObjectV
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 @@ struct AnimationBuilder::AttachLayerContext {
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 @@ struct AnimationBuilder::AttachLayerContext {
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 @@ private:
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 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachLayer(const skjson::ObjectValue*
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.

View File

@ -33,6 +33,7 @@ class Color;
class Matrix;
class Path;
class RenderNode;
class Transform;
} // namespace sksg
namespace skottie {
@ -71,10 +72,10 @@ public:
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;

View File

@ -587,7 +587,7 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachShape(const skjson::ArrayValue*
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 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachShape(const skjson::ArrayValue*
// 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 @@ sk_sp<sksg::RenderNode> AnimationBuilder::attachShape(const skjson::ArrayValue*
// 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));
}

View File

@ -13,8 +13,6 @@
#include "SkPath.h"
#include "SkSGTransform.h"
class SkMatrix;
namespace sksg {
/**
@ -22,9 +20,10 @@ namespace sksg {
*/
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 @@ public:
~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 @@ protected:
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;
};

View File

@ -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 @@ protected:
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 @@ protected:
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;
};

View File

@ -144,7 +144,7 @@ protected:
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.

View File

@ -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

View File

@ -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 @@ SkRect Matrix::onRevalidate(InvalidationController*, const SkMatrix&) {
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);

View File

@ -61,7 +61,7 @@ static void inval_test1(skiatest::Reporter* reporter) {
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 @@ static void inval_test2(skiatest::Reporter* reporter) {
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);

View File

@ -998,7 +998,7 @@ SkMatrix44& SkMatrix44::operator=(const SkMatrix& src) {
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]);

View File

@ -101,9 +101,10 @@ SkMatrix SlideMatrix(const sk_sp<Slide>& slide, const SkRect& dst) {
} // 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 @@ public:
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 @@ protected:
}
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 @@ void SlideDir::load(SkScalar winWidth, SkScalar winHeight) {
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 @@ void SlideDir::load(SkScalar winWidth, SkScalar winHeight) {
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));