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 "config.h" | 5 #include "config.h" |
6 #include "platform/graphics/paint/DisplayItemList.h" | 6 #include "platform/graphics/paint/DisplayItemList.h" |
7 | 7 |
8 #include "platform/NotImplemented.h" | 8 #include "platform/NotImplemented.h" |
9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
10 #include "platform/TraceEvent.h" | 10 #include "platform/TraceEvent.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 #if ENABLE(ASSERT) | 84 #if ENABLE(ASSERT) |
85 size_t index = findMatchingItemFromIndex(displayItem->nonCachedId(), m_newDi
splayItemIndicesByClient, m_newDisplayItems); | 85 size_t index = findMatchingItemFromIndex(displayItem->nonCachedId(), m_newDi
splayItemIndicesByClient, m_newDisplayItems); |
86 if (index != kNotFound) { | 86 if (index != kNotFound) { |
87 #ifndef NDEBUG | 87 #ifndef NDEBUG |
88 showDebugData(); | 88 showDebugData(); |
89 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 89 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
90 displayItem->asDebugString().utf8().data(), m_newDisplayItems[index]
.asDebugString().utf8().data(), static_cast<int>(index)); | 90 displayItem->asDebugString().utf8().data(), m_newDisplayItems[index]
.asDebugString().utf8().data(), static_cast<int>(index)); |
91 #endif | 91 #endif |
92 ASSERT_NOT_REACHED(); | 92 ASSERT_NOT_REACHED(); |
93 } | 93 } |
94 addItemToIndexIfNeeded(*displayItem, m_newDisplayItems.size() - 1, m_newDisp
layItemIndicesByClient); | 94 // TODO: Do we need to check duplicated ids for other types? |
| 95 if (displayItem->isCached() || displayItem->isCacheable()) |
| 96 addItemToIndex(*displayItem, m_newDisplayItems.size() - 1, m_newDisplayI
temIndicesByClient); |
95 #endif // ENABLE(ASSERT) | 97 #endif // ENABLE(ASSERT) |
96 | 98 |
97 ASSERT(!displayItem->skippedCache()); // Only DisplayItemList can set the fl
ag. | 99 ASSERT(!displayItem->skippedCache()); // Only DisplayItemList can set the fl
ag. |
98 if (skippingCache()) | 100 if (skippingCache()) |
99 displayItem->setSkippedCache(); | 101 displayItem->setSkippedCache(); |
100 } | 102 } |
101 | 103 |
102 void DisplayItemList::beginScope() | 104 void DisplayItemList::beginScope() |
103 { | 105 { |
104 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); | 106 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); |
105 m_scopeStack.append(m_nextScope++); | 107 m_scopeStack.append(m_nextScope++); |
106 beginSkippingCache(); | 108 beginSkippingCache(); |
107 } | 109 } |
108 | 110 |
109 void DisplayItemList::endScope() | 111 void DisplayItemList::endScope() |
110 { | 112 { |
111 m_scopeStack.removeLast(); | 113 m_scopeStack.removeLast(); |
112 endSkippingCache(); | 114 endSkippingCache(); |
113 } | 115 } |
114 | 116 |
115 void DisplayItemList::invalidate(DisplayItemClient client) | 117 void DisplayItemList::invalidate(DisplayItemClient client) |
116 { | 118 { |
117 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 119 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
118 // Can only be called during layout/paintInvalidation, not during painting. | 120 // Can only be called during layout/paintInvalidation, not during painting. |
119 ASSERT(m_newDisplayItems.isEmpty()); | 121 ASSERT(m_newDisplayItems.isEmpty()); |
120 updateValidlyCachedClientsIfNeeded(); | 122 updateValidlyCachedClientsIfNeeded(); |
121 m_validlyCachedClients.remove(client); | 123 m_validlyCachedClients.remove(client); |
| 124 updateSubtreeIndicesByClientIfNeeded(); |
| 125 m_subtreeIndicesByClient.remove(client); |
122 } | 126 } |
123 | 127 |
124 void DisplayItemList::invalidateAll() | 128 void DisplayItemList::invalidateAll() |
125 { | 129 { |
126 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 130 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
127 // Can only be called during layout/paintInvalidation, not during painting. | 131 // Can only be called during layout/paintInvalidation, not during painting. |
128 ASSERT(m_newDisplayItems.isEmpty()); | 132 ASSERT(m_newDisplayItems.isEmpty()); |
129 m_currentDisplayItems.clear(); | 133 m_currentDisplayItems.clear(); |
130 m_validlyCachedClients.clear(); | 134 m_validlyCachedClients.clear(); |
131 m_validlyCachedClientsDirty = false; | 135 m_validlyCachedClientsDirty = false; |
| 136 m_subtreeIndicesByClient.clear(); |
| 137 m_subtreeIndicesByClientDirty = false; |
132 } | 138 } |
133 | 139 |
134 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const | 140 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const |
135 { | 141 { |
136 if (skippingCache()) | 142 if (skippingCache()) |
137 return false; | 143 return false; |
138 updateValidlyCachedClientsIfNeeded(); | 144 updateValidlyCachedClientsIfNeeded(); |
139 return m_validlyCachedClients.contains(client); | 145 return m_validlyCachedClients.contains(client); |
140 } | 146 } |
141 | 147 |
| 148 bool DisplayItemList::subtreeCacheIsValid(DisplayItemClient client, DisplayItem:
:Type beginSubtreeType) const |
| 149 { |
| 150 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
| 151 ASSERT(DisplayItem::isBeginSubtreeType(beginSubtreeType)); |
| 152 if (skippingCache()) |
| 153 return false; |
| 154 updateSubtreeIndicesByClientIfNeeded(); |
| 155 return findMatchingItemFromIndex(DisplayItem::Id(client, beginSubtreeType, 0
), m_subtreeIndicesByClient, m_currentDisplayItems) != kNotFound; |
| 156 } |
| 157 |
142 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con
st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems
& list) | 158 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con
st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems
& list) |
143 { | 159 { |
144 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(id.client); | 160 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien
t.find(id.client); |
145 if (it == displayItemIndicesByClient.end()) | 161 if (it == displayItemIndicesByClient.end()) |
146 return kNotFound; | 162 return kNotFound; |
147 | 163 |
148 const Vector<size_t>& indices = it->value; | 164 const Vector<size_t>& indices = it->value; |
149 for (size_t index : indices) { | 165 for (size_t index : indices) { |
150 const DisplayItem& existingItem = list[index]; | 166 const DisplayItem& existingItem = list[index]; |
151 ASSERT(!existingItem.isValid() || existingItem.client() == id.client); | 167 ASSERT(!existingItem.isValid() || existingItem.client() == id.client); |
152 if (existingItem.isValid() && id.matches(existingItem)) | 168 if (existingItem.isValid() && id.matches(existingItem)) |
153 return index; | 169 return index; |
154 } | 170 } |
155 | 171 |
156 return kNotFound; | 172 return kNotFound; |
157 } | 173 } |
158 | 174 |
159 void DisplayItemList::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz
e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient) | 175 void DisplayItemList::addItemToIndex(const DisplayItem& displayItem, size_t inde
x, DisplayItemIndicesByClientMap& displayItemIndicesByClient) |
160 { | 176 { |
161 if (!displayItem.isCacheable()) | 177 displayItemIndicesByClient.add(displayItem.client(), Vector<size_t>()).store
dValue->value.append(index); |
162 return; | |
163 | |
164 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find
(displayItem.client()); | |
165 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? | |
166 displayItemIndicesByClient.add(displayItem.client(), Vector<size_t>()).s
toredValue->value : it->value; | |
167 indices.append(index); | |
168 } | 178 } |
169 | 179 |
170 struct DisplayItemList::OutOfOrderIndexContext { | 180 struct DisplayItemList::OutOfOrderIndexContext { |
171 OutOfOrderIndexContext(DisplayItems::iterator begin) : nextItemToIndex(begin
) { } | 181 OutOfOrderIndexContext(DisplayItems::iterator begin) : nextItemToIndex(begin
) { } |
172 | 182 |
173 DisplayItems::iterator nextItemToIndex; | 183 DisplayItems::iterator nextItemToIndex; |
174 DisplayItemIndicesByClientMap displayItemIndicesByClient; | 184 DisplayItemIndicesByClientMap displayItemIndicesByClient; |
175 }; | 185 }; |
176 | 186 |
177 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::i
terator currentIt, const DisplayItem::Id& id, OutOfOrderIndexContext& context) | 187 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::i
terator currentIt, const DisplayItem::Id& id, OutOfOrderIndexContext& context) |
178 { | 188 { |
179 ASSERT(clientCacheIsValid(id.client)); | 189 ASSERT(clientCacheIsValid(id.client)); |
180 | 190 |
181 // Skip indexing of copied items. | |
182 if (currentIt - context.nextItemToIndex > 0) | |
183 context.nextItemToIndex = currentIt; | |
184 | |
185 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices
ByClient, m_currentDisplayItems); | 191 size_t foundIndex = findMatchingItemFromIndex(id, context.displayItemIndices
ByClient, m_currentDisplayItems); |
186 if (foundIndex != kNotFound) | 192 if (foundIndex != kNotFound) |
187 return m_currentDisplayItems.begin() + foundIndex; | 193 return m_currentDisplayItems.begin() + foundIndex; |
188 | 194 |
189 return findOutOfOrderCachedItemForward(id, context); | 195 // We added indices to all BeginSubtree display items into context.displayIt
emIndicesByClient |
| 196 // at the beginning of the merge algorithm, so don't need to find forward. |
| 197 if (DisplayItem::isBeginSubtreeType(id.type)) |
| 198 return m_currentDisplayItems.end(); |
| 199 |
| 200 return findOutOfOrderCachedItemForward(currentIt, id, context); |
190 } | 201 } |
191 | 202 |
192 // Find forward for the item and index all skipped indexable items. | 203 // Find forward for the item and index all skipped indexable items. |
193 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(const Di
splayItem::Id& id, OutOfOrderIndexContext& context) | 204 DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(DisplayI
tems::iterator currentIt, const DisplayItem::Id& id, OutOfOrderIndexContext& con
text) |
194 { | 205 { |
| 206 // Items before currentIt should have been copied. Skip indexing of them. |
| 207 if (currentIt - context.nextItemToIndex > 0) |
| 208 context.nextItemToIndex = currentIt; |
| 209 |
195 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 210 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); |
196 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { | 211 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { |
197 const DisplayItem& item = *context.nextItemToIndex; | 212 const DisplayItem& item = *context.nextItemToIndex; |
198 ASSERT(item.isValid()); | 213 ASSERT(item.isValid()); |
199 if (item.isCacheable() && clientCacheIsValid(item.client())) { | 214 if (item.isCacheable() && clientCacheIsValid(item.client())) { |
200 if (id.matches(item)) | 215 if (id.matches(item)) |
201 return context.nextItemToIndex++; | 216 return context.nextItemToIndex++; |
202 | 217 |
203 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentDisp
layItems.begin(), context.displayItemIndicesByClient); | 218 if (item.isDrawing() && !item.skippedCache()) |
| 219 addItemToIndex(item, context.nextItemToIndex - m_currentDisplayI
tems.begin(), context.displayItemIndicesByClient); |
204 } | 220 } |
205 } | 221 } |
206 return currentEnd; | 222 return currentEnd; |
207 } | 223 } |
208 | 224 |
209 void DisplayItemList::copyCachedSubtree(DisplayItems::iterator& currentIt, Displ
ayItems& updatedList) | 225 void DisplayItemList::copyCachedSubtree(DisplayItems::iterator& currentIt, Displ
ayItems& updatedList) |
210 { | 226 { |
211 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 227 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
212 ASSERT(currentIt->isBeginSubtree()); | 228 ASSERT(currentIt->isBeginSubtree()); |
213 ASSERT(!currentIt->scope()); | 229 ASSERT(!currentIt->scope()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 m_newDisplayItemIndicesByClient.clear(); | 262 m_newDisplayItemIndicesByClient.clear(); |
247 #endif | 263 #endif |
248 | 264 |
249 if (m_currentDisplayItems.isEmpty()) { | 265 if (m_currentDisplayItems.isEmpty()) { |
250 #if ENABLE(ASSERT) | 266 #if ENABLE(ASSERT) |
251 for (const auto& item : m_newDisplayItems) | 267 for (const auto& item : m_newDisplayItems) |
252 ASSERT(!item.isCached()); | 268 ASSERT(!item.isCached()); |
253 #endif | 269 #endif |
254 m_currentDisplayItems.swap(m_newDisplayItems); | 270 m_currentDisplayItems.swap(m_newDisplayItems); |
255 m_validlyCachedClientsDirty = true; | 271 m_validlyCachedClientsDirty = true; |
| 272 m_subtreeIndicesByClientDirty = true; |
256 m_numCachedItems = 0; | 273 m_numCachedItems = 0; |
257 return; | 274 return; |
258 } | 275 } |
259 | 276 |
260 updateValidlyCachedClientsIfNeeded(); | 277 updateValidlyCachedClientsIfNeeded(); |
261 | 278 |
262 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched | 279 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched |
263 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched | 280 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched |
264 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when | 281 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when |
265 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems | 282 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems |
266 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. | 283 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. |
267 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; | 284 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; |
| 285 outOfOrderIndexContext.displayItemIndicesByClient.swap(m_subtreeIndicesByCli
ent); |
268 | 286 |
269 #if ENABLE(ASSERT) | 287 #if ENABLE(ASSERT) |
270 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ | 288 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
{ |
271 // Under-invalidation checking requires a full index of m_currentDisplay
Items. | 289 // Under-invalidation checking requires a full index of m_currentDisplay
Items. |
272 size_t i = 0; | 290 size_t i = 0; |
273 for (const auto& item : m_currentDisplayItems) { | 291 for (const auto& item : m_currentDisplayItems) { |
274 addItemToIndexIfNeeded(item, i, outOfOrderIndexContext.displayItemIn
dicesByClient); | 292 addItemToIndex(item, i, outOfOrderIndexContext.displayItemIndicesByC
lient); |
275 ++i; | 293 ++i; |
276 } | 294 } |
277 } | 295 } |
278 #endif // ENABLE(ASSERT) | 296 #endif // ENABLE(ASSERT) |
279 | 297 |
280 // TODO(jbroman): Consider revisiting this heuristic. | 298 // TODO(jbroman): Consider revisiting this heuristic. |
281 DisplayItems updatedList( | 299 DisplayItems updatedList( |
282 kMaximumDisplayItemSize, | 300 kMaximumDisplayItemSize, |
283 std::max(m_currentDisplayItems.usedCapacityInBytes(), m_newDisplayItems.
usedCapacityInBytes())); | 301 std::max(m_currentDisplayItems.usedCapacityInBytes(), m_newDisplayItems.
usedCapacityInBytes())); |
284 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); | 302 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); |
285 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 303 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); |
286 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { | 304 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { |
287 const DisplayItem& newDisplayItem = *newIt; | 305 const DisplayItem& newDisplayItem = *newIt; |
288 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 306 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
289 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; | 307 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; |
290 | 308 |
291 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); | 309 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); |
292 | 310 |
293 if (newDisplayItemHasCachedType) { | 311 if (newDisplayItemHasCachedType) { |
294 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki
ngEnabled()); | 312 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki
ngEnabled()); |
295 ASSERT(newDisplayItem.isCached()); | 313 ASSERT(newDisplayItem.isCached()); |
296 ASSERT(clientCacheIsValid(newDisplayItem.client())); | 314 ASSERT(clientCacheIsValid(newDisplayItem.client())); |
297 if (!isSynchronized) { | 315 if (!isSynchronized) { |
298 DisplayItems::iterator foundIt = findOutOfOrderCachedItem(curren
tIt, newDisplayItemId, outOfOrderIndexContext); | 316 currentIt = findOutOfOrderCachedItem(currentIt, newDisplayItemId
, outOfOrderIndexContext); |
299 | 317 if (currentIt == currentEnd) { |
300 if (foundIt == currentEnd) { | |
301 #ifndef NDEBUG | 318 #ifndef NDEBUG |
302 showDebugData(); | 319 showDebugData(); |
303 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD
isplayItem.asDebugString().utf8().data()); | 320 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD
isplayItem.asDebugString().utf8().data()); |
304 #endif | 321 #endif |
305 ASSERT_NOT_REACHED(); | 322 ASSERT_NOT_REACHED(); |
306 | 323 // We did not find the cached display item. This should be i
mpossible, but may occur if there is a bug in |
307 // If foundIt == currentEnd, it means that we did not find t
he cached display item. This should be impossible, but may occur | 324 // the system, such as under-invalidation, incorrect cache c
hecking or duplicate display ids. In this case, |
308 // if there is a bug in the system, such as under-invalidati
on, incorrect cache checking or duplicate display ids. In this case, | |
309 // attempt to recover rather than crashing or bailing on dis
play of the rest of the display list. | 325 // attempt to recover rather than crashing or bailing on dis
play of the rest of the display list. |
310 continue; | 326 continue; |
311 } | 327 } |
312 | |
313 ASSERT(foundIt != currentIt); // because we are in 'if (!isSynch
ronized)' | |
314 currentIt = foundIt; | |
315 } | 328 } |
316 | 329 |
317 if (newDisplayItem.isCachedDrawing()) { | 330 if (newDisplayItem.isCachedDrawing()) { |
318 updatedList.appendByMoving(*currentIt, currentIt->derivedSize())
; | 331 updatedList.appendByMoving(*currentIt, currentIt->derivedSize())
; |
319 ++currentIt; | 332 ++currentIt; |
320 } else { | 333 } else { |
321 ASSERT(newDisplayItem.isCachedSubtree()); | 334 ASSERT(newDisplayItem.isCachedSubtree()); |
322 copyCachedSubtree(currentIt, updatedList); | 335 copyCachedSubtree(currentIt, updatedList); |
323 ASSERT(updatedList.last().isEndSubtree()); | 336 ASSERT(updatedList.last().isEndSubtree()); |
324 } | 337 } |
(...skipping 11 matching lines...) Expand all Loading... |
336 } | 349 } |
337 } | 350 } |
338 | 351 |
339 #if ENABLE(ASSERT) | 352 #if ENABLE(ASSERT) |
340 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 353 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
341 checkNoRemainingCachedDisplayItems(); | 354 checkNoRemainingCachedDisplayItems(); |
342 #endif // ENABLE(ASSERT) | 355 #endif // ENABLE(ASSERT) |
343 | 356 |
344 m_newDisplayItems.clear(); | 357 m_newDisplayItems.clear(); |
345 m_validlyCachedClientsDirty = true; | 358 m_validlyCachedClientsDirty = true; |
| 359 m_subtreeIndicesByClientDirty = true; |
346 m_currentDisplayItems.swap(updatedList); | 360 m_currentDisplayItems.swap(updatedList); |
347 m_numCachedItems = 0; | 361 m_numCachedItems = 0; |
348 } | 362 } |
349 | 363 |
350 size_t DisplayItemList::approximateUnsharedMemoryUsage() const | 364 size_t DisplayItemList::approximateUnsharedMemoryUsage() const |
351 { | 365 { |
352 size_t memoryUsage = sizeof(*this); | 366 size_t memoryUsage = sizeof(*this); |
353 | 367 |
354 // Memory outside this class due to m_currentDisplayItems. | 368 // Memory outside this class due to m_currentDisplayItems. |
355 memoryUsage += m_currentDisplayItems.memoryUsageInBytes(); | 369 memoryUsage += m_currentDisplayItems.memoryUsageInBytes(); |
(...skipping 27 matching lines...) Expand all Loading... |
383 DisplayItemClient lastClient = nullptr; | 397 DisplayItemClient lastClient = nullptr; |
384 for (const DisplayItem& displayItem : m_currentDisplayItems) { | 398 for (const DisplayItem& displayItem : m_currentDisplayItems) { |
385 if (displayItem.client() == lastClient) | 399 if (displayItem.client() == lastClient) |
386 continue; | 400 continue; |
387 lastClient = displayItem.client(); | 401 lastClient = displayItem.client(); |
388 if (!displayItem.skippedCache()) | 402 if (!displayItem.skippedCache()) |
389 m_validlyCachedClients.add(lastClient); | 403 m_validlyCachedClients.add(lastClient); |
390 } | 404 } |
391 } | 405 } |
392 | 406 |
| 407 void DisplayItemList::updateSubtreeIndicesByClientIfNeeded() const |
| 408 { |
| 409 if (!m_subtreeIndicesByClientDirty) |
| 410 return; |
| 411 |
| 412 m_subtreeIndicesByClient.clear(); |
| 413 m_subtreeIndicesByClientDirty = false; |
| 414 |
| 415 for (DisplayItems::const_iterator it = m_currentDisplayItems.begin(); it !=
m_currentDisplayItems.end(); ++it) { |
| 416 if (it->isBeginSubtree() && !it->skippedCache()) |
| 417 addItemToIndex(*it, it - m_currentDisplayItems.begin(), m_subtreeInd
icesByClient); |
| 418 } |
| 419 } |
| 420 |
393 void DisplayItemList::appendToWebDisplayItemList(WebDisplayItemList* list) | 421 void DisplayItemList::appendToWebDisplayItemList(WebDisplayItemList* list) |
394 { | 422 { |
395 for (const DisplayItem& item : m_currentDisplayItems) | 423 for (const DisplayItem& item : m_currentDisplayItems) |
396 item.appendToWebDisplayItemList(list); | 424 item.appendToWebDisplayItemList(list); |
397 } | 425 } |
398 | 426 |
399 void DisplayItemList::commitNewDisplayItemsAndAppendToWebDisplayItemList(WebDisp
layItemList* list) | 427 void DisplayItemList::commitNewDisplayItemsAndAppendToWebDisplayItemList(WebDisp
layItemList* list) |
400 { | 428 { |
401 commitNewDisplayItems(); | 429 commitNewDisplayItems(); |
402 appendToWebDisplayItemList(list); | 430 appendToWebDisplayItemList(list); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 | 573 |
546 void DisplayItemList::replay(GraphicsContext& context) | 574 void DisplayItemList::replay(GraphicsContext& context) |
547 { | 575 { |
548 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 576 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
549 ASSERT(m_newDisplayItems.isEmpty()); | 577 ASSERT(m_newDisplayItems.isEmpty()); |
550 for (DisplayItem& displayItem : m_currentDisplayItems) | 578 for (DisplayItem& displayItem : m_currentDisplayItems) |
551 displayItem.replay(context); | 579 displayItem.replay(context); |
552 } | 580 } |
553 | 581 |
554 } // namespace blink | 582 } // namespace blink |
OLD | NEW |