1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2017 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGTransform.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 11cb93a386Sopenharmony_ci#include "modules/sksg/src/SkSGTransformPriv.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_cinamespace sksg { 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cinamespace { 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_citemplate <typename T> 18cb93a386Sopenharmony_ciSkMatrix AsSkMatrix(const T&); 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_citemplate <> 21cb93a386Sopenharmony_ciSkMatrix AsSkMatrix<SkMatrix>(const SkMatrix& m) { return m; } 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_citemplate <> 24cb93a386Sopenharmony_ciSkMatrix AsSkMatrix<SkM44>(const SkM44& m) { return m.asM33(); } 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_citemplate <typename T> 27cb93a386Sopenharmony_ciSkM44 AsSkM44(const T&); 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_citemplate <> 30cb93a386Sopenharmony_ciSkM44 AsSkM44<SkMatrix>(const SkMatrix& m) { return SkM44(m); } 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_citemplate <> 33cb93a386Sopenharmony_ciSkM44 AsSkM44<SkM44>(const SkM44& m) { return m; } 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_citemplate <typename T> 36cb93a386Sopenharmony_ciclass Concat final : public Transform { 37cb93a386Sopenharmony_cipublic: 38cb93a386Sopenharmony_ci template <typename = std::enable_if<std::is_same<T, SkMatrix>::value || 39cb93a386Sopenharmony_ci std::is_same<T, SkM44 >::value >> 40cb93a386Sopenharmony_ci Concat(sk_sp<Transform> a, sk_sp<Transform> b) 41cb93a386Sopenharmony_ci : fA(std::move(a)), fB(std::move(b)) { 42cb93a386Sopenharmony_ci SkASSERT(fA); 43cb93a386Sopenharmony_ci SkASSERT(fB); 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci this->observeInval(fA); 46cb93a386Sopenharmony_ci this->observeInval(fB); 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci ~Concat() override { 50cb93a386Sopenharmony_ci this->unobserveInval(fA); 51cb93a386Sopenharmony_ci this->unobserveInval(fB); 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_ciprotected: 55cb93a386Sopenharmony_ci SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override { 56cb93a386Sopenharmony_ci fA->revalidate(ic, ctm); 57cb93a386Sopenharmony_ci fB->revalidate(ic, ctm); 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci fComposed.setConcat(TransformPriv::As<T>(fA), 60cb93a386Sopenharmony_ci TransformPriv::As<T>(fB)); 61cb93a386Sopenharmony_ci return SkRect::MakeEmpty(); 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci bool is44() const override { return std::is_same<T, SkM44>::value; } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci SkMatrix asMatrix() const override { 67cb93a386Sopenharmony_ci SkASSERT(!this->hasInval()); 68cb93a386Sopenharmony_ci return AsSkMatrix(fComposed); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci SkM44 asM44() const override { 72cb93a386Sopenharmony_ci SkASSERT(!this->hasInval()); 73cb93a386Sopenharmony_ci return AsSkM44(fComposed); 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ciprivate: 77cb93a386Sopenharmony_ci const sk_sp<Transform> fA, fB; 78cb93a386Sopenharmony_ci T fComposed; 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci using INHERITED = Transform; 81cb93a386Sopenharmony_ci}; 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_citemplate <typename T> 84cb93a386Sopenharmony_ciclass Inverse final : public Transform { 85cb93a386Sopenharmony_cipublic: 86cb93a386Sopenharmony_ci template <typename = std::enable_if<std::is_same<T, SkMatrix>::value || 87cb93a386Sopenharmony_ci std::is_same<T, SkM44 >::value >> 88cb93a386Sopenharmony_ci explicit Inverse(sk_sp<Transform> t) 89cb93a386Sopenharmony_ci : fT(std::move(t)) { 90cb93a386Sopenharmony_ci SkASSERT(fT); 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci this->observeInval(fT); 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci ~Inverse() override { 96cb93a386Sopenharmony_ci this->unobserveInval(fT); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ciprotected: 100cb93a386Sopenharmony_ci SkRect onRevalidate(InvalidationController* ic, const SkMatrix& ctm) override { 101cb93a386Sopenharmony_ci fT->revalidate(ic, ctm); 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci if (!TransformPriv::As<T>(fT).invert(&fInverted)) { 104cb93a386Sopenharmony_ci fInverted.setIdentity(); 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci return SkRect::MakeEmpty(); 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci 110cb93a386Sopenharmony_ci bool is44() const override { return std::is_same<T, SkM44>::value; } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci SkMatrix asMatrix() const override { 113cb93a386Sopenharmony_ci SkASSERT(!this->hasInval()); 114cb93a386Sopenharmony_ci return AsSkMatrix(fInverted); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci SkM44 asM44() const override { 118cb93a386Sopenharmony_ci SkASSERT(!this->hasInval()); 119cb93a386Sopenharmony_ci return AsSkM44(fInverted); 120cb93a386Sopenharmony_ci } 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ciprivate: 123cb93a386Sopenharmony_ci const sk_sp<Transform> fT; 124cb93a386Sopenharmony_ci T fInverted; 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci using INHERITED = Transform; 127cb93a386Sopenharmony_ci}; 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci} // namespace 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_citemplate <> 132cb93a386Sopenharmony_ciSkMatrix Matrix<SkMatrix>::asMatrix() const { return fMatrix; } 133cb93a386Sopenharmony_ci 134cb93a386Sopenharmony_citemplate <> 135cb93a386Sopenharmony_ciSkM44 Matrix<SkMatrix>::asM44() const { return SkM44(fMatrix); } 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_citemplate <> 138cb93a386Sopenharmony_ciSkMatrix Matrix<SkM44>::asMatrix() const { return fMatrix.asM33(); } 139cb93a386Sopenharmony_ci 140cb93a386Sopenharmony_citemplate <> 141cb93a386Sopenharmony_ciSkM44 Matrix<SkM44>::asM44() const { return fMatrix; } 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci// Transform nodes don't generate damage on their own, but via ancestor TransformEffects. 144cb93a386Sopenharmony_ciTransform::Transform() : INHERITED(kBubbleDamage_Trait) {} 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_cisk_sp<Transform> Transform::MakeConcat(sk_sp<Transform> a, sk_sp<Transform> b) { 147cb93a386Sopenharmony_ci if (!a) { 148cb93a386Sopenharmony_ci return b; 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci if (!b) { 152cb93a386Sopenharmony_ci return a; 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci return TransformPriv::Is44(a) || TransformPriv::Is44(b) 156cb93a386Sopenharmony_ci ? sk_sp<Transform>(new Concat<SkM44 >(std::move(a), std::move(b))) 157cb93a386Sopenharmony_ci : sk_sp<Transform>(new Concat<SkMatrix>(std::move(a), std::move(b))); 158cb93a386Sopenharmony_ci} 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_cisk_sp<Transform> Transform::MakeInverse(sk_sp<Transform> t) { 161cb93a386Sopenharmony_ci if (!t) { 162cb93a386Sopenharmony_ci return nullptr; 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci return TransformPriv::Is44(t) 166cb93a386Sopenharmony_ci ? sk_sp<Transform>(new Inverse<SkM44 >(std::move(t))) 167cb93a386Sopenharmony_ci : sk_sp<Transform>(new Inverse<SkMatrix>(std::move(t))); 168cb93a386Sopenharmony_ci} 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ciTransformEffect::TransformEffect(sk_sp<RenderNode> child, sk_sp<Transform> transform) 171cb93a386Sopenharmony_ci : INHERITED(std::move(child)) 172cb93a386Sopenharmony_ci , fTransform(std::move(transform)) { 173cb93a386Sopenharmony_ci this->observeInval(fTransform); 174cb93a386Sopenharmony_ci} 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_ciTransformEffect::~TransformEffect() { 177cb93a386Sopenharmony_ci this->unobserveInval(fTransform); 178cb93a386Sopenharmony_ci} 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_civoid TransformEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const { 181cb93a386Sopenharmony_ci SkAutoCanvasRestore acr(canvas, true); 182cb93a386Sopenharmony_ci canvas->concat(TransformPriv::As<SkM44>(fTransform)); 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ci this->INHERITED::onRender(canvas, ctx); 185cb93a386Sopenharmony_ci} 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ciconst RenderNode* TransformEffect::onNodeAt(const SkPoint& p) const { 188cb93a386Sopenharmony_ci const auto p4 = TransformPriv::As<SkM44>(fTransform).map(p.fX, p.fY, 0, 0); 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ci return this->INHERITED::onNodeAt({p4.x, p4.y}); 191cb93a386Sopenharmony_ci} 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ciSkRect TransformEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) { 194cb93a386Sopenharmony_ci SkASSERT(this->hasInval()); 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci // We don't care about matrix reval results. 197cb93a386Sopenharmony_ci fTransform->revalidate(ic, ctm); 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci // TODO: need to update all the reval plumbing for m44. 200cb93a386Sopenharmony_ci const auto m = TransformPriv::As<SkMatrix>(fTransform); 201cb93a386Sopenharmony_ci auto bounds = this->INHERITED::onRevalidate(ic, SkMatrix::Concat(ctm, m)); 202cb93a386Sopenharmony_ci m.mapRect(&bounds); 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_ci return bounds; 205cb93a386Sopenharmony_ci} 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_ci} // namespace sksg 208