Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(391)

Side by Side Diff: Source/platform/graphics/paint/DisplayItemList.cpp

Issue 1294233004: Subtree caching implementation in blink-core (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Add a complex-subtree-update test Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698