You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.0 KiB
88 lines
2.0 KiB
/*
|
|
* Copyright 2019 Google LLC.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "experimental/xform/SkXform.h"
|
|
|
|
static std::atomic<uint32_t> gGenID{1};
|
|
Xform::GenID Xform::NextGenID() {
|
|
return gGenID++;
|
|
}
|
|
|
|
#ifdef SK_DEBUG
|
|
void Xform::debugValidate() const {
|
|
if (this->isCached() && fParent) {
|
|
SkASSERT(fParent->isCached());
|
|
}
|
|
for (auto c : fChildren) {
|
|
SkASSERT(c->parent() == this);
|
|
c->debugValidate();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void Xform::setParent(sk_sp<Xform> parent) {
|
|
if (parent == fParent) {
|
|
return;
|
|
}
|
|
|
|
if (fParent) {
|
|
fParent->internalRemoveChild(this);
|
|
}
|
|
if (parent) {
|
|
parent->internalAddChild(this);
|
|
}
|
|
fParent = std::move(parent);
|
|
|
|
// Potentially we could skip this if knew that our old and new parents
|
|
// were both cached, and they started us in the same state...
|
|
// For now, we conservatively always inval
|
|
this->invalidateCaches();
|
|
|
|
this->debugValidate();
|
|
}
|
|
|
|
void Xform::internalAddChild(Xform* child) {
|
|
SkASSERT(fChildren.find(child) < 0);
|
|
fChildren.push_back(child);
|
|
}
|
|
|
|
void Xform::internalRemoveChild(Xform* child) {
|
|
int index = fChildren.find(child);
|
|
SkASSERT(index >= 0);
|
|
fChildren.removeShuffle(index);
|
|
}
|
|
|
|
void Xform::invalidateCaches() {
|
|
fGenID = 0;
|
|
if (this->isCached()) {
|
|
this->internalInvalidateCaches();
|
|
for (auto c : fChildren) {
|
|
c->invalidateCaches();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Xform::visit(XformResolver* resolver) {
|
|
this->onVisit(resolver);
|
|
}
|
|
|
|
void Xform::setCache(const SkMatrix& ctm, sk_sp<ClipCache> clip) {
|
|
fCTM = ctm;
|
|
fClip = std::move(clip);
|
|
fGenID = NextGenID();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void MatrixXF::onVisit(XformResolver* resolver) {
|
|
resolver->concat(fLocalMatrix);
|
|
}
|
|
|
|
void ClipXF::onVisit(XformResolver* resolver) {
|
|
resolver->clipRect(fRect, fOp);
|
|
}
|