Flutter Engine
The Flutter Engine
SkSGTransform.cpp
Go to the documentation of this file.
1/*
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
13
14namespace sksg {
15namespace {
16
17template <typename T>
18SkMatrix AsSkMatrix(const T&);
19
20template <>
21SkMatrix AsSkMatrix<SkMatrix>(const SkMatrix& m) { return m; }
22
23template <>
24SkMatrix AsSkMatrix<SkM44>(const SkM44& m) { return m.asM33(); }
25
26template <typename T>
27SkM44 AsSkM44(const T&);
28
29template <>
30SkM44 AsSkM44<SkMatrix>(const SkMatrix& m) { return SkM44(m); }
31
32template <>
33SkM44 AsSkM44<SkM44>(const SkM44& m) { return m; }
34
35template <typename T>
36class Concat final : public Transform {
37public:
41 : fA(std::move(a)), fB(std::move(b)) {
42 SkASSERT(fA);
43 SkASSERT(fB);
44
45 this->observeInval(fA);
46 this->observeInval(fB);
47 }
48
49 ~Concat() override {
50 this->unobserveInval(fA);
51 this->unobserveInval(fB);
52 }
53
54protected:
55 SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
56 fA->revalidate(ic, ctm);
57 fB->revalidate(ic, ctm);
58
59 fComposed.setConcat(TransformPriv::As<T>(fA),
60 TransformPriv::As<T>(fB));
61 return SkRect::MakeEmpty();
62 }
63
64 bool is44() const override { return std::is_same<T, SkM44>::value; }
65
66 SkMatrix asMatrix() const override {
67 SkASSERT(!this->hasInval());
68 return AsSkMatrix(fComposed);
69 }
70
71 SkM44 asM44() const override {
72 SkASSERT(!this->hasInval());
73 return AsSkM44(fComposed);
74 }
75
76private:
77 const sk_sp<Transform> fA, fB;
78 T fComposed;
79
80 using INHERITED = Transform;
81};
82
83template <typename T>
84class Inverse final : public Transform {
85public:
88 explicit Inverse(sk_sp<Transform> t)
89 : fT(std::move(t)) {
90 SkASSERT(fT);
91
92 this->observeInval(fT);
93 }
94
95 ~Inverse() override {
96 this->unobserveInval(fT);
97 }
98
99protected:
100 SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
101 fT->revalidate(ic, ctm);
102
103 if (!TransformPriv::As<T>(fT).invert(&fInverted)) {
104 fInverted.setIdentity();
105 }
106
107 return SkRect::MakeEmpty();
108 }
109
110 bool is44() const override { return std::is_same<T, SkM44>::value; }
111
112 SkMatrix asMatrix() const override {
113 SkASSERT(!this->hasInval());
114 return AsSkMatrix(fInverted);
115 }
116
117 SkM44 asM44() const override {
118 SkASSERT(!this->hasInval());
119 return AsSkM44(fInverted);
120 }
121
122private:
123 const sk_sp<Transform> fT;
124 T fInverted;
125
126 using INHERITED = Transform;
127};
128
129} // namespace
130
131template <>
133
134template <>
136
137template <>
138SkMatrix Matrix<SkM44>::asMatrix() const { return fMatrix.asM33(); }
139
140template <>
142
143// Transform nodes don't generate damage on their own, but via ancestor TransformEffects.
144Transform::Transform() : INHERITED(kBubbleDamage_Trait) {}
145
147 if (!a) {
148 return b;
149 }
150
151 if (!b) {
152 return a;
153 }
154
156 ? sk_sp<Transform>(new Concat<SkM44 >(std::move(a), std::move(b)))
157 : sk_sp<Transform>(new Concat<SkMatrix>(std::move(a), std::move(b)));
158}
159
161 if (!t) {
162 return nullptr;
163 }
164
165 return TransformPriv::Is44(t)
166 ? sk_sp<Transform>(new Inverse<SkM44 >(std::move(t)))
167 : sk_sp<Transform>(new Inverse<SkMatrix>(std::move(t)));
168}
169
170TransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform)
171 : INHERITED(std::move(child))
172 , fTransform(std::move(transform)) {
173 this->observeInval(fTransform);
174}
175
177 this->unobserveInval(fTransform);
178}
179
180void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
181 SkAutoCanvasRestore acr(canvas, true);
182 canvas->concat(TransformPriv::As<SkM44>(fTransform));
183
184 this->INHERITED::onRender(canvas, ctx);
185}
186
188 const auto p4 = TransformPriv::As<SkM44>(fTransform).map(p.fX, p.fY, 0, 0);
189
190 return this->INHERITED::onNodeAt({p4.x, p4.y});
191}
192
194 SkASSERT(this->hasInval());
195
196 // We don't care about matrix reval results.
197 fTransform->revalidate(ic, ctm);
198
199 // TODO: need to update all the reval plumbing for m44.
200 const auto m = TransformPriv::As<SkMatrix>(fTransform);
201 auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
202 m.mapRect(&bounds);
203
204 return bounds;
205}
206
207} // namespace sksg
SkMatrix fMatrix
Definition: FillRRectOp.cpp:74
#define SkASSERT(cond)
Definition: SkAssert.h:116
#define INHERITED(method,...)
Definition: SkRecorder.cpp:128
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
Definition: SkM44.h:150
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition: SkMatrix.h:1775
const RenderNode * onNodeAt(const SkPoint &) const override
void onRender(SkCanvas *, const RenderContext *) const override
SkRect onRevalidate(InvalidationController *, const SkMatrix &) override
SkMatrix asMatrix() const override
void observeInval(const sk_sp< Node > &)
Definition: SkSGNode.cpp:61
void unobserveInval(const sk_sp< Node > &)
Definition: SkSGNode.cpp:84
const SkRect & bounds() const
Definition: SkSGNode.h:55
bool hasInval() const
Definition: SkSGNode.h:60
const RenderNode * onNodeAt(const SkPoint &) const override
void onRender(SkCanvas *, const RenderContext *) const override
SkRect onRevalidate(InvalidationController *, const SkMatrix &) override
static bool Is44(const sk_sp< Transform > &t)
static sk_sp< Transform > MakeInverse(sk_sp< Transform > t)
static sk_sp< Transform > MakeConcat(sk_sp< Transform > a, sk_sp< Transform > b)
static bool b
struct MyStruct a[10]
gboolean invert
uint8_t value
static const char * Concat(const char *a, const char *b)
Definition: file_test.cc:86
Definition: Skottie.h:32
skgpu::graphite::Transform Transform
Definition: ref_ptr.h:256
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
#define T
Definition: precompiler.cc:65
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595