blob: fff1ba49924467b41e56098c60e60b96e7b4b812 [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 Malita13c1b962019-01-10 14:44:59 -050017template <typename T>
Florin Malita919e2092019-01-09 15:37:57 -050018class Concat final : public Transform {
Florin Malita16322632018-09-12 10:15:34 -040019public:
Florin Malita13c1b962019-01-10 14:44:59 -050020 template <typename = std::enable_if<std::is_same<T, SkMatrix >::value ||
21 std::is_same<T, SkMatrix44>::value >>
Florin Malita919e2092019-01-09 15:37:57 -050022 Concat(sk_sp<Transform> a, sk_sp<Transform> b)
23 : fA(std::move(a)), fB(std::move(b)) {
24 SkASSERT(fA);
25 SkASSERT(fB);
26
27 this->observeInval(fA);
28 this->observeInval(fB);
Florin Malita18eafd92018-01-04 21:11:55 -050029 }
Florin Malita18eafd92018-01-04 21:11:55 -050030
Florin Malita919e2092019-01-09 15:37:57 -050031 ~Concat() override {
32 this->unobserveInval(fA);
33 this->unobserveInval(fB);
Florin Malita18eafd92018-01-04 21:11:55 -050034 }
Florin Malita18eafd92018-01-04 21:11:55 -050035
Florin Malitadf0e1af2019-01-10 11:27:13 -050036protected:
37 SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
38 fA->revalidate(ic, ctm);
39 fB->revalidate(ic, ctm);
40
Florin Malita13c1b962019-01-10 14:44:59 -050041 fComposed.setConcat(TransformPriv::As<T>(fA),
42 TransformPriv::As<T>(fB));
Florin Malitadf0e1af2019-01-10 11:27:13 -050043 return SkRect::MakeEmpty();
44 }
45
Florin Malita13c1b962019-01-10 14:44:59 -050046 bool is44() const override { return std::is_same<T, SkMatrix44>::value; }
47
Florin Malita919e2092019-01-09 15:37:57 -050048 SkMatrix asMatrix() const override {
49 return fComposed;
50 }
51
52 SkMatrix44 asMatrix44() const override {
53 return fComposed;
Florin Malita18eafd92018-01-04 21:11:55 -050054 }
55
Florin Malita16322632018-09-12 10:15:34 -040056private:
Florin Malita919e2092019-01-09 15:37:57 -050057 const sk_sp<Transform> fA, fB;
Florin Malita13c1b962019-01-10 14:44:59 -050058 T fComposed;
Florin Malita16322632018-09-12 10:15:34 -040059
Florin Malita919e2092019-01-09 15:37:57 -050060 using INHERITED = Transform;
Florin Malita16322632018-09-12 10:15:34 -040061};
62
63} // namespace
64
Florin Malita919e2092019-01-09 15:37:57 -050065// Transform nodes don't generate damage on their own, but via ancestor TransformEffects.
66Transform::Transform() : INHERITED(kBubbleDamage_Trait) {}
67
68sk_sp<Transform> Transform::MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b) {
69 if (!a) {
70 return b;
71 }
72
Florin Malita13c1b962019-01-10 14:44:59 -050073 if (!b) {
74 return a;
75 }
76
77 return TransformPriv::Is44(a) || TransformPriv::Is44(b)
78 ? sk_sp<Transform>(new Concat<SkMatrix44>(std::move(a), std::move(b)))
79 : sk_sp<Transform>(new Concat<SkMatrix >(std::move(a), std::move(b)));
Florin Malita16322632018-09-12 10:15:34 -040080}
81
Florin Malita919e2092019-01-09 15:37:57 -050082TransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform)
Florin Malita4aa44412017-12-19 12:21:02 -050083 : INHERITED(std::move(child))
Florin Malita919e2092019-01-09 15:37:57 -050084 , fTransform(std::move(transform)) {
85 this->observeInval(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -050086}
87
Florin Malita919e2092019-01-09 15:37:57 -050088TransformEffect::~TransformEffect() {
89 this->unobserveInval(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -050090}
Florin Malita4aa44412017-12-19 12:21:02 -050091
Florin Malita919e2092019-01-09 15:37:57 -050092void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
Florin Malita13c1b962019-01-10 14:44:59 -050093 const auto m = TransformPriv::As<SkMatrix>(fTransform);
Florin Malita18eafd92018-01-04 21:11:55 -050094 SkAutoCanvasRestore acr(canvas, !m.isIdentity());
95 canvas->concat(m);
Florin Malitac0132ff2018-08-09 07:40:01 -040096 this->INHERITED::onRender(canvas, ctx);
Florin Malita4aa44412017-12-19 12:21:02 -050097}
98
Florin Malitaeb46bd82019-02-12 09:33:21 -050099const RenderNode* TransformEffect::onNodeAt(const SkPoint& p) const {
100 const auto m = TransformPriv::As<SkMatrix>(fTransform);
101
102 SkPoint mapped_p;
103 m.mapPoints(&mapped_p, &p, 1);
104
105 return this->INHERITED::onNodeAt(mapped_p);
106}
107
Florin Malita919e2092019-01-09 15:37:57 -0500108SkRect TransformEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
Florin Malitac75e2402018-01-03 16:17:29 -0500109 SkASSERT(this->hasInval());
110
Florin Malitac14f1442018-01-05 11:32:31 -0500111 // We don't care about matrix reval results.
Florin Malita919e2092019-01-09 15:37:57 -0500112 fTransform->revalidate(ic, ctm);
Florin Malita18eafd92018-01-04 21:11:55 -0500113
Florin Malita13c1b962019-01-10 14:44:59 -0500114 const auto m = TransformPriv::As<SkMatrix>(fTransform);
Florin Malitac14f1442018-01-05 11:32:31 -0500115 auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
116 m.mapRect(&bounds);
Florin Malitac75e2402018-01-03 16:17:29 -0500117
Florin Malitac14f1442018-01-05 11:32:31 -0500118 return bounds;
Florin Malita4aa44412017-12-19 12:21:02 -0500119}
120
121} // namespace sksg