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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp

Issue 1508223005: Client side display item cache flag (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ScrollbarTheme
Patch Set: Created 4 years, 7 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
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 "platform/graphics/paint/PaintController.h" 5 #include "platform/graphics/paint/PaintController.h"
6 6
7 #include "platform/TraceEvent.h" 7 #include "platform/TraceEvent.h"
8 #include "platform/graphics/GraphicsLayer.h" 8 #include "platform/graphics/GraphicsLayer.h"
9 #include "platform/graphics/paint/DrawingDisplayItem.h" 9 #include "platform/graphics/paint/DrawingDisplayItem.h"
10 10
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 #endif 131 #endif
132 132
133 invalidateUntracked(client); 133 invalidateUntracked(client);
134 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects) 134 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects)
135 m_trackedPaintInvalidationObjects->append(client.debugName()); 135 m_trackedPaintInvalidationObjects->append(client.debugName());
136 } 136 }
137 137
138 void PaintController::invalidateUntracked(const DisplayItemClient& client) 138 void PaintController::invalidateUntracked(const DisplayItemClient& client)
139 { 139 {
140 // This can be called during painting, but we can't invalidate already paint ed clients. 140 // This can be called during painting, but we can't invalidate already paint ed clients.
141 client.setDisplayItemsUncached();
141 ASSERT(!m_newDisplayItemIndicesByClient.contains(&client)); 142 ASSERT(!m_newDisplayItemIndicesByClient.contains(&client));
142 updateValidlyCachedClientsIfNeeded();
143 m_validlyCachedClients.remove(&client);
144 } 143 }
145 144
146 void PaintController::invalidateAll() 145 void PaintController::invalidateAll()
147 { 146 {
148 // Can only be called during layout/paintInvalidation, not during painting. 147 // Can only be called during layout/paintInvalidation, not during painting.
149 ASSERT(m_newDisplayItemList.isEmpty()); 148 ASSERT(m_newDisplayItemList.isEmpty());
150 m_currentPaintArtifact.reset(); 149 m_currentPaintArtifact.reset();
151 m_validlyCachedClients.clear(); 150 m_currentCacheGeneration.invalidate();
152 m_validlyCachedClientsDirty = false;
153 151
154 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects) 152 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvali dationObjects)
155 m_trackedPaintInvalidationObjects->append("##ALL##"); 153 m_trackedPaintInvalidationObjects->append("##ALL##");
156 } 154 }
157 155
158 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const 156 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const
159 { 157 {
158 ASSERT(DisplayItemClient::isAlive(client));
160 if (skippingCache()) 159 if (skippingCache())
161 return false; 160 return false;
162 updateValidlyCachedClientsIfNeeded(); 161 return client.displayItemsAreCached(m_currentCacheGeneration);
163 return m_validlyCachedClients.contains(&client);
164 } 162 }
165 163
166 void PaintController::invalidatePaintOffset(const DisplayItemClient& client) 164 void PaintController::invalidatePaintOffset(const DisplayItemClient& client)
167 { 165 {
168 ASSERT(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); 166 ASSERT(RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled());
169 invalidate(client); 167 invalidate(client);
170 168
171 #if ENABLE(ASSERT) 169 #if ENABLE(ASSERT)
172 ASSERT(!paintOffsetWasInvalidated(client)); 170 ASSERT(!paintOffsetWasInvalidated(client));
173 m_clientsWithPaintOffsetInvalidations.add(&client); 171 m_clientsWithPaintOffsetInvalidations.add(&client);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 return findOutOfOrderCachedItemForward(id, context); 227 return findOutOfOrderCachedItemForward(id, context);
230 } 228 }
231 229
232 // Find forward for the item and index all skipped indexable items. 230 // Find forward for the item and index all skipped indexable items.
233 DisplayItemList::iterator PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& id, OutOfOrderIndexContext& context) 231 DisplayItemList::iterator PaintController::findOutOfOrderCachedItemForward(const DisplayItem::Id& id, OutOfOrderIndexContext& context)
234 { 232 {
235 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItem List().end(); 233 DisplayItemList::iterator currentEnd = m_currentPaintArtifact.getDisplayItem List().end();
236 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { 234 for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) {
237 const DisplayItem& item = *context.nextItemToIndex; 235 const DisplayItem& item = *context.nextItemToIndex;
238 ASSERT(item.hasValidClient()); 236 ASSERT(item.hasValidClient());
239 if (item.isCacheable() && clientCacheIsValid(item.client())) { 237 if (id.matches(item))
240 if (id.matches(item)) 238 return context.nextItemToIndex++;
241 return context.nextItemToIndex++; 239 if (item.isCacheable())
242
243 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPain tArtifact.getDisplayItemList().begin(), context.displayItemIndicesByClient); 240 addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPain tArtifact.getDisplayItemList().begin(), context.displayItemIndicesByClient);
244 }
245 } 241 }
246 return currentEnd; 242 return currentEnd;
247 } 243 }
248 244
249 void PaintController::copyCachedSubsequence(const DisplayItemList& currentList, DisplayItemList::iterator& currentIt, DisplayItemList& updatedList) 245 void PaintController::copyCachedSubsequence(const DisplayItemList& currentList, DisplayItemList::iterator& currentIt, DisplayItemList& updatedList)
250 { 246 {
251 ASSERT(currentIt->getType() == DisplayItem::Subsequence); 247 ASSERT(currentIt->getType() == DisplayItem::Subsequence);
252 ASSERT(!currentIt->scope()); 248 ASSERT(!currentIt->scope());
253 DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::EndSubseq uence, 0); 249 DisplayItem::Id endSubsequenceId(currentIt->client(), DisplayItem::EndSubseq uence, 0);
254 do { 250 do {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 // Coefficients are related to the ratio of out-of-order CachedDisplayItems 285 // Coefficients are related to the ratio of out-of-order CachedDisplayItems
290 // and the average number of (Drawing|Subsequence)DisplayItems per client. 286 // and the average number of (Drawing|Subsequence)DisplayItems per client.
291 // 287 //
292 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFrom LayoutObject) 288 void PaintController::commitNewDisplayItemsInternal(const LayoutSize& offsetFrom LayoutObject)
293 { 289 {
294 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", 290 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems",
295 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(), 291 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(),
296 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems); 292 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems);
297 m_numCachedNewItems = 0; 293 m_numCachedNewItems = 0;
298 294
299 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
300 m_clientsCheckedPaintInvalidation.clear();
301
302 // These data structures are used during painting only. 295 // These data structures are used during painting only.
303 ASSERT(m_scopeStack.isEmpty()); 296 ASSERT(m_scopeStack.isEmpty());
304 m_scopeStack.clear(); 297 m_scopeStack.clear();
305 m_nextScope = 1; 298 m_nextScope = 1;
306 ASSERT(!skippingCache()); 299 ASSERT(!skippingCache());
307 #if ENABLE(ASSERT) 300 #if ENABLE(ASSERT)
308 m_newDisplayItemIndicesByClient.clear(); 301 m_newDisplayItemIndicesByClient.clear();
309 m_clientsWithPaintOffsetInvalidations.clear(); 302 m_clientsWithPaintOffsetInvalidations.clear();
310 m_invalidations.clear(); 303 m_invalidations.clear();
311 #endif 304 #endif
312 305
313 if (m_currentPaintArtifact.isEmpty()) { 306 if (m_currentPaintArtifact.isEmpty()) {
314 #if ENABLE(ASSERT) 307 #if ENABLE(ASSERT)
315 for (const auto& item : m_newDisplayItemList) 308 for (const auto& item : m_newDisplayItemList)
316 ASSERT(!item.isCached()); 309 ASSERT(!item.isCached());
317 #endif 310 #endif
318 for (const auto& item : m_newDisplayItemList) 311 for (const auto& item : m_newDisplayItemList)
319 m_newDisplayItemList.appendVisualRect(visualRectForDisplayItem(item, offsetFromLayoutObject)); 312 m_newDisplayItemList.appendVisualRect(visualRectForDisplayItem(item, offsetFromLayoutObject));
320 313
321 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_newPaintChunks.releasePaintChunks()); 314 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_newPaintChunks.releasePaintChunks());
322 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBy tes); 315 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBy tes);
323 m_validlyCachedClientsDirty = true; 316 updateCacheGeneration();
324 return; 317 return;
325 } 318 }
326 319
327 updateValidlyCachedClientsIfNeeded();
328
329 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched 320 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched
330 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched 321 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched
331 // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This en sures that when 322 // by later out-of-order CachedDisplayItems in m_newDisplayItemList. This en sures that when
332 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems 323 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems
333 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. 324 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time.
334 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.getDisp layItemList().begin()); 325 OutOfOrderIndexContext outOfOrderIndexContext(m_currentPaintArtifact.getDisp layItemList().begin());
335 326
336 // TODO(jbroman): Consider revisiting this heuristic. 327 // TODO(jbroman): Consider revisiting this heuristic.
337 DisplayItemList updatedList(std::max(m_currentPaintArtifact.getDisplayItemLi st().usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes())); 328 DisplayItemList updatedList(std::max(m_currentPaintArtifact.getDisplayItemLi st().usedCapacityInBytes(), m_newDisplayItemList.usedCapacityInBytes()));
338 Vector<PaintChunk> updatedPaintChunks; 329 Vector<PaintChunk> updatedPaintChunks;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 #if ENABLE(ASSERT) 387 #if ENABLE(ASSERT)
397 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 388 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
398 checkNoRemainingCachedDisplayItems(); 389 checkNoRemainingCachedDisplayItems();
399 #endif // ENABLE(ASSERT) 390 #endif // ENABLE(ASSERT)
400 391
401 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to 392 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to
402 // merge the paint chunks as well. 393 // merge the paint chunks as well.
403 m_currentPaintArtifact = PaintArtifact(std::move(updatedList), m_newPaintChu nks.releasePaintChunks()); 394 m_currentPaintArtifact = PaintArtifact(std::move(updatedList), m_newPaintChu nks.releasePaintChunks());
404 395
405 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBytes) ; 396 m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBytes) ;
406 m_validlyCachedClientsDirty = true; 397 updateCacheGeneration();
407 } 398 }
408 399
409 size_t PaintController::approximateUnsharedMemoryUsage() const 400 size_t PaintController::approximateUnsharedMemoryUsage() const
410 { 401 {
411 size_t memoryUsage = sizeof(*this); 402 size_t memoryUsage = sizeof(*this);
412 403
413 // Memory outside this class due to m_currentPaintArtifact. 404 // Memory outside this class due to m_currentPaintArtifact.
414 memoryUsage += m_currentPaintArtifact.approximateUnsharedMemoryUsage() - siz eof(m_currentPaintArtifact); 405 memoryUsage += m_currentPaintArtifact.approximateUnsharedMemoryUsage() - siz eof(m_currentPaintArtifact);
415 406
416 // TODO(jbroman): If display items begin to have significant external memory 407 // TODO(jbroman): If display items begin to have significant external memory
417 // usage that's not shared with the embedder, we should account for it here. 408 // usage that's not shared with the embedder, we should account for it here.
418 // 409 //
419 // External objects, shared with the embedder, such as SkPicture, should be 410 // External objects, shared with the embedder, such as SkPicture, should be
420 // excluded to avoid double counting. It is the embedder's responsibility to 411 // excluded to avoid double counting. It is the embedder's responsibility to
421 // count such objects. 412 // count such objects.
422 // 413 //
423 // At time of writing, the only known case of unshared external memory was 414 // At time of writing, the only known case of unshared external memory was
424 // the rounded clips vector in ClipDisplayItem, which is not expected to 415 // the rounded clips vector in ClipDisplayItem, which is not expected to
425 // contribute significantly to memory usage. 416 // contribute significantly to memory usage.
426 417
427 // Memory outside this class due to m_newDisplayItemList. 418 // Memory outside this class due to m_newDisplayItemList.
428 ASSERT(m_newDisplayItemList.isEmpty()); 419 ASSERT(m_newDisplayItemList.isEmpty());
429 memoryUsage += m_newDisplayItemList.memoryUsageInBytes(); 420 memoryUsage += m_newDisplayItemList.memoryUsageInBytes();
430 421
431 return memoryUsage; 422 return memoryUsage;
432 } 423 }
433 424
434 void PaintController::updateValidlyCachedClientsIfNeeded() const 425 void PaintController::updateCacheGeneration()
435 { 426 {
436 if (!m_validlyCachedClientsDirty) 427 m_currentCacheGeneration = DisplayItemCacheGeneration::next();
437 return;
438
439 m_validlyCachedClients.clear();
440 m_validlyCachedClientsDirty = false;
441
442 const DisplayItemClient* lastAddedClient = nullptr;
443 for (const DisplayItem& displayItem : m_currentPaintArtifact.getDisplayItemL ist()) { 428 for (const DisplayItem& displayItem : m_currentPaintArtifact.getDisplayItemL ist()) {
444 if (&displayItem.client() == lastAddedClient) 429 if (displayItem.isCacheable())
445 continue; 430 displayItem.client().setDisplayItemsCached(m_currentCacheGeneration) ;
446 if (displayItem.isCacheable()) {
447 lastAddedClient = &displayItem.client();
448 m_validlyCachedClients.add(lastAddedClient);
449 }
450 } 431 }
451 } 432 }
452 433
453 #if ENABLE(ASSERT) 434 #if ENABLE(ASSERT)
454 435
455 void PaintController::checkUnderInvalidation(DisplayItemList::iterator& newIt, D isplayItemList::iterator& currentIt) 436 void PaintController::checkUnderInvalidation(DisplayItemList::iterator& newIt, D isplayItemList::iterator& currentIt)
456 { 437 {
457 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 438 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
458 ASSERT(newIt->isCached()); 439 ASSERT(newIt->isCached());
459 440
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 { 487 {
507 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 488 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
508 ASSERT(!newItem.isCached()); 489 ASSERT(!newItem.isCached());
509 ASSERT(!oldItem.isCached()); 490 ASSERT(!oldItem.isCached());
510 491
511 if (newItem.skippedCache()) { 492 if (newItem.skippedCache()) {
512 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: sk ipped-cache in cached subsequence", &newItem, &oldItem); 493 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: sk ipped-cache in cached subsequence", &newItem, &oldItem);
513 ASSERT_NOT_REACHED(); 494 ASSERT_NOT_REACHED();
514 } 495 }
515 496
516 if (newItem.isCacheable() && !m_validlyCachedClients.contains(&newItem.clien t())) { 497 if (newItem.isCacheable() && !clientCacheIsValid(newItem.client())) {
517 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: in validated in cached subsequence", &newItem, &oldItem); 498 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: in validated in cached subsequence", &newItem, &oldItem);
518 ASSERT_NOT_REACHED(); 499 ASSERT_NOT_REACHED();
519 } 500 }
520 501
521 if (newItem.equals(oldItem)) 502 if (newItem.equals(oldItem))
522 return; 503 return;
523 504
524 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: displa y item changed", &newItem, &oldItem); 505 showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: displa y item changed", &newItem, &oldItem);
525 506
526 #ifndef NDEBUG 507 #ifndef NDEBUG
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 554
574 void PaintController::showDebugData() const 555 void PaintController::showDebugData() const
575 { 556 {
576 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); 557 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data());
577 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data()); 558 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data());
578 } 559 }
579 560
580 #endif // ifndef NDEBUG 561 #endif // ifndef NDEBUG
581 562
582 } // namespace blink 563 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698