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