Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Namespaces | Macros
SkSGNode.cpp File Reference
#include "modules/sksg/include/SkSGNode.h"
#include "include/private/base/SkDebug.h"
#include "modules/sksg/include/SkSGInvalidationController.h"
#include "src/core/SkRectPriv.h"
#include <algorithm>

Go to the source code of this file.

Classes

class  sksg::Node::ScopedFlag
 

Namespaces

namespace  sksg
 

Macros

#define TRAVERSAL_GUARD
 

Macro Definition Documentation

◆ TRAVERSAL_GUARD

#define TRAVERSAL_GUARD
Value:
ScopedFlag traversal_guard(this, kInTraversal_Flag); \
if (traversal_guard.wasSet()) \
return

Definition at line 40 of file SkSGNode.cpp.

45 : fInvalObserver(nullptr)
47 , fInvalTraits(invalTraits)
48 , fFlags(kInvalidated_Flag)
49 , fNodeFlags(0) {}
50
51Node::~Node() {
52 if (fFlags & kObserverArray_Flag) {
53 SkASSERT(fInvalObserverArray->empty());
54 delete fInvalObserverArray;
55 } else {
56 SkASSERT(!fInvalObserver);
57 }
58}
59
60void Node::observeInval(const sk_sp<Node>& node) {
61 SkASSERT(node);
62 if (!(node->fFlags & kObserverArray_Flag)) {
63 if (!node->fInvalObserver) {
64 node->fInvalObserver = this;
65 return;
66 }
67
68 auto observers = new std::vector<Node*>();
69 observers->reserve(2);
70 observers->push_back(node->fInvalObserver);
71
72 node->fInvalObserverArray = observers;
73 node->fFlags |= kObserverArray_Flag;
74 }
75
76 // No duplicate observers.
77 SkASSERT(std::find(node->fInvalObserverArray->begin(),
78 node->fInvalObserverArray->end(), this) == node->fInvalObserverArray->end());
79
80 node->fInvalObserverArray->push_back(this);
81}
82
83void Node::unobserveInval(const sk_sp<Node>& node) {
84 SkASSERT(node);
85 if (!(node->fFlags & kObserverArray_Flag)) {
86 SkASSERT(node->fInvalObserver == this);
87 node->fInvalObserver = nullptr;
88 return;
89 }
90
91 SkDEBUGCODE(const auto origSize = node->fInvalObserverArray->size());
92 node->fInvalObserverArray->erase(std::remove(node->fInvalObserverArray->begin(),
93 node->fInvalObserverArray->end(), this),
94 node->fInvalObserverArray->end());
95 SkASSERT(node->fInvalObserverArray->size() == origSize - 1);
96}
97
98template <typename Func>
99void Node::forEachInvalObserver(Func&& func) const {
100 if (fFlags & kObserverArray_Flag) {
101 for (const auto& parent : *fInvalObserverArray) {
102 func(parent);
103 }
104 return;
105 }
106
107 if (fInvalObserver) {
108 func(fInvalObserver);
109 }
110}
111
112void Node::invalidate(bool damageBubbling) {
114
115 if (this->hasInval() && (!damageBubbling || (fFlags & kDamage_Flag))) {
116 // All done.
117 return;
118 }
119
120 if (damageBubbling && !(fInvalTraits & kBubbleDamage_Trait)) {
121 // Found a damage observer.
122 fFlags |= kDamage_Flag;
123 damageBubbling = false;
124 }
125
126 fFlags |= kInvalidated_Flag;
127
128 forEachInvalObserver([&](Node* observer) {
129 observer->invalidate(damageBubbling);
130 });
131}
132
133const SkRect& Node::revalidate(InvalidationController* ic, const SkMatrix& ctm) {
135
136 if (!this->hasInval()) {
137 return fBounds;
138 }
139
140 const auto generate_damage =
141 ic && ((fFlags & kDamage_Flag) || (fInvalTraits & kOverrideDamage_Trait));
142 if (!generate_damage) {
143 // Trivial transitive revalidation.
144 fBounds = this->onRevalidate(ic, ctm);
145 } else {
146 // Revalidate and emit damage for old-bounds, new-bounds.
147 const auto prev_bounds = fBounds;
148
149 auto* ic_override = (fInvalTraits & kOverrideDamage_Trait) ? nullptr : ic;
150 fBounds = this->onRevalidate(ic_override, ctm);
151
152 ic->inval(prev_bounds, ctm);
153 if (fBounds != prev_bounds) {
154 ic->inval(fBounds, ctm);
155 }
156 }
157
158 fFlags &= ~(kInvalidated_Flag | kDamage_Flag);
159
160 return fBounds;
161}
162
163} // namespace sksg
const SkRect fBounds
uint16_t fFlags
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
#define TRAVERSAL_GUARD
Definition SkSGNode.cpp:40
static SkRect MakeLargeS32()
Definition SkRectPriv.h:33
Definition dart.idl:29