| Index: third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
|
| index af1afd999974fb4c4a2a73a9c2141852d1bd0e0a..ea460b37c45f65eb686156fdf467fcde8a019ff4 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
|
| @@ -138,8 +138,9 @@
|
| void PaintController::invalidateUntracked(const DisplayItemClient& client)
|
| {
|
| // This can be called during painting, but we can't invalidate already painted clients.
|
| - client.setDisplayItemsUncached();
|
| ASSERT(!m_newDisplayItemIndicesByClient.contains(&client));
|
| + updateValidlyCachedClientsIfNeeded();
|
| + m_validlyCachedClients.remove(&client);
|
| }
|
|
|
| void PaintController::invalidateAll()
|
| @@ -147,7 +148,8 @@
|
| // Can only be called during layout/paintInvalidation, not during painting.
|
| ASSERT(m_newDisplayItemList.isEmpty());
|
| m_currentPaintArtifact.reset();
|
| - m_currentCacheGeneration.invalidate();
|
| + m_validlyCachedClients.clear();
|
| + m_validlyCachedClientsDirty = false;
|
|
|
| if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_trackedPaintInvalidationObjects)
|
| m_trackedPaintInvalidationObjects->append("##ALL##");
|
| @@ -155,10 +157,10 @@
|
|
|
| bool PaintController::clientCacheIsValid(const DisplayItemClient& client) const
|
| {
|
| - ASSERT(DisplayItemClient::isAlive(client));
|
| if (skippingCache())
|
| return false;
|
| - return client.displayItemsAreCached(m_currentCacheGeneration);
|
| + updateValidlyCachedClientsIfNeeded();
|
| + return m_validlyCachedClients.contains(&client);
|
| }
|
|
|
| void PaintController::invalidatePaintOffset(const DisplayItemClient& client)
|
| @@ -234,10 +236,12 @@
|
| for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) {
|
| const DisplayItem& item = *context.nextItemToIndex;
|
| ASSERT(item.hasValidClient());
|
| - if (id.matches(item))
|
| - return context.nextItemToIndex++;
|
| - if (item.isCacheable())
|
| + if (item.isCacheable() && clientCacheIsValid(item.client())) {
|
| + if (id.matches(item))
|
| + return context.nextItemToIndex++;
|
| +
|
| addItemToIndexIfNeeded(item, context.nextItemToIndex - m_currentPaintArtifact.getDisplayItemList().begin(), context.displayItemIndicesByClient);
|
| + }
|
| }
|
| return currentEnd;
|
| }
|
| @@ -292,6 +296,9 @@
|
| "num_non_cached_new_items", (int)m_newDisplayItemList.size() - m_numCachedNewItems);
|
| m_numCachedNewItems = 0;
|
|
|
| + if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
|
| + m_clientsCheckedPaintInvalidation.clear();
|
| +
|
| // These data structures are used during painting only.
|
| ASSERT(m_scopeStack.isEmpty());
|
| m_scopeStack.clear();
|
| @@ -313,9 +320,11 @@
|
|
|
| m_currentPaintArtifact = PaintArtifact(std::move(m_newDisplayItemList), m_newPaintChunks.releasePaintChunks());
|
| m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBytes);
|
| - updateCacheGeneration();
|
| + m_validlyCachedClientsDirty = true;
|
| return;
|
| }
|
| +
|
| + updateValidlyCachedClientsIfNeeded();
|
|
|
| // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched
|
| // by CachedDisplayItems during synchronized matching. The indexed items will be matched
|
| @@ -394,7 +403,7 @@
|
| m_currentPaintArtifact = PaintArtifact(std::move(updatedList), m_newPaintChunks.releasePaintChunks());
|
|
|
| m_newDisplayItemList = DisplayItemList(kInitialDisplayItemListCapacityBytes);
|
| - updateCacheGeneration();
|
| + m_validlyCachedClientsDirty = true;
|
| }
|
|
|
| size_t PaintController::approximateUnsharedMemoryUsage() const
|
| @@ -422,12 +431,22 @@
|
| return memoryUsage;
|
| }
|
|
|
| -void PaintController::updateCacheGeneration()
|
| -{
|
| - m_currentCacheGeneration = DisplayItemCacheGeneration::next();
|
| +void PaintController::updateValidlyCachedClientsIfNeeded() const
|
| +{
|
| + if (!m_validlyCachedClientsDirty)
|
| + return;
|
| +
|
| + m_validlyCachedClients.clear();
|
| + m_validlyCachedClientsDirty = false;
|
| +
|
| + const DisplayItemClient* lastAddedClient = nullptr;
|
| for (const DisplayItem& displayItem : m_currentPaintArtifact.getDisplayItemList()) {
|
| - if (displayItem.isCacheable())
|
| - displayItem.client().setDisplayItemsCached(m_currentCacheGeneration);
|
| + if (&displayItem.client() == lastAddedClient)
|
| + continue;
|
| + if (displayItem.isCacheable()) {
|
| + lastAddedClient = &displayItem.client();
|
| + m_validlyCachedClients.add(lastAddedClient);
|
| + }
|
| }
|
| }
|
|
|
| @@ -494,7 +513,7 @@
|
| ASSERT_NOT_REACHED();
|
| }
|
|
|
| - if (newItem.isCacheable() && !clientCacheIsValid(newItem.client())) {
|
| + if (newItem.isCacheable() && !m_validlyCachedClients.contains(&newItem.client())) {
|
| showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: invalidated in cached subsequence", &newItem, &oldItem);
|
| ASSERT_NOT_REACHED();
|
| }
|
|
|