blob: ddfabd929f1a5262a1f14a64049ca393c9e3744e [file] [log] [blame]
Florin Malita4aa44412017-12-19 12:21:02 -05001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkSGTransform.h"
9
10#include "SkCanvas.h"
11
12namespace sksg {
Florin Malita919e2092019-01-09 15:37:57 -050013
Florin Malita16322632018-09-12 10:15:34 -040014namespace {
15
Florin Malita919e2092019-01-09 15:37:57 -050016// Always compose in 4x4 for now.
17class Concat final : public Transform {
Florin Malita16322632018-09-12 10:15:34 -040018public:
Florin Malita919e2092019-01-09 15:37:57 -050019 Concat(sk_sp<Transform> a, sk_sp<Transform> b)
20 : fA(std::move(a)), fB(std::move(b)) {
21 SkASSERT(fA);
22 SkASSERT(fB);
23
24 this->observeInval(fA);
25 this->observeInval(fB);
Florin Malita18eafd92018-01-04 21:11:55 -050026 }
Florin Malita18eafd92018-01-04 21:11:55 -050027
Florin Malita919e2092019-01-09 15:37:57 -050028 ~Concat() override {
29 this->unobserveInval(fA);
30 this->unobserveInval(fB);
Florin Malita18eafd92018-01-04 21:11:55 -050031 }
Florin Malita18eafd92018-01-04 21:11:55 -050032
Florin Malita919e2092019-01-09 15:37:57 -050033 SkMatrix asMatrix() const override {
34 return fComposed;
35 }
36
37 SkMatrix44 asMatrix44() const override {
38 return fComposed;
Florin Malita18eafd92018-01-04 21:11:55 -050039 }
40
Florin Malita16322632018-09-12 10:15:34 -040041protected:
42 SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
Florin Malita919e2092019-01-09 15:37:57 -050043 fA->revalidate(ic, ctm);
44 fB->revalidate(ic, ctm);
45
46 fComposed.setConcat(fA->asMatrix44(), fB->asMatrix44());
Florin Malita16322632018-09-12 10:15:34 -040047 return SkRect::MakeEmpty();
48 }
49
50private:
Florin Malita919e2092019-01-09 15:37:57 -050051 const sk_sp<Transform> fA, fB;
52 SkMatrix44 fComposed;
Florin Malita16322632018-09-12 10:15:34 -040053
Florin Malita919e2092019-01-09 15:37:57 -050054 using INHERITED = Transform;
Florin Malita16322632018-09-12 10:15:34 -040055};
56
57} // namespace
58
Florin Malita919e2092019-01-09 15:37:57 -050059// Transform nodes don't generate damage on their own, but via ancestor TransformEffects.
60Transform::Transform() : INHERITED(kBubbleDamage_Trait) {}
61
62sk_sp<Transform> Transform::MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b) {
63 if (!a) {
64 return b;
65 }
66
67 return b ? sk_make_sp<Concat>(std::move(a), std::move(b))
68 : a;
Florin Malita16322632018-09-12 10:15:34 -040069}
70
Florin Malita919e2092019-01-09 15:37:57 -050071sk_sp<Matrix> Matrix::Make(const SkMatrix& m) {
72 return sk_sp<Matrix>(new Matrix(m));
73}
Florin Malita16322632018-09-12 10:15:34 -040074
Florin Malita919e2092019-01-09 15:37:57 -050075Matrix::Matrix(const SkMatrix& m) : fMatrix(m) {}
76
77SkMatrix Matrix::asMatrix() const {
78 return fMatrix;
79}
80
81SkMatrix44 Matrix::asMatrix44() const {
Florin Malita16322632018-09-12 10:15:34 -040082 return fMatrix;
83}
84
85SkRect Matrix::onRevalidate(InvalidationController*, const SkMatrix&) {
Florin Malitac14f1442018-01-05 11:32:31 -050086 return SkRect::MakeEmpty();
Florin Malita18eafd92018-01-04 21:11:55 -050087}
88
Florin Malita919e2092019-01-09 15:37:57 -050089sk_sp<Matrix44> Matrix44::Make(const SkMatrix44& m) {
90 return sk_sp<Matrix44>(new Matrix44(m));
91}
92
93Matrix44::Matrix44(const SkMatrix44& m) : fMatrix(m) {}
94
95SkMatrix Matrix44::asMatrix() const {
96 return fMatrix;
97}
98
99SkMatrix44 Matrix44::asMatrix44() const {
100 return fMatrix;
101}
102
103SkRect Matrix44::onRevalidate(InvalidationController*, const SkMatrix&) {
104 return SkRect::MakeEmpty();
105}
106
107TransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform)
Florin Malita4aa44412017-12-19 12:21:02 -0500108 : INHERITED(std::move(child))
Florin Malita919e2092019-01-09 15:37:57 -0500109 , fTransform(std::move(transform)) {
110 this->observeInval(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -0500111}
112
Florin Malita919e2092019-01-09 15:37:57 -0500113TransformEffect::~TransformEffect() {
114 this->unobserveInval(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -0500115}
Florin Malita4aa44412017-12-19 12:21:02 -0500116
Florin Malita919e2092019-01-09 15:37:57 -0500117void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
118 const auto m = fTransform->asMatrix();
Florin Malita18eafd92018-01-04 21:11:55 -0500119 SkAutoCanvasRestore acr(canvas, !m.isIdentity());
120 canvas->concat(m);
Florin Malitac0132ff2018-08-09 07:40:01 -0400121 this->INHERITED::onRender(canvas, ctx);
Florin Malita4aa44412017-12-19 12:21:02 -0500122}
123
Florin Malita919e2092019-01-09 15:37:57 -0500124SkRect TransformEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
Florin Malitac75e2402018-01-03 16:17:29 -0500125 SkASSERT(this->hasInval());
126
Florin Malitac14f1442018-01-05 11:32:31 -0500127 // We don't care about matrix reval results.
Florin Malita919e2092019-01-09 15:37:57 -0500128 fTransform->revalidate(ic, ctm);
Florin Malita18eafd92018-01-04 21:11:55 -0500129
Florin Malita919e2092019-01-09 15:37:57 -0500130 const auto m = fTransform->asMatrix();
Florin Malitac14f1442018-01-05 11:32:31 -0500131 auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
132 m.mapRect(&bounds);
Florin Malitac75e2402018-01-03 16:17:29 -0500133
Florin Malitac14f1442018-01-05 11:32:31 -0500134 return bounds;
Florin Malita4aa44412017-12-19 12:21:02 -0500135}
136
137} // namespace sksg