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

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

Issue 2114653003: New PaintController under-invalidation checking (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@CommitOnTheWay
Patch Set: Fix subsequence Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
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 24e041f2dfa42c8fd87ee2decc2415e96c99bd86..0b991a0f1a9d607a2138e4eb964405306ab9d636 100644
--- a/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
+++ b/third_party/WebKit/Source/platform/graphics/paint/PaintController.cpp
@@ -41,11 +41,12 @@ bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client
if (!clientCacheIsValid(client))
return false;
-#if ENABLE(ASSERT)
- // When under-invalidation checking is enabled, we output CachedDrawing display item
- // followed by the display item containing forced painting.
- if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
+#if DCHECK_IS_ON()
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) {
+ // We are checking under-invalidation of a subsequence enclosing this display item.
+ // Let the client continue to actually paint the display item.
return false;
+ }
#endif
DisplayItemList::iterator cachedItem = findCachedItem(DisplayItem::Id(client, type));
@@ -56,13 +57,27 @@ bool PaintController::useCachedDrawingIfPossible(const DisplayItemClient& client
++m_numCachedNewItems;
ensureNewDisplayItemListInitialCapacity();
- processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem));
+ if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
+ processNewItem(m_newDisplayItemList.appendByMoving(*cachedItem));
m_nextItemToMatch = cachedItem + 1;
// Items before m_nextItemToMatch have been copied so we don't need to index them.
if (m_nextItemToMatch - m_nextItemToIndex > 0)
m_nextItemToIndex = m_nextItemToMatch;
+#if DCHECK_IS_ON()
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
+ if (!isCheckingUnderInvalidation()) {
+ m_underInvalidationCheckingBegin = cachedItem;
+ m_underInvalidationCheckingEnd = cachedItem + 1;
+ m_underInvalidationMessagePrefix = "";
+ }
+ // Return false to let the painter actually paint, and we will check if the new painting
+ // is the same as the cached.
+ return false;
+ }
+#endif
+
return true;
}
@@ -81,11 +96,13 @@ bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl
if (!clientCacheIsValid(client))
return false;
-#if ENABLE(ASSERT)
- // When under-invalidation checking is enabled, we output CachedDrawing display item
- // followed by the display item containing forced painting.
- if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
+#if DCHECK_IS_ON()
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled() && isCheckingUnderInvalidation()) {
+ // We are checking under-invalidation of an ancestor subsequence enclosing this one.
+ // The ancestor subsequence is supposed to have already "copied", so we should let the
+ // client continue to actually paint the descendant subsequences without "copying".
return false;
+ }
#endif
DisplayItemList::iterator cachedItem = findCachedItem(DisplayItem::Id(client, DisplayItem::Subsequence));
@@ -103,6 +120,14 @@ bool PaintController::useCachedSubsequenceIfPossible(const DisplayItemClient& cl
if (cachedItem - m_nextItemToIndex > 0)
m_nextItemToIndex = cachedItem;
+#if DCHECK_IS_ON()
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
+ // Return false to let the painter actually paint, and we will check if the new painting
+ // is the same as the cached.
+ return false;
+ }
+#endif
+
return true;
}
@@ -185,6 +210,9 @@ void PaintController::processNewItem(DisplayItem& displayItem)
NOTREACHED();
}
addItemToIndexIfNeeded(displayItem, m_newDisplayItemList.size() - 1, m_newDisplayItemIndicesByClient);
+
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
+ checkUnderInvalidation();
#endif // DCHECK_IS_ON()
if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
@@ -313,11 +341,27 @@ DisplayItemList::iterator PaintController::findOutOfOrderCachedItemForward(const
return end;
}
+// Copies a cached subsequence from current list to the new list.
// On return, |it| points to the item after the EndSubsequence item of the subsequence.
+// When paintUnderInvaldiationCheckingEnabled() we'll not actually copy the subsequence,
+// but mark the begin and end of the subsequence for under-invalidation checking.
void PaintController::copyCachedSubsequence(DisplayItemList::iterator& it)
{
+#if DCHECK_IS_ON()
DCHECK(it->getType() == DisplayItem::Subsequence);
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
+ DCHECK(!isCheckingUnderInvalidation());
+ m_underInvalidationCheckingBegin = it;
+#ifndef NDEBUG
+ m_underInvalidationMessagePrefix = "(In CachedSubsequence of " + it->clientDebugString() + ")";
+#else
+ m_underInvalidationMessagePrefix = "(In CachedSubsequence)";
+#endif
+ }
+#endif
+
DisplayItem::Id endSubsequenceId(it->client(), DisplayItem::EndSubsequence);
+ bool metEndSubsequence = false;
do {
// We should always find the EndSubsequence display item.
DCHECK(it != m_currentPaintArtifact.getDisplayItemList().end());
@@ -326,9 +370,19 @@ void PaintController::copyCachedSubsequence(DisplayItemList::iterator& it)
CHECK(it->client().isAlive());
#endif
++m_numCachedNewItems;
- processNewItem(m_newDisplayItemList.appendByMoving(*it));
+ if (it->getId() == endSubsequenceId)
+ metEndSubsequence = true;
+ if (!DCHECK_IS_ON() || !RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
+ processNewItem(m_newDisplayItemList.appendByMoving(*it));
++it;
- } while (endSubsequenceId != m_newDisplayItemList.last().getId());
+ } while (!metEndSubsequence);
+
+#if DCHECK_IS_ON()
+ if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
+ m_underInvalidationCheckingEnd = it;
+ DCHECK(isCheckingUnderInvalidation());
+ }
+#endif
}
static IntRect visualRectForDisplayItem(const DisplayItem& displayItem, const LayoutSize& offsetFromLayoutObject)
@@ -342,6 +396,10 @@ void PaintController::resetCurrentListIterators()
{
m_nextItemToMatch = m_currentPaintArtifact.getDisplayItemList().begin();
m_nextItemToIndex = m_nextItemToMatch;
+#if DCHECK_IS_ON()
+ m_underInvalidationCheckingBegin = m_currentPaintArtifact.getDisplayItemList().end();
+ m_underInvalidationCheckingEnd = m_currentPaintArtifact.getDisplayItemList().begin();
+#endif
}
void PaintController::commitNewDisplayItems(const LayoutSize& offsetFromLayoutObject)
@@ -428,91 +486,47 @@ void PaintController::appendDebugDrawingAfterCommit(const DisplayItemClient& dis
resetCurrentListIterators();
}
-#if 0 // DCHECK_IS_ON()
-// TODO(wangxianzhu): Fix under-invalidation checking for the new caching method.
+#if DCHECK_IS_ON()
-void PaintController::checkUnderInvalidation(DisplayItemList::iterator& newIt, DisplayItemList::iterator& currentIt)
+void PaintController::showUnderInvalidationError(const char* reason, const DisplayItem& newItem, const DisplayItem& oldItem) const
{
- DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled());
-
- // When under-invalidation-checking is enabled, the forced painting is following the cached display item.
- DisplayItem::Type nextItemType = DisplayItem::nonCachedType(newIt->getType());
- ++newIt;
- DCHECK(newIt->getType() == nextItemType);
-
- if (newIt->isDrawing()) {
- checkCachedDisplayItemIsUnchanged("", *newIt, *currentIt);
- return;
- }
-
- DCHECK(newIt->getType() == DisplayItem::Subsequence);
-
+ LOG(ERROR) << m_underInvalidationMessagePrefix << " " << reason;
#ifndef NDEBUG
- CString messagePrefix = String::format("(In CachedSubsequence of %s)", newIt->clientDebugString().utf8().data()).utf8();
+ LOG(ERROR) << "New display item: " << newItem.asDebugString();
+ LOG(ERROR) << "Old display item: " << oldItem.asDebugString();
#else
- CString messagePrefix = "(In CachedSubsequence)";
+ LOG(ERROR) << "Run debug build to get more details.";
#endif
+ LOG(ERROR) << "See http://crbug.com/619103.";
- DisplayItem::Id endSubsequenceId(newIt->client(), DisplayItem::EndSubsequence);
- while (true) {
- DCHECK(newIt != m_newDisplayItemList.end());
- if (newIt->isCached())
- checkUnderInvalidation(newIt, currentIt);
- else
- checkCachedDisplayItemIsUnchanged(messagePrefix.data(), *newIt, *currentIt);
-
- if (endSubsequenceId.matches(*newIt))
- break;
-
- ++newIt;
- ++currentIt;
- }
-}
-
-static void showUnderInvalidationError(const char* messagePrefix, const char* reason, const DisplayItem* newItem, const DisplayItem* oldItem)
-{
#ifndef NDEBUG
- WTFLogAlways("%s %s:\nNew display item: %s\nOld display item: %s\nSee http://crbug.com/450725.", messagePrefix, reason,
- newItem ? newItem->asDebugString().utf8().data() : "None",
- oldItem ? oldItem->asDebugString().utf8().data() : "None");
-#else
- WTFLogAlways("%s %s. Run debug build to get more details\nSee http://crbug.com/450725.", messagePrefix, reason);
+ if (newItem.isDrawing()) {
+ RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(newItem).picture();
+ RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(oldItem).picture();
+ LOG(INFO) << "new picture:\n" << (newPicture ? pictureAsDebugString(newPicture.get()) : "None");
+ LOG(INFO) << "old picture:\n" << (oldPicture ? pictureAsDebugString(oldPicture.get()) : "None");
+ }
#endif // NDEBUG
}
-void PaintController::checkCachedDisplayItemIsUnchanged(const char* messagePrefix, const DisplayItem& newItem, const DisplayItem& oldItem)
+void PaintController::checkUnderInvalidation()
{
DCHECK(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled());
- DCHECK(!newItem.isCached());
- DCHECK(!oldItem.isCached());
- if (newItem.skippedCache()) {
- showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: skipped-cache in cached subsequence", &newItem, &oldItem);
- NOTREACHED();
- }
+ if (!isCheckingUnderInvalidation())
+ return;
+
+ const DisplayItem& newItem = m_newDisplayItemList.last();
+ const DisplayItem& oldItem = *m_underInvalidationCheckingBegin++;
if (newItem.isCacheable() && !clientCacheIsValid(newItem.client())) {
- showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: invalidated in cached subsequence", &newItem, &oldItem);
+ showUnderInvalidationError("under-invalidation of PaintLayer: invalidated in cached subsequence", newItem, oldItem);
NOTREACHED();
}
-
- if (newItem.equals(oldItem))
- return;
-
- showUnderInvalidationError(messagePrefix, "ERROR: under-invalidation: display item changed", &newItem, &oldItem);
-
-#ifndef NDEBUG
- if (newItem.isDrawing()) {
- RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>(newItem).picture();
- RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>(oldItem).picture();
- String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture.get()) : "None";
- String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture.get()) : "None";
- WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data());
- WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data());
+ if (!newItem.equals(oldItem)) {
+ showUnderInvalidationError("under-invalidation: display item changed", newItem, oldItem);
+ NOTREACHED();
}
-#endif // NDEBUG
-
- NOTREACHED();
}
#endif // DCHECK_IS_ON()
@@ -533,10 +547,12 @@ String PaintController::displayItemListAsDebugString(const DisplayItemList& list
stringBuilder.append(", cacheIsValid: ");
stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" : "false");
}
- IntRect visualRect = list.visualRect(i);
- stringBuilder.append(String::format(", visualRect: [%d,%d %dx%d]",
- visualRect.x(), visualRect.y(),
- visualRect.width(), visualRect.height()));
+ if (list.hasVisualRect(i)) {
+ IntRect visualRect = list.visualRect(i);
+ stringBuilder.append(String::format(", visualRect: [%d,%d %dx%d]",
+ visualRect.x(), visualRect.y(),
+ visualRect.width(), visualRect.height()));
+ }
stringBuilder.append('}');
}
return stringBuilder.toString();

Powered by Google App Engine
This is Rietveld 408576698