blob: e869c3a476b223e5d5bfc6c87bdbff2dc14d3356 [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"
Florin Malitadf0e1af2019-01-10 11:27:13 -050011#include "SkSGTransformPriv.h"
Florin Malita4aa44412017-12-19 12:21:02 -050012
13namespace sksg {
Florin Malita919e2092019-01-09 15:37:57 -050014
Florin Malita16322632018-09-12 10:15:34 -040015namespace {
16
Florin Malita919e2092019-01-09 15:37:57 -050017// Always compose in 4x4 for now.
18class Concat final : public Transform {
Florin Malita16322632018-09-12 10:15:34 -040019public:
Florin Malita919e2092019-01-09 15:37:57 -050020 Concat(sk_sp<Transform> a, sk_sp<Transform> b)
21 : fA(std::move(a)), fB(std::move(b)) {
22 SkASSERT(fA);
23 SkASSERT(fB);
24
25 this->observeInval(fA);
26 this->observeInval(fB);
Florin Malita18eafd92018-01-04 21:11:55 -050027 }
Florin Malita18eafd92018-01-04 21:11:55 -050028
Florin Malita919e2092019-01-09 15:37:57 -050029 ~Concat() override {
30 this->unobserveInval(fA);
31 this->unobserveInval(fB);
Florin Malita18eafd92018-01-04 21:11:55 -050032 }
Florin Malita18eafd92018-01-04 21:11:55 -050033
Florin Malitadf0e1af2019-01-10 11:27:13 -050034protected:
35 SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
36 fA->revalidate(ic, ctm);
37 fB->revalidate(ic, ctm);
38
39 fComposed.setConcat(TransformPriv::AsMatrix44(fA),
40 TransformPriv::AsMatrix44(fB));
41 return SkRect::MakeEmpty();
42 }
43
Florin Malita919e2092019-01-09 15:37:57 -050044 SkMatrix asMatrix() const override {
45 return fComposed;
46 }
47
48 SkMatrix44 asMatrix44() const override {
49 return fComposed;
Florin Malita18eafd92018-01-04 21:11:55 -050050 }
51
Florin Malita16322632018-09-12 10:15:34 -040052private:
Florin Malita919e2092019-01-09 15:37:57 -050053 const sk_sp<Transform> fA, fB;
54 SkMatrix44 fComposed;
Florin Malita16322632018-09-12 10:15:34 -040055
Florin Malita919e2092019-01-09 15:37:57 -050056 using INHERITED = Transform;
Florin Malita16322632018-09-12 10:15:34 -040057};
58
59} // namespace
60
Florin Malita919e2092019-01-09 15:37:57 -050061// Transform nodes don't generate damage on their own, but via ancestor TransformEffects.
62Transform::Transform() : INHERITED(kBubbleDamage_Trait) {}
63
64sk_sp<Transform> Transform::MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b) {
65 if (!a) {
66 return b;
67 }
68
69 return b ? sk_make_sp<Concat>(std::move(a), std::move(b))
70 : a;
Florin Malita16322632018-09-12 10:15:34 -040071}
72
Florin Malita919e2092019-01-09 15:37:57 -050073sk_sp<Matrix> Matrix::Make(const SkMatrix& m) {
74 return sk_sp<Matrix>(new Matrix(m));
75}
Florin Malita16322632018-09-12 10:15:34 -040076
Florin Malita919e2092019-01-09 15:37:57 -050077Matrix::Matrix(const SkMatrix& m) : fMatrix(m) {}
78
79SkMatrix Matrix::asMatrix() const {
80 return fMatrix;
81}
82
83SkMatrix44 Matrix::asMatrix44() const {
Florin Malita16322632018-09-12 10:15:34 -040084 return fMatrix;
85}
86
87SkRect Matrix::onRevalidate(InvalidationController*, const SkMatrix&) {
Florin Malitac14f1442018-01-05 11:32:31 -050088 return SkRect::MakeEmpty();
Florin Malita18eafd92018-01-04 21:11:55 -050089}
90
Florin Malita919e2092019-01-09 15:37:57 -050091sk_sp<Matrix44> Matrix44::Make(const SkMatrix44& m) {
92 return sk_sp<Matrix44>(new Matrix44(m));
93}
94
95Matrix44::Matrix44(const SkMatrix44& m) : fMatrix(m) {}
96
97SkMatrix Matrix44::asMatrix() const {
98 return fMatrix;
99}
100
101SkMatrix44 Matrix44::asMatrix44() const {
102 return fMatrix;
103}
104
105SkRect Matrix44::onRevalidate(InvalidationController*, const SkMatrix&) {
106 return SkRect::MakeEmpty();
107}
108
109TransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform)
Florin Malita4aa44412017-12-19 12:21:02 -0500110 : INHERITED(std::move(child))
Florin Malita919e2092019-01-09 15:37:57 -0500111 , fTransform(std::move(transform)) {
112 this->observeInval(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -0500113}
114
Florin Malita919e2092019-01-09 15:37:57 -0500115TransformEffect::~TransformEffect() {
116 this->unobserveInval(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -0500117}
Florin Malita4aa44412017-12-19 12:21:02 -0500118
Florin Malita919e2092019-01-09 15:37:57 -0500119void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
Florin Malitadf0e1af2019-01-10 11:27:13 -0500120 const auto m = TransformPriv::AsMatrix(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -0500121 SkAutoCanvasRestore acr(canvas, !m.isIdentity());
122 canvas->concat(m);
Florin Malitac0132ff2018-08-09 07:40:01 -0400123 this->INHERITED::onRender(canvas, ctx);
Florin Malita4aa44412017-12-19 12:21:02 -0500124}
125
Florin Malita919e2092019-01-09 15:37:57 -0500126SkRect TransformEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
Florin Malitac75e2402018-01-03 16:17:29 -0500127 SkASSERT(this->hasInval());
128
Florin Malitac14f1442018-01-05 11:32:31 -0500129 // We don't care about matrix reval results.
Florin Malita919e2092019-01-09 15:37:57 -0500130 fTransform->revalidate(ic, ctm);
Florin Malita18eafd92018-01-04 21:11:55 -0500131
Florin Malitadf0e1af2019-01-10 11:27:13 -0500132 const auto m = TransformPriv::AsMatrix(fTransform);
Florin Malitac14f1442018-01-05 11:32:31 -0500133 auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
134 m.mapRect(&bounds);
Florin Malitac75e2402018-01-03 16:17:29 -0500135
Florin Malitac14f1442018-01-05 11:32:31 -0500136 return bounds;
Florin Malita4aa44412017-12-19 12:21:02 -0500137}
138
139} // namespace sksg