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(); |
} |