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/TraceEvent.h" | 9 #include "platform/TraceEvent.h" |
10 #include "platform/graphics/paint/DrawingDisplayItem.h" | 10 #include "platform/graphics/paint/DrawingDisplayItem.h" |
11 | 11 |
12 #ifndef NDEBUG | 12 #ifndef NDEBUG |
13 #include "platform/graphics/LoggingCanvas.h" | 13 #include "platform/graphics/LoggingCanvas.h" |
14 #include "wtf/text/StringBuilder.h" | 14 #include "wtf/text/StringBuilder.h" |
15 #include <stdio.h> | 15 #include <stdio.h> |
16 #endif | 16 #endif |
17 | 17 |
18 namespace blink { | 18 namespace blink { |
19 | 19 |
20 const DisplayItems& DisplayItemList::displayItems() const | 20 const DisplayItems& DisplayItemList::displayItems() const |
21 { | 21 { |
22 ASSERT(m_newDisplayItems.isEmpty()); | 22 ASSERT(m_newDisplayItems.isEmpty()); |
23 return m_currentDisplayItems; | 23 return m_currentDisplayItems; |
24 } | 24 } |
25 | 25 |
| 26 const Vector<PaintChunk>& DisplayItemList::paintChunks() const |
| 27 { |
| 28 ASSERT(m_newPaintChunks.isInInitialState()); |
| 29 return m_currentPaintChunks; |
| 30 } |
| 31 |
26 bool DisplayItemList::lastDisplayItemIsNoopBegin() const | 32 bool DisplayItemList::lastDisplayItemIsNoopBegin() const |
27 { | 33 { |
28 if (m_newDisplayItems.isEmpty()) | 34 if (m_newDisplayItems.isEmpty()) |
29 return false; | 35 return false; |
30 | 36 |
31 const auto& lastDisplayItem = m_newDisplayItems.last(); | 37 const auto& lastDisplayItem = m_newDisplayItems.last(); |
32 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); | 38 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); |
33 } | 39 } |
34 | 40 |
35 void DisplayItemList::removeLastDisplayItem() | 41 void DisplayItemList::removeLastDisplayItem() |
36 { | 42 { |
37 if (m_newDisplayItems.isEmpty()) | 43 if (m_newDisplayItems.isEmpty()) |
38 return; | 44 return; |
39 | 45 |
40 #if ENABLE(ASSERT) | 46 #if ENABLE(ASSERT) |
41 // Also remove the index pointing to the removed display item. | 47 // Also remove the index pointing to the removed display item. |
42 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient
.find(m_newDisplayItems.last().client()); | 48 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient
.find(m_newDisplayItems.last().client()); |
43 if (it != m_newDisplayItemIndicesByClient.end()) { | 49 if (it != m_newDisplayItemIndicesByClient.end()) { |
44 Vector<size_t>& indices = it->value; | 50 Vector<size_t>& indices = it->value; |
45 if (!indices.isEmpty() && indices.last() == (m_newDisplayItems.size() -
1)) | 51 if (!indices.isEmpty() && indices.last() == (m_newDisplayItems.size() -
1)) |
46 indices.removeLast(); | 52 indices.removeLast(); |
47 } | 53 } |
48 #endif | 54 #endif |
49 m_newDisplayItems.removeLast(); | 55 m_newDisplayItems.removeLast(); |
| 56 m_newPaintChunks.decrementDisplayItemIndex(); |
50 } | 57 } |
51 | 58 |
52 void DisplayItemList::processNewItem(DisplayItem& displayItem) | 59 void DisplayItemList::processNewItem(DisplayItem& displayItem) |
53 { | 60 { |
54 ASSERT(!m_constructionDisabled); | 61 ASSERT(!m_constructionDisabled); |
55 ASSERT(!skippingCache() || !displayItem.isCached()); | 62 ASSERT(!skippingCache() || !displayItem.isCached()); |
56 | 63 |
57 if (displayItem.isCached()) | 64 if (displayItem.isCached()) |
58 ++m_numCachedItems; | 65 ++m_numCachedItems; |
59 | 66 |
(...skipping 17 matching lines...) Expand all Loading... |
77 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", | 84 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=%
d)\n", |
78 displayItem.asDebugString().utf8().data(), m_newDisplayItems[index].
asDebugString().utf8().data(), static_cast<int>(index)); | 85 displayItem.asDebugString().utf8().data(), m_newDisplayItems[index].
asDebugString().utf8().data(), static_cast<int>(index)); |
79 #endif | 86 #endif |
80 ASSERT_NOT_REACHED(); | 87 ASSERT_NOT_REACHED(); |
81 } | 88 } |
82 addItemToIndexIfNeeded(displayItem, m_newDisplayItems.size() - 1, m_newDispl
ayItemIndicesByClient); | 89 addItemToIndexIfNeeded(displayItem, m_newDisplayItems.size() - 1, m_newDispl
ayItemIndicesByClient); |
83 #endif // ENABLE(ASSERT) | 90 #endif // ENABLE(ASSERT) |
84 | 91 |
85 if (skippingCache()) | 92 if (skippingCache()) |
86 displayItem.setSkippedCache(); | 93 displayItem.setSkippedCache(); |
| 94 |
| 95 m_newPaintChunks.incrementDisplayItemIndex(); |
| 96 } |
| 97 |
| 98 void DisplayItemList::updateCurrentPaintProperties(const PaintProperties& newPai
ntProperties) |
| 99 { |
| 100 m_newPaintChunks.updateCurrentPaintProperties(newPaintProperties); |
87 } | 101 } |
88 | 102 |
89 void DisplayItemList::beginScope() | 103 void DisplayItemList::beginScope() |
90 { | 104 { |
91 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); | 105 ASSERT_WITH_SECURITY_IMPLICATION(m_nextScope < UINT_MAX); |
92 m_scopeStack.append(m_nextScope++); | 106 m_scopeStack.append(m_nextScope++); |
93 beginSkippingCache(); | 107 beginSkippingCache(); |
94 } | 108 } |
95 | 109 |
96 void DisplayItemList::endScope() | 110 void DisplayItemList::endScope() |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 #if ENABLE(ASSERT) | 279 #if ENABLE(ASSERT) |
266 m_newDisplayItemIndicesByClient.clear(); | 280 m_newDisplayItemIndicesByClient.clear(); |
267 #endif | 281 #endif |
268 | 282 |
269 if (m_currentDisplayItems.isEmpty()) { | 283 if (m_currentDisplayItems.isEmpty()) { |
270 #if ENABLE(ASSERT) | 284 #if ENABLE(ASSERT) |
271 for (const auto& item : m_newDisplayItems) | 285 for (const auto& item : m_newDisplayItems) |
272 ASSERT(!item.isCached()); | 286 ASSERT(!item.isCached()); |
273 #endif | 287 #endif |
274 m_currentDisplayItems.swap(m_newDisplayItems); | 288 m_currentDisplayItems.swap(m_newDisplayItems); |
| 289 m_currentPaintChunks = m_newPaintChunks.releasePaintChunks(); |
275 m_validlyCachedClientsDirty = true; | 290 m_validlyCachedClientsDirty = true; |
276 m_numCachedItems = 0; | 291 m_numCachedItems = 0; |
277 return; | 292 return; |
278 } | 293 } |
279 | 294 |
280 updateValidlyCachedClientsIfNeeded(); | 295 updateValidlyCachedClientsIfNeeded(); |
281 | 296 |
282 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched | 297 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that
have not been matched |
283 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched | 298 // by CachedDisplayItems during synchronized matching. The indexed items wil
l be matched |
284 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when | 299 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur
es that when |
285 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems | 300 // out-of-order CachedDisplayItems occur, we only traverse at most once over
m_currentDisplayItems |
286 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. | 301 // looking for potential matches. Thus we can ensure that the algorithm runs
in linear time. |
287 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; | 302 OutOfOrderIndexContext outOfOrderIndexContext(m_currentDisplayItems.begin())
; |
288 | 303 |
289 // TODO(jbroman): Consider revisiting this heuristic. | 304 // TODO(jbroman): Consider revisiting this heuristic. |
290 DisplayItems updatedList(std::max(m_currentDisplayItems.usedCapacityInBytes(
), m_newDisplayItems.usedCapacityInBytes())); | 305 DisplayItems updatedList(std::max(m_currentDisplayItems.usedCapacityInBytes(
), m_newDisplayItems.usedCapacityInBytes())); |
| 306 Vector<PaintChunk> updatedPaintChunks; |
291 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); | 307 DisplayItems::iterator currentIt = m_currentDisplayItems.begin(); |
292 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); | 308 DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); |
293 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { | 309 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne
wDisplayItems.end(); ++newIt) { |
294 const DisplayItem& newDisplayItem = *newIt; | 310 const DisplayItem& newDisplayItem = *newIt; |
295 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 311 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
296 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; | 312 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt
emId.type; |
297 | 313 |
298 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); | 314 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche
s(*currentIt); |
299 | 315 |
300 if (newDisplayItemHasCachedType) { | 316 if (newDisplayItemHasCachedType) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 // Items before currentIt should have been copied so we don't need to in
dex them. | 359 // Items before currentIt should have been copied so we don't need to in
dex them. |
344 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) | 360 if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0) |
345 outOfOrderIndexContext.nextItemToIndex = currentIt; | 361 outOfOrderIndexContext.nextItemToIndex = currentIt; |
346 } | 362 } |
347 | 363 |
348 #if ENABLE(ASSERT) | 364 #if ENABLE(ASSERT) |
349 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 365 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
350 checkNoRemainingCachedDisplayItems(); | 366 checkNoRemainingCachedDisplayItems(); |
351 #endif // ENABLE(ASSERT) | 367 #endif // ENABLE(ASSERT) |
352 | 368 |
| 369 // TODO(jbroman): When subsequence caching applies to SPv2, we'll need to |
| 370 // merge the paint chunks as well. |
| 371 m_currentPaintChunks = m_newPaintChunks.releasePaintChunks(); |
| 372 |
353 m_newDisplayItems.clear(); | 373 m_newDisplayItems.clear(); |
354 m_validlyCachedClientsDirty = true; | 374 m_validlyCachedClientsDirty = true; |
355 m_currentDisplayItems.swap(updatedList); | 375 m_currentDisplayItems.swap(updatedList); |
356 m_numCachedItems = 0; | 376 m_numCachedItems = 0; |
357 | 377 |
358 #if ENABLE(ASSERT) | 378 #if ENABLE(ASSERT) |
359 m_clientsWithPaintOffsetInvalidations.clear(); | 379 m_clientsWithPaintOffsetInvalidations.clear(); |
360 #endif | 380 #endif |
361 } | 381 } |
362 | 382 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 | 567 |
548 void DisplayItemList::replay(GraphicsContext& context) | 568 void DisplayItemList::replay(GraphicsContext& context) |
549 { | 569 { |
550 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 570 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
551 ASSERT(m_newDisplayItems.isEmpty()); | 571 ASSERT(m_newDisplayItems.isEmpty()); |
552 for (DisplayItem& displayItem : m_currentDisplayItems) | 572 for (DisplayItem& displayItem : m_currentDisplayItems) |
553 displayItem.replay(context); | 573 displayItem.replay(context); |
554 } | 574 } |
555 | 575 |
556 } // namespace blink | 576 } // namespace blink |
OLD | NEW |