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 "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 #include "third_party/skia/include/core/SkPictureAnalyzer.h" | 10 #include "third_party/skia/include/core/SkPictureAnalyzer.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
44 | 44 |
45 size_t cachedItem = findCachedItem(DisplayItem::Id(client, type)); | 45 size_t cachedItem = findCachedItem(DisplayItem::Id(client, type)); |
46 if (cachedItem == kNotFound) { | 46 if (cachedItem == kNotFound) { |
47 NOTREACHED(); | 47 NOTREACHED(); |
48 return false; | 48 return false; |
49 } | 49 } |
50 | 50 |
51 ++m_numCachedNewItems; | 51 ++m_numCachedNewItems; |
52 ensureNewDisplayItemListInitialCapacity(); | 52 ensureNewDisplayItemListInitialCapacity(); |
53 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidati onCheckingEnabled()) | 53 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidati onCheckingEnabled()) |
54 processNewItem(m_newDisplayItemList.appendByMoving(m_currentPaintArtifac t.getDisplayItemList()[cachedItem])); | 54 processNewItem(m_newDisplayItemList.appendByMoving(m_currentPaintArtifac t.getDisplayItemList()[cachedItem]), FromCachedItem); |
55 | 55 |
56 m_nextItemToMatch = cachedItem + 1; | 56 m_nextItemToMatch = cachedItem + 1; |
57 // Items before m_nextItemToMatch have been copied so we don't need to index them. | 57 // Items before m_nextItemToMatch have been copied so we don't need to index them. |
58 if (m_nextItemToMatch > m_nextItemToIndex) | 58 if (m_nextItemToMatch > m_nextItemToIndex) |
59 m_nextItemToIndex = m_nextItemToMatch; | 59 m_nextItemToIndex = m_nextItemToMatch; |
60 | 60 |
61 #if DCHECK_IS_ON() | 61 #if DCHECK_IS_ON() |
62 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) { | 62 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) { |
63 if (!isCheckingUnderInvalidation()) { | 63 if (!isCheckingUnderInvalidation()) { |
64 m_underInvalidationCheckingBegin = cachedItem; | 64 m_underInvalidationCheckingBegin = cachedItem; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); | 126 return lastDisplayItem.isBegin() && !lastDisplayItem.drawsContent(); |
127 } | 127 } |
128 | 128 |
129 void PaintController::removeLastDisplayItem() | 129 void PaintController::removeLastDisplayItem() |
130 { | 130 { |
131 if (m_newDisplayItemList.isEmpty()) | 131 if (m_newDisplayItemList.isEmpty()) |
132 return; | 132 return; |
133 | 133 |
134 #if DCHECK_IS_ON() | 134 #if DCHECK_IS_ON() |
135 // Also remove the index pointing to the removed display item. | 135 // Also remove the index pointing to the removed display item. |
136 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient .find(&m_newDisplayItemList.last().client()); | 136 IndicesByClientMap::iterator it = m_newDisplayItemIndicesByClient.find(&m_ne wDisplayItemList.last().client()); |
137 if (it != m_newDisplayItemIndicesByClient.end()) { | 137 if (it != m_newDisplayItemIndicesByClient.end()) { |
138 Vector<size_t>& indices = it->value; | 138 Vector<size_t>& indices = it->value; |
139 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1)) | 139 if (!indices.isEmpty() && indices.last() == (m_newDisplayItemList.size() - 1)) |
140 indices.removeLast(); | 140 indices.removeLast(); |
141 } | 141 } |
142 | 142 |
143 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) { | 143 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) { |
144 if (m_skippedProbableUnderInvalidationCount) { | 144 if (m_skippedProbableUnderInvalidationCount) { |
145 --m_skippedProbableUnderInvalidationCount; | 145 --m_skippedProbableUnderInvalidationCount; |
146 } else { | 146 } else { |
147 DCHECK(m_underInvalidationCheckingBegin); | 147 DCHECK(m_underInvalidationCheckingBegin); |
148 --m_underInvalidationCheckingBegin; | 148 --m_underInvalidationCheckingBegin; |
149 } | 149 } |
150 } | 150 } |
151 #endif | 151 #endif |
152 m_newDisplayItemList.removeLast(); | 152 m_newDisplayItemList.removeLast(); |
153 | 153 |
154 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 154 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
155 m_newPaintChunks.decrementDisplayItemIndex(); | 155 m_newPaintChunks.decrementDisplayItemIndex(); |
156 } | 156 } |
157 | 157 |
158 const DisplayItem* PaintController::lastDisplayItem(unsigned offset) | 158 const DisplayItem* PaintController::lastDisplayItem(unsigned offset) |
159 { | 159 { |
160 if (offset < m_newDisplayItemList.size()) | 160 if (offset < m_newDisplayItemList.size()) |
161 return &m_newDisplayItemList[m_newDisplayItemList.size() - offset - 1]; | 161 return &m_newDisplayItemList[m_newDisplayItemList.size() - offset - 1]; |
162 return nullptr; | 162 return nullptr; |
163 } | 163 } |
164 | 164 |
165 void PaintController::processNewItem(DisplayItem& displayItem) | 165 void PaintController::processNewItem(DisplayItem& displayItem, NewItemSource new ItemSource) |
166 { | 166 { |
167 DCHECK(!m_constructionDisabled); | 167 DCHECK(!m_constructionDisabled); |
168 | 168 |
169 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 169 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
170 if (!isSkippingCache()) { | 170 if (!isSkippingCache()) { |
171 if (displayItem.isCacheable()) { | 171 if (displayItem.isCacheable()) { |
172 // Mark the client shouldKeepAlive under this PaintController. | 172 // Mark the client shouldKeepAlive under this PaintController. |
173 // The status will end after the new display items are committed. | 173 // The status will end after the new display items are committed. |
174 displayItem.client().beginShouldKeepAlive(this); | 174 displayItem.client().beginShouldKeepAlive(this); |
175 | 175 |
176 if (!m_currentSubsequenceClients.isEmpty()) { | 176 if (!m_currentSubsequenceClients.isEmpty()) { |
177 // Mark the client shouldKeepAlive under the current subsequence . | 177 // Mark the client shouldKeepAlive under the current subsequence . |
178 // The status will end when the subsequence owner is invalidated or deleted. | 178 // The status will end when the subsequence owner is invalidated or deleted. |
179 displayItem.client().beginShouldKeepAlive(m_currentSubsequenceCl ients.last()); | 179 displayItem.client().beginShouldKeepAlive(m_currentSubsequenceCl ients.last()); |
180 } | 180 } |
181 } | 181 } |
182 | 182 |
183 if (displayItem.getType() == DisplayItem::Subsequence) { | 183 if (displayItem.getType() == DisplayItem::Subsequence) { |
184 m_currentSubsequenceClients.append(&displayItem.client()); | 184 m_currentSubsequenceClients.append(&displayItem.client()); |
185 } else if (displayItem.getType() == DisplayItem::EndSubsequence) { | 185 } else if (displayItem.getType() == DisplayItem::EndSubsequence) { |
186 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); | 186 CHECK(m_currentSubsequenceClients.last() == &displayItem.client()); |
187 m_currentSubsequenceClients.removeLast(); | 187 m_currentSubsequenceClients.removeLast(); |
188 } | 188 } |
189 } | 189 } |
190 #endif | 190 #endif |
191 | 191 |
192 if (isSkippingCache()) | 192 if (isSkippingCache()) { |
193 DCHECK(newItemSource == NewPainting); | |
193 displayItem.setSkippedCache(); | 194 displayItem.setSkippedCache(); |
195 } | |
196 | |
197 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | |
198 if (newItemSource != FromCachedSubsequence) | |
199 m_currentChunkIsFromCachedSubsequence = false; | |
200 | |
201 size_t lastChunkIndex = m_newPaintChunks.lastChunkIndex(); | |
202 if (m_newPaintChunks.incrementDisplayItemIndex(displayItem)) { | |
203 DCHECK(lastChunkIndex != m_newPaintChunks.lastChunkIndex()); | |
204 if (lastChunkIndex != kNotFound) | |
205 generateChunkRerasterizationRects(m_newPaintChunks.paintChunkAt( lastChunkIndex)); | |
206 m_currentChunkIsFromCachedSubsequence = true; | |
207 } | |
208 } | |
194 | 209 |
195 #if DCHECK_IS_ON() | 210 #if DCHECK_IS_ON() |
196 // Verify noop begin/end pairs have been removed. | 211 // Verify noop begin/end pairs have been removed. |
197 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { | 212 if (m_newDisplayItemList.size() >= 2 && displayItem.isEnd()) { |
198 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2]; | 213 const auto& beginDisplayItem = m_newDisplayItemList[m_newDisplayItemList .size() - 2]; |
199 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::Subsequence && !beginDisplayItem.drawsContent()) | 214 if (beginDisplayItem.isBegin() && beginDisplayItem.getType() != DisplayI tem::Subsequence && !beginDisplayItem.drawsContent()) |
200 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); | 215 DCHECK(!displayItem.isEndAndPairedWith(beginDisplayItem.getType())); |
201 } | 216 } |
202 | 217 |
203 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList); | 218 size_t index = findMatchingItemFromIndex(displayItem.getId(), m_newDisplayIt emIndicesByClient, m_newDisplayItemList); |
204 if (index != kNotFound) { | 219 if (index != kNotFound) { |
205 #ifndef NDEBUG | 220 #ifndef NDEBUG |
206 showDebugData(); | 221 showDebugData(); |
207 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", | 222 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", |
208 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index)); | 223 displayItem.asDebugString().utf8().data(), m_newDisplayItemList[inde x].asDebugString().utf8().data(), static_cast<int>(index)); |
209 #endif | 224 #endif |
210 NOTREACHED(); | 225 NOTREACHED(); |
211 } | 226 } |
212 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient); | 227 addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDi splayItemIndicesByClient); |
213 | 228 |
214 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 229 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
215 checkUnderInvalidation(); | 230 checkUnderInvalidation(); |
216 #endif // DCHECK_IS_ON() | 231 #endif // DCHECK_IS_ON() |
217 | |
218 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
219 m_newPaintChunks.incrementDisplayItemIndex(displayItem); | |
220 } | 232 } |
221 | 233 |
222 void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id , const PaintChunkProperties& newProperties) | 234 void PaintController::updateCurrentPaintChunkProperties(const PaintChunk::Id* id , const PaintChunkProperties& newProperties) |
223 { | 235 { |
224 m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties); | 236 m_newPaintChunks.updateCurrentPaintChunkProperties(id, newProperties); |
225 } | 237 } |
226 | 238 |
227 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const | 239 const PaintChunkProperties& PaintController::currentPaintChunkProperties() const |
228 { | 240 { |
229 return m_newPaintChunks.currentPaintChunkProperties(); | 241 return m_newPaintChunks.currentPaintChunkProperties(); |
(...skipping 10 matching lines...) Expand all Loading... | |
240 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const | 252 bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const |
241 { | 253 { |
242 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 254 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
243 CHECK(client.isAlive()); | 255 CHECK(client.isAlive()); |
244 #endif | 256 #endif |
245 if (isSkippingCache()) | 257 if (isSkippingCache()) |
246 return false; | 258 return false; |
247 return client.displayItemsAreCached(m_currentCacheGeneration); | 259 return client.displayItemsAreCached(m_currentCacheGeneration); |
248 } | 260 } |
249 | 261 |
250 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItemL ist& list) | 262 size_t PaintController::findMatchingItemFromIndex(const DisplayItem::Id& id, con st IndicesByClientMap& displayItemIndicesByClient, const DisplayItemList& list) |
251 { | 263 { |
252 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(&id.client); | 264 IndicesByClientMap::const_iterator it = displayItemIndicesByClient.find(&id. client); |
253 if (it == displayItemIndicesByClient.end()) | 265 if (it == displayItemIndicesByClient.end()) |
254 return kNotFound; | 266 return kNotFound; |
255 | 267 |
256 const Vector<size_t>& indices = it->value; | 268 const Vector<size_t>& indices = it->value; |
257 for (size_t index : indices) { | 269 for (size_t index : indices) { |
258 const DisplayItem& existingItem = list[index]; | 270 const DisplayItem& existingItem = list[index]; |
259 DCHECK(!existingItem.hasValidClient() || existingItem.client() == id.cli ent); | 271 DCHECK(!existingItem.hasValidClient() || existingItem.client() == id.cli ent); |
260 if (id == existingItem.getId()) | 272 if (id == existingItem.getId()) |
261 return index; | 273 return index; |
262 } | 274 } |
263 | 275 |
264 return kNotFound; | 276 return kNotFound; |
265 } | 277 } |
266 | 278 |
267 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient) | 279 void PaintController::addItemToIndexIfNeeded(const DisplayItem& displayItem, siz e_t index, IndicesByClientMap& displayItemIndicesByClient) |
268 { | 280 { |
269 if (!displayItem.isCacheable()) | 281 if (!displayItem.isCacheable()) |
270 return; | 282 return; |
271 | 283 |
272 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find (&displayItem.client()); | 284 IndicesByClientMap::iterator it = displayItemIndicesByClient.find(&displayIt em.client()); |
273 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? | 285 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? |
274 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value; | 286 displayItemIndicesByClient.add(&displayItem.client(), Vector<size_t>()). storedValue->value : it->value; |
275 indices.append(index); | 287 indices.append(index); |
276 } | 288 } |
277 | 289 |
278 size_t PaintController::findCachedItem(const DisplayItem::Id& id) | 290 size_t PaintController::findCachedItem(const DisplayItem::Id& id) |
279 { | 291 { |
280 DCHECK(clientCacheIsValid(id.client)); | 292 DCHECK(clientCacheIsValid(id.client)); |
281 | 293 |
282 // Try to find the item sequentially first. This is fast if the current list and the new list are in | 294 // Try to find the item sequentially first. This is fast if the current list and the new list are in |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS | 382 #if CHECK_DISPLAY_ITEM_CLIENT_ALIVENESS |
371 CHECK(cachedItem->client().isAlive()); | 383 CHECK(cachedItem->client().isAlive()); |
372 #endif | 384 #endif |
373 ++m_numCachedNewItems; | 385 ++m_numCachedNewItems; |
374 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; | 386 bool metEndSubsequence = cachedItem->getId() == endSubsequenceId; |
375 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) { | 387 if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvali dationCheckingEnabled()) { |
376 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) { | 388 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && cachedItemIn dex == cachedChunk->endIndex) { |
377 ++cachedChunk; | 389 ++cachedChunk; |
378 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties); | 390 updateCurrentPaintChunkProperties(cachedChunk->id ? &*cachedChun k->id : nullptr, cachedChunk->properties); |
379 } | 391 } |
380 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem)); | 392 processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem), Fro mCachedSubsequence); |
381 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 393 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
382 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk)); | 394 DCHECK((!m_newPaintChunks.lastChunk().id && !cachedChunk->id) || m_newPaintChunks.lastChunk().matches(*cachedChunk)); |
383 } | 395 } |
384 | 396 |
385 ++cachedItemIndex; | 397 ++cachedItemIndex; |
386 if (metEndSubsequence) | 398 if (metEndSubsequence) |
387 break; | 399 break; |
388 | 400 |
389 // We should always be able to find the EndSubsequence display item. | 401 // We should always be able to find the EndSubsequence display item. |
390 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz e()); | 402 DCHECK(cachedItemIndex < m_currentPaintArtifact.getDisplayItemList().siz e()); |
(...skipping 12 matching lines...) Expand all Loading... | |
403 { | 415 { |
404 LayoutRect visualRect = displayItem.client().visualRect(); | 416 LayoutRect visualRect = displayItem.client().visualRect(); |
405 visualRect.move(-offsetFromLayoutObject); | 417 visualRect.move(-offsetFromLayoutObject); |
406 return enclosingIntRect(visualRect); | 418 return enclosingIntRect(visualRect); |
407 } | 419 } |
408 | 420 |
409 void PaintController::resetCurrentListIndices() | 421 void PaintController::resetCurrentListIndices() |
410 { | 422 { |
411 m_nextItemToMatch = 0; | 423 m_nextItemToMatch = 0; |
412 m_nextItemToIndex = 0; | 424 m_nextItemToIndex = 0; |
425 m_nextChunkToMatch = 0; | |
413 #if DCHECK_IS_ON() | 426 #if DCHECK_IS_ON() |
414 m_underInvalidationCheckingBegin = 0; | 427 m_underInvalidationCheckingBegin = 0; |
415 m_underInvalidationCheckingEnd = 0; | 428 m_underInvalidationCheckingEnd = 0; |
416 m_skippedProbableUnderInvalidationCount = 0; | 429 m_skippedProbableUnderInvalidationCount = 0; |
417 #endif | 430 #endif |
418 } | 431 } |
419 | 432 |
420 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject) | 433 void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutOb ject) |
421 { | 434 { |
422 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", | 435 TRACE_EVENT2("blink,benchmark", "PaintController::commitNewDisplayItems", |
423 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(), | 436 "current_display_list_size", (int)m_currentPaintArtifact.getDisplayItemL ist().size(), |
424 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems); | 437 "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCach edNewItems); |
425 m_numCachedNewItems = 0; | 438 m_numCachedNewItems = 0; |
426 | 439 |
427 // These data structures are used during painting only. | 440 // These data structures are used during painting only. |
428 DCHECK(!isSkippingCache()); | 441 DCHECK(!isSkippingCache()); |
429 #if DCHECK_IS_ON() | 442 #if DCHECK_IS_ON() |
430 m_newDisplayItemIndicesByClient.clear(); | 443 m_newDisplayItemIndicesByClient.clear(); |
431 #endif | 444 #endif |
432 | 445 |
446 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && !m_newDisplayItemLis t.isEmpty()) | |
447 generateChunkRerasterizationRects(m_newPaintChunks.lastChunk()); | |
448 | |
433 SkPictureGpuAnalyzer gpuAnalyzer; | 449 SkPictureGpuAnalyzer gpuAnalyzer; |
434 | 450 |
435 m_currentCacheGeneration = DisplayItemClient::CacheGenerationOrInvalidationR eason::next(); | 451 m_currentCacheGeneration = DisplayItemClient::CacheGenerationOrInvalidationR eason::next(); |
436 Vector<const DisplayItemClient*> skippedCacheClients; | 452 Vector<const DisplayItemClient*> skippedCacheClients; |
437 for (const auto& item : m_newDisplayItemList) { | 453 for (const auto& item : m_newDisplayItemList) { |
438 // No reason to continue the analysis once we have a veto. | 454 // No reason to continue the analysis once we have a veto. |
439 if (gpuAnalyzer.suitableForGpuRasterization()) | 455 if (gpuAnalyzer.suitableForGpuRasterization()) |
440 item.analyzeForGpuRasterization(gpuAnalyzer); | 456 item.analyzeForGpuRasterization(gpuAnalyzer); |
441 | 457 |
442 // TODO(wkorman): Only compute and append visual rect for drawings. | 458 // TODO(wkorman): Only compute and append visual rect for drawings. |
(...skipping 10 matching lines...) Expand all Loading... | |
453 } | 469 } |
454 | 470 |
455 for (auto* client : skippedCacheClients) | 471 for (auto* client : skippedCacheClients) |
456 client->setDisplayItemsUncached(); | 472 client->setDisplayItemsUncached(); |
457 | 473 |
458 // The new list will not be appended to again so we can release unused memor y. | 474 // The new list will not be appended to again so we can release unused memor y. |
459 m_newDisplayItemList.shrinkToFit(); | 475 m_newDisplayItemList.shrinkToFit(); |
460 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_ne wPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization()); | 476 m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_ne wPaintChunks.releasePaintChunks(), gpuAnalyzer.suitableForGpuRasterization()); |
461 resetCurrentListIndices(); | 477 resetCurrentListIndices(); |
462 m_outOfOrderItemIndices.clear(); | 478 m_outOfOrderItemIndices.clear(); |
479 m_outOfOrderChunkIndices.clear(); | |
463 | 480 |
464 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 481 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
465 for (const auto& chunk : m_currentPaintArtifact.paintChunks()) { | 482 for (const auto& chunk : m_currentPaintArtifact.paintChunks()) { |
466 if (chunk.id && chunk.id->client.isJustCreated()) | 483 if (chunk.id && chunk.id->client.isJustCreated()) |
467 chunk.id->client.clearIsJustCreated(); | 484 chunk.id->client.clearIsJustCreated(); |
468 } | 485 } |
469 } | 486 } |
470 | 487 |
471 // We'll allocate the initial buffer when we start the next paint. | 488 // We'll allocate the initial buffer when we start the next paint. |
472 m_newDisplayItemList = DisplayItemList(0); | 489 m_newDisplayItemList = DisplayItemList(0); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 | 527 |
511 void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis playItemClient, PassRefPtr<SkPicture> picture, const LayoutSize& offsetFromLayou tObject) | 528 void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis playItemClient, PassRefPtr<SkPicture> picture, const LayoutSize& offsetFromLayou tObject) |
512 { | 529 { |
513 DCHECK(m_newDisplayItemList.isEmpty()); | 530 DCHECK(m_newDisplayItemList.isEmpty()); |
514 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList( ).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug Drawing, picture); | 531 DrawingDisplayItem& displayItem = m_currentPaintArtifact.getDisplayItemList( ).allocateAndConstruct<DrawingDisplayItem>(displayItemClient, DisplayItem::Debug Drawing, picture); |
515 displayItem.setSkippedCache(); | 532 displayItem.setSkippedCache(); |
516 // TODO(wkorman): Only compute and append visual rect for drawings. | 533 // TODO(wkorman): Only compute and append visual rect for drawings. |
517 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi splayItem(displayItem, offsetFromLayoutObject)); | 534 m_currentPaintArtifact.getDisplayItemList().appendVisualRect(visualRectForDi splayItem(displayItem, offsetFromLayoutObject)); |
518 } | 535 } |
519 | 536 |
537 void PaintController::generateChunkRerasterizationRects(PaintChunk& newChunk) | |
538 { | |
539 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
540 if (m_currentChunkIsFromCachedSubsequence) | |
541 return; | |
542 | |
543 if (!newChunk.id) { | |
chrishtr
2016/08/26 18:10:51
Why would there be no id?
Xianzhu
2016/08/26 18:39:23
Please see https://cs.chromium.org/chromium/src/th
| |
544 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIn tRect())); | |
545 return; | |
546 } | |
547 | |
548 // Try to match old chunk sequentially first. | |
549 const auto& oldChunks = m_currentPaintArtifact.paintChunks(); | |
550 while (m_nextChunkToMatch < oldChunks.size()) { | |
551 const PaintChunk& oldChunk = oldChunks[m_nextChunkToMatch]; | |
552 if (newChunk.matches(oldChunk)) { | |
553 generateChunkRerasterizationRectsComparingOldChunk(newChunk, oldChun k); | |
554 ++m_nextChunkToMatch; | |
555 return; | |
556 } | |
557 | |
558 // Add skipped old chunks into the index. | |
559 if (oldChunk.id) { | |
560 auto it = m_outOfOrderChunkIndices.find(&oldChunk.id->client); | |
561 Vector<size_t>& indices = it == m_outOfOrderChunkIndices.end() ? | |
562 m_outOfOrderChunkIndices.add(&oldChunk.id->client, Vector<size_t >()).storedValue->value : it->value; | |
563 indices.append(m_nextChunkToMatch); | |
564 } | |
565 ++m_nextChunkToMatch; | |
566 } | |
567 | |
568 // Sequential matching reaches the end. Find from the out-of-order index. | |
569 auto it = m_outOfOrderChunkIndices.find(&newChunk.id->client); | |
570 if (it != m_outOfOrderChunkIndices.end()) { | |
571 for (size_t i : it->value) { | |
572 if (newChunk.matches(oldChunks[i])) { | |
573 generateChunkRerasterizationRectsComparingOldChunk(newChunk, old Chunks[i]); | |
574 return; | |
575 } | |
576 } | |
577 } | |
578 | |
579 // We reach here because the chunk is new. | |
580 newChunk.rasterInvalidationRects.append(FloatRect(LayoutRect::infiniteIntRec t())); | |
581 } | |
582 | |
583 void PaintController::generateChunkRerasterizationRectsComparingOldChunk(PaintCh unk& newChunk, const PaintChunk& oldChunk) | |
584 { | |
585 DCHECK(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
586 | |
587 // TODO(wangxianzhu): Support raster invalidation for recordered display ite ms without invalidating | |
chrishtr
2016/08/26 18:10:51
Do you mean "reordered"? What is an example where
Xianzhu
2016/08/26 18:39:23
Yes :) An example is z-index change: actually we d
| |
588 // display item clients. Currently we invalidate display item clients ensuri ng raster invalidation. | |
589 | |
590 // Maps from each client to the index of the first drawing-content display i tem of the client. | |
591 HashMap<const DisplayItemClient*, size_t> oldChunkClients; | |
592 for (size_t i = oldChunk.beginIndex; i < oldChunk.endIndex; ++i) { | |
593 const DisplayItem& oldItem = m_currentPaintArtifact.getDisplayItemList() [i]; | |
594 if (oldItem.hasValidClient() && oldItem.drawsContent()) | |
595 oldChunkClients.add(&oldItem.client(), i); | |
596 } | |
597 | |
598 HashSet<const DisplayItemClient*> newChunkClients; | |
599 for (size_t i = newChunk.beginIndex; i < newChunk.endIndex; ++i) { | |
600 const DisplayItem& newItem = m_newDisplayItemList[i]; | |
601 if (newItem.drawsContent()) { | |
602 if (!newItem.client().isJustCreated() && newItem.client().getPaintIn validationReason() == PaintInvalidationNone) | |
chrishtr
2016/08/26 18:10:51
This is to check for cached items?
Xianzhu
2016/08/26 18:39:23
Yes. Changed to clientCacheIsValid(newItem.client(
| |
603 oldChunkClients.remove(&newItem.client()); | |
604 else | |
605 newChunkClients.add(&newItem.client()); | |
606 } | |
607 } | |
608 | |
609 // TODO(wangxianzhu): Handle PaintInvalidationIncremental and optimize paint offset change. | |
610 for (const DisplayItemClient* client : newChunkClients) | |
611 newChunk.rasterInvalidationRects.append(client->visualRect()); | |
612 for (const auto& oldChunkClientInfo : oldChunkClients) | |
613 newChunk.rasterInvalidationRects.append(m_currentPaintArtifact.getDispla yItemList().visualRect(oldChunkClientInfo.value)); | |
614 } | |
615 | |
520 #if DCHECK_IS_ON() | 616 #if DCHECK_IS_ON() |
521 | 617 |
522 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const | 618 void PaintController::showUnderInvalidationError(const char* reason, const Displ ayItem& newItem, const DisplayItem* oldItem) const |
523 { | 619 { |
524 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; | 620 LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason; |
525 #ifndef NDEBUG | 621 #ifndef NDEBUG |
526 LOG(ERROR) << "New display item: " << newItem.asDebugString(); | 622 LOG(ERROR) << "New display item: " << newItem.asDebugString(); |
527 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() : "None"); | 623 LOG(ERROR) << "Old display item: " << (oldItem ? oldItem->asDebugString() : "None"); |
528 #else | 624 #else |
529 LOG(ERROR) << "Run debug build to get more details."; | 625 LOG(ERROR) << "Run debug build to get more details."; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
611 return stringBuilder.toString(); | 707 return stringBuilder.toString(); |
612 } | 708 } |
613 | 709 |
614 void PaintController::showDebugData() const | 710 void PaintController::showDebugData() const |
615 { | 711 { |
616 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); | 712 WTFLogAlways("current display item list: [%s]\n", displayItemListAsDebugStri ng(m_currentPaintArtifact.getDisplayItemList()).utf8().data()); |
617 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data()); | 713 WTFLogAlways("new display item list: [%s]\n", displayItemListAsDebugString(m _newDisplayItemList).utf8().data()); |
618 } | 714 } |
619 | 715 |
620 } // namespace blink | 716 } // namespace blink |
OLD | NEW |