• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 #include "SkSGTransform.h"
9 
10 #include "SkCanvas.h"
11 #include "SkSGTransformPriv.h"
12 
13 namespace sksg {
14 
15 namespace {
16 
17 template <typename T>
18 class Concat final : public Transform {
19 public:
20     template <typename = std::enable_if<std::is_same<T, SkMatrix  >::value ||
21                                         std::is_same<T, SkMatrix44>::value >>
Concat(sk_sp<Transform> a,sk_sp<Transform> b)22     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);
29     }
30 
~Concat()31     ~Concat() override {
32         this->unobserveInval(fA);
33         this->unobserveInval(fB);
34     }
35 
36 protected:
onRevalidate(InvalidationController * ic,const SkMatrix & ctm)37     SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override {
38         fA->revalidate(ic, ctm);
39         fB->revalidate(ic, ctm);
40 
41         fComposed.setConcat(TransformPriv::As<T>(fA),
42                             TransformPriv::As<T>(fB));
43         return SkRect::MakeEmpty();
44     }
45 
is44() const46     bool is44() const override { return std::is_same<T, SkMatrix44>::value; }
47 
asMatrix() const48     SkMatrix asMatrix() const override {
49         return fComposed;
50     }
51 
asMatrix44() const52     SkMatrix44 asMatrix44() const override {
53         return fComposed;
54     }
55 
56 private:
57     const sk_sp<Transform> fA, fB;
58     T                      fComposed;
59 
60     using INHERITED = Transform;
61 };
62 
63 } // namespace
64 
65 // Transform nodes don't generate damage on their own, but via ancestor TransformEffects.
Transform()66 Transform::Transform() : INHERITED(kBubbleDamage_Trait) {}
67 
MakeConcat(sk_sp<Transform> a,sk_sp<Transform> b)68 sk_sp<Transform> Transform::MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b) {
69     if (!a) {
70         return b;
71     }
72 
73     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)));
80 }
81 
TransformEffect(sk_sp<RenderNode> child,sk_sp<Transform> transform)82 TransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform)
83     : INHERITED(std::move(child))
84     , fTransform(std::move(transform)) {
85     this->observeInval(fTransform);
86 }
87 
~TransformEffect()88 TransformEffect::~TransformEffect() {
89     this->unobserveInval(fTransform);
90 }
91 
onRender(SkCanvas * canvas,const RenderContext * ctx) const92 void TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
93     const auto m = TransformPriv::As<SkMatrix>(fTransform);
94     SkAutoCanvasRestore acr(canvas, !m.isIdentity());
95     canvas->concat(m);
96     this->INHERITED::onRender(canvas, ctx);
97 }
98 
onNodeAt(const SkPoint & p) const99 const 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 
onRevalidate(InvalidationController * ic,const SkMatrix & ctm)108 SkRect TransformEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
109     SkASSERT(this->hasInval());
110 
111     // We don't care about matrix reval results.
112     fTransform->revalidate(ic, ctm);
113 
114     const auto m = TransformPriv::As<SkMatrix>(fTransform);
115     auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m));
116     m.mapRect(&bounds);
117 
118     return bounds;
119 }
120 
121 } // namespace sksg
122