1 /* 2 * Copyright 2019 Google LLC. 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 "experimental/xform/SkXform.h" 9 10 static std::atomic<uint32_t> gGenID{1}; NextGenID()11Xform::GenID Xform::NextGenID() { 12 return gGenID++; 13 } 14 15 #ifdef SK_DEBUG debugValidate() const16void Xform::debugValidate() const { 17 if (this->isCached() && fParent) { 18 SkASSERT(fParent->isCached()); 19 } 20 for (auto c : fChildren) { 21 SkASSERT(c->parent() == this); 22 c->debugValidate(); 23 } 24 } 25 #endif 26 setParent(sk_sp<Xform> parent)27void Xform::setParent(sk_sp<Xform> parent) { 28 if (parent == fParent) { 29 return; 30 } 31 32 if (fParent) { 33 fParent->internalRemoveChild(this); 34 } 35 if (parent) { 36 parent->internalAddChild(this); 37 } 38 fParent = std::move(parent); 39 40 // Potentially we could skip this if knew that our old and new parents 41 // were both cached, and they started us in the same state... 42 // For now, we conservatively always inval 43 this->invalidateCaches(); 44 45 this->debugValidate(); 46 } 47 internalAddChild(Xform * child)48void Xform::internalAddChild(Xform* child) { 49 SkASSERT(fChildren.find(child) < 0); 50 fChildren.push_back(child); 51 } 52 internalRemoveChild(Xform * child)53void Xform::internalRemoveChild(Xform* child) { 54 int index = fChildren.find(child); 55 SkASSERT(index >= 0); 56 fChildren.removeShuffle(index); 57 } 58 invalidateCaches()59void Xform::invalidateCaches() { 60 fGenID = 0; 61 if (this->isCached()) { 62 this->internalInvalidateCaches(); 63 for (auto c : fChildren) { 64 c->invalidateCaches(); 65 } 66 } 67 } 68 visit(XformResolver * resolver)69void Xform::visit(XformResolver* resolver) { 70 this->onVisit(resolver); 71 } 72 setCache(const SkMatrix & ctm,sk_sp<ClipCache> clip)73void Xform::setCache(const SkMatrix& ctm, sk_sp<ClipCache> clip) { 74 fCTM = ctm; 75 fClip = std::move(clip); 76 fGenID = NextGenID(); 77 } 78 79 ////////////////////////////////////////////////////////////////////////////////////////////////// 80 onVisit(XformResolver * resolver)81void MatrixXF::onVisit(XformResolver* resolver) { 82 resolver->concat(fLocalMatrix); 83 } 84 onVisit(XformResolver * resolver)85void ClipXF::onVisit(XformResolver* resolver) { 86 resolver->clipRect(fRect, fOp); 87 } 88