xref: /aosp_15_r20/external/skia/modules/sksg/include/SkSGNode.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2017 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef SkSGNode_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define SkSGNode_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
16*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker class SkMatrix;
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker namespace sksg {
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker class InvalidationController;
23*c8dee2aaSAndroid Build Coastguard Worker 
24*c8dee2aaSAndroid Build Coastguard Worker /**
25*c8dee2aaSAndroid Build Coastguard Worker  * Base class for all scene graph nodes.
26*c8dee2aaSAndroid Build Coastguard Worker  *
27*c8dee2aaSAndroid Build Coastguard Worker  * Handles ingress edge management for the DAG (i.e. node -> "parent" node mapping),
28*c8dee2aaSAndroid Build Coastguard Worker  * and invalidation.
29*c8dee2aaSAndroid Build Coastguard Worker  *
30*c8dee2aaSAndroid Build Coastguard Worker  * Note: egress edges are only implemented/supported in container subclasses
31*c8dee2aaSAndroid Build Coastguard Worker  * (e.g. Group, Effect, Draw).
32*c8dee2aaSAndroid Build Coastguard Worker  */
33*c8dee2aaSAndroid Build Coastguard Worker class Node : public SkRefCnt {
34*c8dee2aaSAndroid Build Coastguard Worker public:
35*c8dee2aaSAndroid Build Coastguard Worker     // Traverse the DAG and revalidate any dependant/invalidated nodes.
36*c8dee2aaSAndroid Build Coastguard Worker     // Returns the bounding box for the DAG fragment.
37*c8dee2aaSAndroid Build Coastguard Worker     const SkRect& revalidate(InvalidationController*, const SkMatrix&);
38*c8dee2aaSAndroid Build Coastguard Worker 
39*c8dee2aaSAndroid Build Coastguard Worker     // Tag this node for invalidation and optional damage.
40*c8dee2aaSAndroid Build Coastguard Worker     void invalidate(bool damage = true);
41*c8dee2aaSAndroid Build Coastguard Worker 
42*c8dee2aaSAndroid Build Coastguard Worker protected:
43*c8dee2aaSAndroid Build Coastguard Worker     enum InvalTraits {
44*c8dee2aaSAndroid Build Coastguard Worker         // Nodes with this trait never generate direct damage -- instead,
45*c8dee2aaSAndroid Build Coastguard Worker         // the damage bubbles up to ancestors.
46*c8dee2aaSAndroid Build Coastguard Worker         kBubbleDamage_Trait   = 1 << 0,
47*c8dee2aaSAndroid Build Coastguard Worker 
48*c8dee2aaSAndroid Build Coastguard Worker         // Nodes with this trait obscure the descendants' damage and always override it.
49*c8dee2aaSAndroid Build Coastguard Worker         kOverrideDamage_Trait = 1 << 1,
50*c8dee2aaSAndroid Build Coastguard Worker     };
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker     explicit Node(uint32_t invalTraits);
53*c8dee2aaSAndroid Build Coastguard Worker     ~Node() override;
54*c8dee2aaSAndroid Build Coastguard Worker 
bounds()55*c8dee2aaSAndroid Build Coastguard Worker     const SkRect& bounds() const {
56*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->hasInval());
57*c8dee2aaSAndroid Build Coastguard Worker         return fBounds;
58*c8dee2aaSAndroid Build Coastguard Worker     }
59*c8dee2aaSAndroid Build Coastguard Worker 
hasInval()60*c8dee2aaSAndroid Build Coastguard Worker     bool hasInval() const { return fFlags & kInvalidated_Flag; }
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker     // Dispatched on revalidation.  Subclasses are expected to recompute/cache their properties
63*c8dee2aaSAndroid Build Coastguard Worker     // and return their bounding box in local coordinates.
64*c8dee2aaSAndroid Build Coastguard Worker     virtual SkRect onRevalidate(InvalidationController*, const SkMatrix& ctm) = 0;
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker     // Register/unregister |this| to receive invalidation events from a descendant.
67*c8dee2aaSAndroid Build Coastguard Worker     void observeInval(const sk_sp<Node>&);
68*c8dee2aaSAndroid Build Coastguard Worker     void unobserveInval(const sk_sp<Node>&);
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker private:
71*c8dee2aaSAndroid Build Coastguard Worker     enum Flags {
72*c8dee2aaSAndroid Build Coastguard Worker         kInvalidated_Flag   = 1 << 0, // the node or its descendants require revalidation
73*c8dee2aaSAndroid Build Coastguard Worker         kDamage_Flag        = 1 << 1, // the node contributes damage during revalidation
74*c8dee2aaSAndroid Build Coastguard Worker         kObserverArray_Flag = 1 << 2, // the node has more than one inval observer
75*c8dee2aaSAndroid Build Coastguard Worker         kInTraversal_Flag   = 1 << 3, // the node is part of a traversal (cycle detection)
76*c8dee2aaSAndroid Build Coastguard Worker     };
77*c8dee2aaSAndroid Build Coastguard Worker 
78*c8dee2aaSAndroid Build Coastguard Worker     template <typename Func>
79*c8dee2aaSAndroid Build Coastguard Worker     void forEachInvalObserver(Func&&) const;
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker     class ScopedFlag;
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker     union {
84*c8dee2aaSAndroid Build Coastguard Worker         Node*               fInvalObserver;
85*c8dee2aaSAndroid Build Coastguard Worker         std::vector<Node*>* fInvalObserverArray;
86*c8dee2aaSAndroid Build Coastguard Worker     };
87*c8dee2aaSAndroid Build Coastguard Worker     SkRect                  fBounds;
88*c8dee2aaSAndroid Build Coastguard Worker     const uint32_t          fInvalTraits :  2;
89*c8dee2aaSAndroid Build Coastguard Worker     uint32_t                fFlags       :  4; // Internal flags.
90*c8dee2aaSAndroid Build Coastguard Worker     uint32_t                fNodeFlags   :  8; // Accessible from select subclasses.
91*c8dee2aaSAndroid Build Coastguard Worker     // Free bits                         : 18;
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker     friend class NodePriv;
94*c8dee2aaSAndroid Build Coastguard Worker     friend class RenderNode; // node flags access
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = SkRefCnt;
97*c8dee2aaSAndroid Build Coastguard Worker };
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker // Helper for defining attribute getters/setters in subclasses.
100*c8dee2aaSAndroid Build Coastguard Worker #define SG_ATTRIBUTE(attr_name, attr_type, attr_container)             \
101*c8dee2aaSAndroid Build Coastguard Worker     const attr_type& get##attr_name() const { return attr_container; } \
102*c8dee2aaSAndroid Build Coastguard Worker     void set##attr_name(const attr_type& v) {                          \
103*c8dee2aaSAndroid Build Coastguard Worker         if (attr_container == v) return;                               \
104*c8dee2aaSAndroid Build Coastguard Worker         attr_container = v;                                            \
105*c8dee2aaSAndroid Build Coastguard Worker         this->invalidate();                                            \
106*c8dee2aaSAndroid Build Coastguard Worker     }                                                                  \
107*c8dee2aaSAndroid Build Coastguard Worker     void set##attr_name(attr_type&& v) {                               \
108*c8dee2aaSAndroid Build Coastguard Worker         if (attr_container == v) return;                               \
109*c8dee2aaSAndroid Build Coastguard Worker         attr_container = std::move(v);                                 \
110*c8dee2aaSAndroid Build Coastguard Worker         this->invalidate();                                            \
111*c8dee2aaSAndroid Build Coastguard Worker     }
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker #define SG_MAPPED_ATTRIBUTE(attr_name, attr_type, attr_container)                \
114*c8dee2aaSAndroid Build Coastguard Worker     attr_type get##attr_name() const { return attr_container.get##attr_name(); } \
115*c8dee2aaSAndroid Build Coastguard Worker     void set##attr_name(const attr_type& v) {                                    \
116*c8dee2aaSAndroid Build Coastguard Worker         if (attr_container.get##attr_name() == v) return;                        \
117*c8dee2aaSAndroid Build Coastguard Worker         attr_container.set##attr_name(v);                                        \
118*c8dee2aaSAndroid Build Coastguard Worker         this->invalidate();                                                      \
119*c8dee2aaSAndroid Build Coastguard Worker     }                                                                            \
120*c8dee2aaSAndroid Build Coastguard Worker     void set##attr_name(attr_type&& v) {                                         \
121*c8dee2aaSAndroid Build Coastguard Worker         if (attr_container.get##attr_name() == v) return;                        \
122*c8dee2aaSAndroid Build Coastguard Worker         attr_container.set##attr_name(std::move(v));                             \
123*c8dee2aaSAndroid Build Coastguard Worker         this->invalidate();                                                      \
124*c8dee2aaSAndroid Build Coastguard Worker     }
125*c8dee2aaSAndroid Build Coastguard Worker 
126*c8dee2aaSAndroid Build Coastguard Worker } // namespace sksg
127*c8dee2aaSAndroid Build Coastguard Worker 
128*c8dee2aaSAndroid Build Coastguard Worker #endif // SkSGNode_DEFINED
129