• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
bounds()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);
hasInval()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