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 {
57 }
58}
59
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
77 SkASSERT(std::find(node->fInvalObserverArray->begin(),
78 node->fInvalObserverArray->end(), this) == node->fInvalObserverArray->end());
79
80 node->fInvalObserverArray->push_back(this);
81}
82
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
117 return;
118 }
119
120 if (damageBubbling && !(fInvalTraits & kBubbleDamage_Trait)) {
121
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()) {
138 }
139
140 const auto generate_damage =
141 ic && ((
fFlags & kDamage_Flag) || (fInvalTraits & kOverrideDamage_Trait));
142 if (!generate_damage) {
143
144 fBounds = this->onRevalidate(ic, ctm);
145 } else {
146
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);
155 }
156 }
157
158 fFlags &= ~(kInvalidated_Flag | kDamage_Flag);
159
161}
162
163}
static SkRect MakeLargeS32()