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

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: s/setSelfNeedsRepaint/setNeedsRepaint/ 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 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698