[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