1 /* 2 * Copyright 2017 Google Inc. 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 #ifndef SkSGNode_DEFINED 9 #define SkSGNode_DEFINED 10 11 #include "SkRect.h" 12 #include "SkRefCnt.h" 13 #include "SkTDArray.h" 14 15 class SkCanvas; 16 class SkMatrix; 17 18 namespace sksg { 19 20 class InvalidationController; 21 22 /** 23 * Base class for all scene graph nodes. 24 * 25 * Handles ingress edge management for the DAG (i.e. node -> "parent" node mapping), 26 * and invalidation. 27 * 28 * Note: egress edges are only implemented/supported in container subclasses 29 * (e.g. Group, Effect, Draw). 30 */ 31 class Node : public SkRefCnt { 32 public: 33 // Traverse the DAG and revalidate any dependant/invalidated nodes. 34 // Returns the bounding box for the DAG fragment. 35 const SkRect& revalidate(InvalidationController*, const SkMatrix&); 36 37 protected: 38 enum InvalTraits { 39 // Nodes with this trait never generate direct damage -- instead, 40 // the damage bubbles up to ancestors. 41 kBubbleDamage_Trait = 1 << 0, 42 }; 43 44 explicit Node(uint32_t invalTraits); 45 ~Node() override; 46 47 const SkRect& bounds() const { 48 SkASSERT(!this->hasInval()); 49 return fBounds; 50 } 51 52 // Tag this node for invalidation and optional damage. 53 void invalidate(bool damage = true); 54 bool hasInval() const { return fFlags & kInvalidated_Flag; } 55 56 // Dispatched on revalidation. Subclasses are expected to recompute/cache their properties 57 // and return their bounding box in local coordinates. 58 virtual SkRect onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0; 59 60 // Register/unregister |this| to receive invalidation events from a descendant. 61 void observeInval(const sk_sp<Node>&); 62 void unobserveInval(const sk_sp<Node>&); 63 64 private: 65 enum Flags { 66 kInvalidated_Flag = 1 << 0, // the node or its descendants require revalidation 67 kDamage_Flag = 1 << 1, // the node contributes damage during revalidation 68 kObserverArray_Flag = 1 << 2, // the node has more than one inval observer 69 kInTraversal_Flag = 1 << 3, // the node is part of a traversal (cycle detection) 70 }; 71 72 template <typename Func> 73 void forEachInvalObserver(Func&&) const; 74 75 class ScopedFlag; 76 77 union { 78 Node* fInvalObserver; 79 SkTDArray<Node*>* fInvalObserverArray; 80 }; 81 SkRect fBounds; 82 const uint32_t fInvalTraits : 16; 83 uint32_t fFlags : 16; 84 85 typedef SkRefCnt INHERITED; 86 }; 87 88 // Helper for defining attribute getters/setters in subclasses. 89 #define SG_ATTRIBUTE(attr_name, attr_type, attr_container) \ 90 const attr_type& get##attr_name() const { return attr_container; } \ 91 void set##attr_name(const attr_type& v) { \ 92 if (attr_container == v) return; \ 93 attr_container = v; \ 94 this->invalidate(); \ 95 } 96 97 } // namespace sksg 98 99 #endif // SkSGNode_DEFINED 100