OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/css/invalidation/StyleInvalidator.h" | 5 #include "core/css/invalidation/StyleInvalidator.h" |
6 | 6 |
7 #include "core/css/invalidation/InvalidationSet.h" | 7 #include "core/css/invalidation/InvalidationSet.h" |
8 #include "core/dom/Document.h" | 8 #include "core/dom/Document.h" |
9 #include "core/dom/Element.h" | 9 #include "core/dom/Element.h" |
10 #include "core/dom/ElementTraversal.h" | 10 #include "core/dom/ElementTraversal.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 for (auto& invalidationSet : invalidationLists.descendants) { | 82 for (auto& invalidationSet : invalidationLists.descendants) { |
83 ASSERT(!invalidationSet->wholeSubtreeInvalid()); | 83 ASSERT(!invalidationSet->wholeSubtreeInvalid()); |
84 if (invalidationSet->isEmpty()) | 84 if (invalidationSet->isEmpty()) |
85 continue; | 85 continue; |
86 if (pendingInvalidations.descendants().contains(invalidationSet)) | 86 if (pendingInvalidations.descendants().contains(invalidationSet)) |
87 continue; | 87 continue; |
88 pendingInvalidations.descendants().append(invalidationSet); | 88 pendingInvalidations.descendants().append(invalidationSet); |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 void StyleInvalidator::clearInvalidation(Element& element) | 92 void StyleInvalidator::scheduleSiblingInvalidationsAsDescendants(const Invalidat
ionLists& invalidationLists, ContainerNode& schedulingParent) |
93 { | 93 { |
94 if (!element.needsStyleInvalidation()) | 94 if (invalidationLists.siblings.isEmpty()) |
95 return; | 95 return; |
96 m_pendingInvalidationMap.remove(&element); | 96 |
97 element.clearNeedsStyleInvalidation(); | 97 PendingInvalidations& pendingInvalidations = ensurePendingInvalidations(sche
dulingParent); |
| 98 |
| 99 for (auto& invalidationSet : invalidationLists.siblings) { |
| 100 if (invalidationSet->invalidatesSelf() && !pendingInvalidations.descenda
nts().contains(invalidationSet)) |
| 101 pendingInvalidations.descendants().append(invalidationSet); |
| 102 |
| 103 if (DescendantInvalidationSet* descendants = toSiblingInvalidationSet(*i
nvalidationSet).siblingDescendants()) { |
| 104 if (!pendingInvalidations.descendants().contains(descendants)) |
| 105 pendingInvalidations.descendants().append(descendants); |
| 106 } |
| 107 } |
| 108 schedulingParent.setNeedsStyleInvalidation(); |
98 } | 109 } |
99 | 110 |
100 PendingInvalidations& StyleInvalidator::ensurePendingInvalidations(Element& elem
ent) | 111 void StyleInvalidator::clearInvalidation(ContainerNode& node) |
101 { | 112 { |
102 PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(&
element, nullptr); | 113 if (!node.needsStyleInvalidation()) |
| 114 return; |
| 115 m_pendingInvalidationMap.remove(&node); |
| 116 node.clearNeedsStyleInvalidation(); |
| 117 } |
| 118 |
| 119 PendingInvalidations& StyleInvalidator::ensurePendingInvalidations(ContainerNode
& node) |
| 120 { |
| 121 PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(&
node, nullptr); |
103 if (addResult.isNewEntry) | 122 if (addResult.isNewEntry) |
104 addResult.storedValue->value = wrapUnique(new PendingInvalidations()); | 123 addResult.storedValue->value = wrapUnique(new PendingInvalidations()); |
105 return *addResult.storedValue->value; | 124 return *addResult.storedValue->value; |
106 } | 125 } |
107 | 126 |
108 StyleInvalidator::StyleInvalidator() | 127 StyleInvalidator::StyleInvalidator() |
109 { | 128 { |
110 s_tracingEnabled = TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(TRACE_DISABLED
_BY_DEFAULT("devtools.timeline.invalidationTracking")); | 129 s_tracingEnabled = TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(TRACE_DISABLED
_BY_DEFAULT("devtools.timeline.invalidationTracking")); |
111 InvalidationSet::cacheTracingFlag(); | 130 InvalidationSet::cacheTracingFlag(); |
112 } | 131 } |
113 | 132 |
114 StyleInvalidator::~StyleInvalidator() | 133 StyleInvalidator::~StyleInvalidator() |
115 { | 134 { |
116 } | 135 } |
117 | 136 |
118 void StyleInvalidator::RecursionData::pushInvalidationSet(const DescendantInvali
dationSet& invalidationSet) | 137 void StyleInvalidator::RecursionData::pushInvalidationSet(const InvalidationSet&
invalidationSet) |
119 { | 138 { |
120 ASSERT(!m_wholeSubtreeInvalid); | 139 ASSERT(!m_wholeSubtreeInvalid); |
121 ASSERT(!invalidationSet.wholeSubtreeInvalid()); | 140 ASSERT(!invalidationSet.wholeSubtreeInvalid()); |
122 ASSERT(!invalidationSet.isEmpty()); | 141 ASSERT(!invalidationSet.isEmpty()); |
123 if (invalidationSet.treeBoundaryCrossing()) | 142 if (invalidationSet.treeBoundaryCrossing()) |
124 m_treeBoundaryCrossing = true; | 143 m_treeBoundaryCrossing = true; |
125 if (invalidationSet.insertionPointCrossing()) | 144 if (invalidationSet.insertionPointCrossing()) |
126 m_insertionPointCrossing = true; | 145 m_insertionPointCrossing = true; |
127 if (invalidationSet.invalidatesSlotted()) | 146 if (invalidationSet.invalidatesSlotted()) |
128 m_invalidatesSlotted = true; | 147 m_invalidatesSlotted = true; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 } | 219 } |
201 | 220 |
202 if (!descendants->isEmpty()) | 221 if (!descendants->isEmpty()) |
203 recursionData.pushInvalidationSet(*descendants); | 222 recursionData.pushInvalidationSet(*descendants); |
204 } | 223 } |
205 | 224 |
206 } | 225 } |
207 return thisElementNeedsStyleRecalc; | 226 return thisElementNeedsStyleRecalc; |
208 } | 227 } |
209 | 228 |
210 void StyleInvalidator::pushInvalidationSetsForElement(Element& element, Recursio
nData& recursionData, SiblingData& siblingData) | 229 void StyleInvalidator::pushInvalidationSetsForContainerNode(ContainerNode& node,
RecursionData& recursionData, SiblingData& siblingData) |
211 { | 230 { |
212 PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&e
lement); | 231 PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&n
ode); |
213 ASSERT(pendingInvalidations); | 232 ASSERT(pendingInvalidations); |
214 | 233 |
215 for (const auto& invalidationSet : pendingInvalidations->siblings()) | 234 for (const auto& invalidationSet : pendingInvalidations->siblings()) |
216 siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSe
t)); | 235 siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSe
t)); |
217 | 236 |
218 if (element.getStyleChangeType() >= SubtreeStyleChange) | 237 if (node.getStyleChangeType() >= SubtreeStyleChange) |
219 return; | 238 return; |
220 | 239 |
221 if (!pendingInvalidations->descendants().isEmpty()) { | 240 if (!pendingInvalidations->descendants().isEmpty()) { |
222 for (const auto& invalidationSet : pendingInvalidations->descendants()) | 241 for (const auto& invalidationSet : pendingInvalidations->descendants()) |
223 recursionData.pushInvalidationSet(toDescendantInvalidationSet(*inval
idationSet)); | 242 recursionData.pushInvalidationSet(*invalidationSet); |
224 if (UNLIKELY(*s_tracingEnabled)) { | 243 if (UNLIKELY(*s_tracingEnabled)) { |
225 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.in
validationTracking"), | 244 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.in
validationTracking"), |
226 "StyleInvalidatorInvalidationTracking", | 245 "StyleInvalidatorInvalidationTracking", |
227 TRACE_EVENT_SCOPE_THREAD, | 246 TRACE_EVENT_SCOPE_THREAD, |
228 "data", InspectorStyleInvalidatorInvalidateEvent::invalidationLi
st(element, pendingInvalidations->descendants())); | 247 "data", InspectorStyleInvalidatorInvalidateEvent::invalidationLi
st(node, pendingInvalidations->descendants())); |
229 } | 248 } |
230 } | 249 } |
231 } | 250 } |
232 | 251 |
233 ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element
& element, RecursionData& recursionData, SiblingData& siblingData) | 252 ALWAYS_INLINE bool StyleInvalidator::checkInvalidationSetsAgainstElement(Element
& element, RecursionData& recursionData, SiblingData& siblingData) |
234 { | 253 { |
235 if (recursionData.wholeSubtreeInvalid()) | 254 if (recursionData.wholeSubtreeInvalid()) |
236 return false; | 255 return false; |
237 | 256 |
238 bool thisElementNeedsStyleRecalc = false; | 257 bool thisElementNeedsStyleRecalc = false; |
239 if (element.getStyleChangeType() >= SubtreeStyleChange) { | 258 if (element.getStyleChangeType() >= SubtreeStyleChange) { |
240 recursionData.setWholeSubtreeInvalid(); | 259 recursionData.setWholeSubtreeInvalid(); |
241 } else { | 260 } else { |
242 thisElementNeedsStyleRecalc = recursionData.matchesCurrentInvalidationSe
ts(element); | 261 thisElementNeedsStyleRecalc = recursionData.matchesCurrentInvalidationSe
ts(element); |
243 if (UNLIKELY(!siblingData.isEmpty())) | 262 if (UNLIKELY(!siblingData.isEmpty())) |
244 thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationS
ets(element, recursionData); | 263 thisElementNeedsStyleRecalc |= siblingData.matchCurrentInvalidationS
ets(element, recursionData); |
245 } | 264 } |
246 | 265 |
247 if (UNLIKELY(element.needsStyleInvalidation())) | 266 if (UNLIKELY(element.needsStyleInvalidation())) |
248 pushInvalidationSetsForElement(element, recursionData, siblingData); | 267 pushInvalidationSetsForContainerNode(element, recursionData, siblingData
); |
249 | 268 |
250 return thisElementNeedsStyleRecalc; | 269 return thisElementNeedsStyleRecalc; |
251 } | 270 } |
252 | 271 |
253 bool StyleInvalidator::invalidateShadowRootChildren(Element& element, RecursionD
ata& recursionData) | 272 bool StyleInvalidator::invalidateShadowRootChildren(Element& element, RecursionD
ata& recursionData) |
254 { | 273 { |
255 bool someChildrenNeedStyleRecalc = false; | 274 bool someChildrenNeedStyleRecalc = false; |
256 for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->old
erShadowRoot()) { | 275 for (ShadowRoot* root = element.youngestShadowRoot(); root; root = root->old
erShadowRoot()) { |
257 if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInval
idation() && !root->needsStyleInvalidation()) | 276 if (!recursionData.treeBoundaryCrossing() && !root->childNeedsStyleInval
idation() && !root->needsStyleInvalidation()) |
258 continue; | 277 continue; |
| 278 RecursionCheckpoint checkpoint(&recursionData); |
259 SiblingData siblingData; | 279 SiblingData siblingData; |
| 280 if (UNLIKELY(root->needsStyleInvalidation())) |
| 281 pushInvalidationSetsForContainerNode(*root, recursionData, siblingDa
ta); |
260 for (Element* child = ElementTraversal::firstChild(*root); child; child
= ElementTraversal::nextSibling(*child)) { | 282 for (Element* child = ElementTraversal::firstChild(*root); child; child
= ElementTraversal::nextSibling(*child)) { |
261 bool childRecalced = invalidate(*child, recursionData, siblingData); | 283 bool childRecalced = invalidate(*child, recursionData, siblingData); |
262 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRe
calced; | 284 someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRe
calced; |
263 } | 285 } |
264 root->clearChildNeedsStyleInvalidation(); | 286 root->clearChildNeedsStyleInvalidation(); |
265 root->clearNeedsStyleInvalidation(); | 287 root->clearNeedsStyleInvalidation(); |
266 } | 288 } |
267 return someChildrenNeedStyleRecalc; | 289 return someChildrenNeedStyleRecalc; |
268 } | 290 } |
269 | 291 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 distributedNode->setNeedsStyleRecalc(LocalStyleChange, StyleChangeRe
asonForTracing::create(StyleChangeReason::StyleInvalidator)); | 350 distributedNode->setNeedsStyleRecalc(LocalStyleChange, StyleChangeRe
asonForTracing::create(StyleChangeReason::StyleInvalidator)); |
329 } | 351 } |
330 } | 352 } |
331 | 353 |
332 DEFINE_TRACE(StyleInvalidator) | 354 DEFINE_TRACE(StyleInvalidator) |
333 { | 355 { |
334 visitor->trace(m_pendingInvalidationMap); | 356 visitor->trace(m_pendingInvalidationMap); |
335 } | 357 } |
336 | 358 |
337 } // namespace blink | 359 } // namespace blink |
OLD | NEW |