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