[sksg] Refactor inval registration
... to avoid having too many Node friends.
TBR=
Change-Id: I8f8ff570d94ea48017935066a3d51cd8265ec120
Reviewed-on: https://skia-review.googlesource.com/97980
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/experimental/sksg/SkSGDraw.cpp b/experimental/sksg/SkSGDraw.cpp
index 33c73a5..b73bf3b 100644
--- a/experimental/sksg/SkSGDraw.cpp
+++ b/experimental/sksg/SkSGDraw.cpp
@@ -16,13 +16,13 @@
Draw::Draw(sk_sp<GeometryNode> geometry, sk_sp<PaintNode> paint)
: fGeometry(std::move(geometry))
, fPaint(std::move(paint)) {
- fGeometry->addInvalReceiver(this);
- fPaint->addInvalReceiver(this);
+ this->observeInval(fGeometry);
+ this->observeInval(fPaint);
}
Draw::~Draw() {
- fGeometry->removeInvalReceiver(this);
- fPaint->removeInvalReceiver(this);
+ this->unobserveInval(fGeometry);
+ this->unobserveInval(fPaint);
}
void Draw::onRender(SkCanvas* canvas) const {
diff --git a/experimental/sksg/SkSGEffectNode.cpp b/experimental/sksg/SkSGEffectNode.cpp
index 1ecf7c7..70050cc 100644
--- a/experimental/sksg/SkSGEffectNode.cpp
+++ b/experimental/sksg/SkSGEffectNode.cpp
@@ -11,11 +11,11 @@
EffectNode::EffectNode(sk_sp<RenderNode> child)
: fChild(std::move(child)) {
- fChild->addInvalReceiver(this);
+ this->observeInval(fChild);
}
EffectNode::~EffectNode() {
- fChild->removeInvalReceiver(this);
+ this->unobserveInval(fChild);
}
void EffectNode::onRender(SkCanvas* canvas) const {
diff --git a/experimental/sksg/SkSGGroup.cpp b/experimental/sksg/SkSGGroup.cpp
index b71837a..aeccf23 100644
--- a/experimental/sksg/SkSGGroup.cpp
+++ b/experimental/sksg/SkSGGroup.cpp
@@ -13,7 +13,7 @@
Group::~Group() {
for (const auto& child : fChildren) {
- child->removeInvalReceiver(this);
+ this->unobserveInval(child);
}
}
@@ -25,7 +25,7 @@
}
}
- node->addInvalReceiver(this);
+ this->observeInval(node);
fChildren.push_back(std::move(node));
this->invalidate();
@@ -36,7 +36,7 @@
for (int i = 0; i < origCount; ++i) {
if (fChildren[i] == node) {
fChildren.removeShuffle(i);
- node->removeInvalReceiver(this);
+ this->unobserveInval(node);
break;
}
}
diff --git a/experimental/sksg/SkSGNode.cpp b/experimental/sksg/SkSGNode.cpp
index 74867ef..35b2640 100644
--- a/experimental/sksg/SkSGNode.cpp
+++ b/experimental/sksg/SkSGNode.cpp
@@ -39,64 +39,66 @@
return
Node::Node(uint32_t invalTraits)
- : fInvalReceiver(nullptr)
+ : fInvalObserver(nullptr)
, fBounds(SkRectPriv::MakeLargeS32())
, fInvalTraits(invalTraits)
, fFlags(kInvalidated_Flag) {}
Node::~Node() {
- if (fFlags & kReceiverArray_Flag) {
- SkASSERT(fInvalReceiverArray->isEmpty());
- delete fInvalReceiverArray;
+ if (fFlags & kObserverArray_Flag) {
+ SkASSERT(fInvalObserverArray->isEmpty());
+ delete fInvalObserverArray;
} else {
- SkASSERT(!fInvalReceiver);
+ SkASSERT(!fInvalObserver);
}
}
-void Node::addInvalReceiver(Node* receiver) {
- if (!(fFlags & kReceiverArray_Flag)) {
- if (!fInvalReceiver) {
- fInvalReceiver = receiver;
+void Node::observeInval(const sk_sp<Node>& node) {
+ SkASSERT(node);
+ if (!(node->fFlags & kObserverArray_Flag)) {
+ if (!node->fInvalObserver) {
+ node->fInvalObserver = this;
return;
}
- auto receivers = new SkTDArray<Node*>();
- receivers->setReserve(2);
- receivers->push(fInvalReceiver);
+ auto observers = new SkTDArray<Node*>();
+ observers->setReserve(2);
+ observers->push(node->fInvalObserver);
- fInvalReceiverArray = receivers;
- fFlags |= kReceiverArray_Flag;
+ node->fInvalObserverArray = observers;
+ node->fFlags |= kObserverArray_Flag;
}
- // No duplicate receivers.
- SkASSERT(fInvalReceiverArray->find(receiver) < 0);
+ // No duplicate observers.
+ SkASSERT(node->fInvalObserverArray->find(this) < 0);
- fInvalReceiverArray->push(receiver);
+ node->fInvalObserverArray->push(this);
}
-void Node::removeInvalReceiver(Node* receiver) {
- if (!(fFlags & kReceiverArray_Flag)) {
- SkASSERT(fInvalReceiver == receiver);
- fInvalReceiver = nullptr;
+void Node::unobserveInval(const sk_sp<Node>& node) {
+ SkASSERT(node);
+ if (!(node->fFlags & kObserverArray_Flag)) {
+ SkASSERT(node->fInvalObserver == this);
+ node->fInvalObserver = nullptr;
return;
}
- const auto idx = fInvalReceiverArray->find(receiver);
+ const auto idx = node->fInvalObserverArray->find(this);
SkASSERT(idx >= 0);
- fInvalReceiverArray->remove(idx);
+ node->fInvalObserverArray->remove(idx);
}
template <typename Func>
-void Node::forEachInvalReceiver(Func&& func) const {
- if (fFlags & kReceiverArray_Flag) {
- for (const auto& parent : *fInvalReceiverArray) {
+void Node::forEachInvalObserver(Func&& func) const {
+ if (fFlags & kObserverArray_Flag) {
+ for (const auto& parent : *fInvalObserverArray) {
func(parent);
}
return;
}
- if (fInvalReceiver) {
- func(fInvalReceiver);
+ if (fInvalObserver) {
+ func(fInvalObserver);
}
}
@@ -109,15 +111,15 @@
}
if (damageBubbling && !(fInvalTraits & kBubbleDamage_Trait)) {
- // Found a damage receiver.
+ // Found a damage observer.
fFlags |= kDamage_Flag;
damageBubbling = false;
}
fFlags |= kInvalidated_Flag;
- forEachInvalReceiver([&](Node* receiver) {
- receiver->invalidate(damageBubbling);
+ forEachInvalObserver([&](Node* observer) {
+ observer->invalidate(damageBubbling);
});
}
diff --git a/experimental/sksg/SkSGNode.h b/experimental/sksg/SkSGNode.h
index 5518984..6396e4d 100644
--- a/experimental/sksg/SkSGNode.h
+++ b/experimental/sksg/SkSGNode.h
@@ -57,36 +57,26 @@
// and return their bounding box in local coordinates.
virtual SkRect onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0;
+ // Register/unregister |this| to receive invalidation events from a descendant.
+ void observeInval(const sk_sp<Node>&);
+ void unobserveInval(const sk_sp<Node>&);
+
private:
enum Flags {
kInvalidated_Flag = 1 << 0, // the node or its descendants require revalidation
kDamage_Flag = 1 << 1, // the node contributes damage during revalidation
- kReceiverArray_Flag = 1 << 2, // the node has more than one inval receiver
+ kObserverArray_Flag = 1 << 2, // the node has more than one inval observer
kInTraversal_Flag = 1 << 3, // the node is part of a traversal (cycle detection)
};
- void addInvalReceiver(Node*);
- void removeInvalReceiver(Node*);
- // TODO: too friendly, find another way.
- friend class Draw;
- friend class EffectNode;
- friend class GeometryTransform;
- friend class Group;
- friend class MaskEffect;
- friend class Matrix;
- friend class Merge;
- friend class Stroke;
- friend class Transform;
- friend class TrimEffect;
-
template <typename Func>
- void forEachInvalReceiver(Func&&) const;
+ void forEachInvalObserver(Func&&) const;
class ScopedFlag;
union {
- Node* fInvalReceiver;
- SkTDArray<Node*>* fInvalReceiverArray;
+ Node* fInvalObserver;
+ SkTDArray<Node*>* fInvalObserverArray;
};
SkRect fBounds;
const uint32_t fInvalTraits : 16;
diff --git a/experimental/sksg/effects/SkSGMaskEffect.cpp b/experimental/sksg/effects/SkSGMaskEffect.cpp
index d4ce6df..17b4da7 100644
--- a/experimental/sksg/effects/SkSGMaskEffect.cpp
+++ b/experimental/sksg/effects/SkSGMaskEffect.cpp
@@ -14,11 +14,11 @@
MaskEffect::MaskEffect(sk_sp<RenderNode> child, sk_sp<RenderNode> mask)
: INHERITED(std::move(child))
, fMaskNode(std::move(mask)) {
- fMaskNode->addInvalReceiver(this);
+ this->observeInval(fMaskNode);
}
MaskEffect::~MaskEffect() {
- fMaskNode->removeInvalReceiver(this);
+ this->unobserveInval(fMaskNode);
}
void MaskEffect::onRender(SkCanvas* canvas) const {
diff --git a/experimental/sksg/effects/SkSGTransform.cpp b/experimental/sksg/effects/SkSGTransform.cpp
index a5731b1..6a985a9 100644
--- a/experimental/sksg/effects/SkSGTransform.cpp
+++ b/experimental/sksg/effects/SkSGTransform.cpp
@@ -16,13 +16,13 @@
, fParent(std::move(parent))
, fLocalMatrix(m) {
if (fParent) {
- fParent->addInvalReceiver(this);
+ this->observeInval(fParent);
}
}
Matrix::~Matrix() {
if (fParent) {
- fParent->removeInvalReceiver(this);
+ this->unobserveInval(fParent);
}
}
@@ -40,11 +40,11 @@
Transform::Transform(sk_sp<RenderNode> child, sk_sp<Matrix> matrix)
: INHERITED(std::move(child))
, fMatrix(std::move(matrix)) {
- fMatrix->addInvalReceiver(this);
+ this->observeInval(fMatrix);
}
Transform::~Transform() {
- fMatrix->removeInvalReceiver(this);
+ this->unobserveInval(fMatrix);
}
void Transform::onRender(SkCanvas* canvas) const {
diff --git a/experimental/sksg/geometry/SkSGGeometryTransform.cpp b/experimental/sksg/geometry/SkSGGeometryTransform.cpp
index 14c37d9..91367d4 100644
--- a/experimental/sksg/geometry/SkSGGeometryTransform.cpp
+++ b/experimental/sksg/geometry/SkSGGeometryTransform.cpp
@@ -14,13 +14,13 @@
GeometryTransform::GeometryTransform(sk_sp<GeometryNode> child, sk_sp<Matrix> matrix)
: fChild(std::move(child))
, fMatrix(std::move(matrix)) {
- fChild->addInvalReceiver(this);
- fMatrix->addInvalReceiver(this);
+ this->observeInval(fChild);
+ this->observeInval(fMatrix);
}
GeometryTransform::~GeometryTransform() {
- fChild->removeInvalReceiver(this);
- fMatrix->removeInvalReceiver(this);
+ this->unobserveInval(fChild);
+ this->unobserveInval(fMatrix);
}
SkRect GeometryTransform::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
diff --git a/experimental/sksg/geometry/SkSGMerge.cpp b/experimental/sksg/geometry/SkSGMerge.cpp
index 9c22e75..49e7804 100644
--- a/experimental/sksg/geometry/SkSGMerge.cpp
+++ b/experimental/sksg/geometry/SkSGMerge.cpp
@@ -16,13 +16,13 @@
: fGeos(std::move(geos))
, fMode(mode) {
for (const auto& geo : fGeos) {
- geo->addInvalReceiver(this);
+ this->observeInval(geo);
}
}
Merge::~Merge() {
for (const auto& geo : fGeos) {
- geo->removeInvalReceiver(this);
+ this->unobserveInval(geo);
}
}
diff --git a/experimental/sksg/geometry/SkSGTrimEffect.cpp b/experimental/sksg/geometry/SkSGTrimEffect.cpp
index 4ee85c8..f311822 100644
--- a/experimental/sksg/geometry/SkSGTrimEffect.cpp
+++ b/experimental/sksg/geometry/SkSGTrimEffect.cpp
@@ -15,11 +15,11 @@
TrimEffect::TrimEffect(sk_sp<GeometryNode> child)
: fChild(std::move(child)) {
- fChild->addInvalReceiver(this);
+ this->observeInval(fChild);
}
TrimEffect::~TrimEffect() {
- fChild->removeInvalReceiver(this);
+ this->unobserveInval(fChild);
}
// TODO