Fix assertion failure during out-of-order matching

The assertion failure occurs in the following sequence:
- Out-of-order matching to n-th item;
- Synchronized matching to (n+m)-th item;
- Out-of-order matching to (n-k)-th item;
- Out-of-order matching to (n+m+l)-th.

The problem is that we only update nextItemToIndex during out-of-order
matching, but not during synchronized matching, causing we tried to
index already copied items (n to n+m).

BUG=526590
TEST=DisplayItemListTest.OutOfOrderNoCrash

Review URL: https://codereview.chromium.org/1307653007

git-svn-id: svn://svn.chromium.org/blink/trunk@201684 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 774733f0
...@@ -244,7 +244,7 @@ struct DisplayItemList::OutOfOrderIndexContext { ...@@ -244,7 +244,7 @@ struct DisplayItemList::OutOfOrderIndexContext {
DisplayItemIndicesByClientMap displayItemIndicesByClient; DisplayItemIndicesByClientMap displayItemIndicesByClient;
}; };
DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::iterator currentIt, const DisplayItem::Id& id, OutOfOrderIndexContext& context) DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(const DisplayItem::Id& id, OutOfOrderIndexContext& context)
{ {
ASSERT(clientCacheIsValid(id.client)); ASSERT(clientCacheIsValid(id.client));
...@@ -252,16 +252,12 @@ DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::i ...@@ -252,16 +252,12 @@ DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::i
if (foundIndex != kNotFound) if (foundIndex != kNotFound)
return m_currentDisplayItems.begin() + foundIndex; return m_currentDisplayItems.begin() + foundIndex;
return findOutOfOrderCachedItemForward(currentIt, id, context); return findOutOfOrderCachedItemForward(id, context);
} }
// Find forward for the item and index all skipped indexable items. // Find forward for the item and index all skipped indexable items.
DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(DisplayItems::iterator currentIt, const DisplayItem::Id& id, OutOfOrderIndexContext& context) DisplayItems::iterator DisplayItemList::findOutOfOrderCachedItemForward(const DisplayItem::Id& id, OutOfOrderIndexContext& context)
{ {
// Items before currentIt should have been copied. Skip indexing of them.
if (currentIt - context.nextItemToIndex > 0)
context.nextItemToIndex = currentIt;
DisplayItems::iterator currentEnd = m_currentDisplayItems.end(); DisplayItems::iterator currentEnd = m_currentDisplayItems.end();
for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) { for (; context.nextItemToIndex != currentEnd; ++context.nextItemToIndex) {
const DisplayItem& item = *context.nextItemToIndex; const DisplayItem& item = *context.nextItemToIndex;
...@@ -367,7 +363,7 @@ void DisplayItemList::commitNewDisplayItems(DisplayListDiff*) ...@@ -367,7 +363,7 @@ void DisplayItemList::commitNewDisplayItems(DisplayListDiff*)
ASSERT(newDisplayItem.isCached()); ASSERT(newDisplayItem.isCached());
ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && !paintOffsetWasInvalidated(newDisplayItem.client()))); ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && !paintOffsetWasInvalidated(newDisplayItem.client())));
if (!isSynchronized) { if (!isSynchronized) {
currentIt = findOutOfOrderCachedItem(currentIt, newDisplayItemId, outOfOrderIndexContext); currentIt = findOutOfOrderCachedItem(newDisplayItemId, outOfOrderIndexContext);
if (currentIt == currentEnd) { if (currentIt == currentEnd) {
#ifndef NDEBUG #ifndef NDEBUG
...@@ -406,6 +402,9 @@ void DisplayItemList::commitNewDisplayItems(DisplayListDiff*) ...@@ -406,6 +402,9 @@ void DisplayItemList::commitNewDisplayItems(DisplayListDiff*)
if (isSynchronized) if (isSynchronized)
++currentIt; ++currentIt;
} }
// Items before currentIt should have been copied so we don't need to index them.
if (currentIt - outOfOrderIndexContext.nextItemToIndex > 0)
outOfOrderIndexContext.nextItemToIndex = currentIt;
} }
#if ENABLE(ASSERT) #if ENABLE(ASSERT)
......
...@@ -178,8 +178,8 @@ private: ...@@ -178,8 +178,8 @@ private:
static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, DisplayItemIndicesByClientMap&); static void addItemToIndexIfNeeded(const DisplayItem&, size_t index, DisplayItemIndicesByClientMap&);
struct OutOfOrderIndexContext; struct OutOfOrderIndexContext;
DisplayItems::iterator findOutOfOrderCachedItem(DisplayItems::iterator currentIt, const DisplayItem::Id&, OutOfOrderIndexContext&); DisplayItems::iterator findOutOfOrderCachedItem(const DisplayItem::Id&, OutOfOrderIndexContext&);
DisplayItems::iterator findOutOfOrderCachedItemForward(DisplayItems::iterator currentIt, const DisplayItem::Id&, OutOfOrderIndexContext&); DisplayItems::iterator findOutOfOrderCachedItemForward(const DisplayItem::Id&, OutOfOrderIndexContext&);
void copyCachedSubsequence(DisplayItems::iterator& currentIt, DisplayItems& updatedList); void copyCachedSubsequence(DisplayItems::iterator& currentIt, DisplayItems& updatedList);
#if ENABLE(ASSERT) #if ENABLE(ASSERT)
......
...@@ -516,6 +516,31 @@ TEST_F(DisplayItemListTest, CachedSubsequenceSwapOrder) ...@@ -516,6 +516,31 @@ TEST_F(DisplayItemListTest, CachedSubsequenceSwapOrder)
TestDisplayItem(container1, DisplayItem::EndSubsequence)); TestDisplayItem(container1, DisplayItem::EndSubsequence));
} }
TEST_F(DisplayItemListTest, OutOfOrderNoCrash)
{
TestDisplayItemClient client("client");
GraphicsContext context(&displayItemList());
const DisplayItem::Type type1 = DisplayItem::DrawingFirst;
const DisplayItem::Type type2 = static_cast<DisplayItem::Type>(DisplayItem::DrawingFirst + 1);
const DisplayItem::Type type3 = static_cast<DisplayItem::Type>(DisplayItem::DrawingFirst + 2);
const DisplayItem::Type type4 = static_cast<DisplayItem::Type>(DisplayItem::DrawingFirst + 3);
drawRect(context, client, type1, FloatRect(100, 100, 100, 100));
drawRect(context, client, type2, FloatRect(100, 100, 50, 200));
drawRect(context, client, type3, FloatRect(100, 100, 50, 200));
drawRect(context, client, type4, FloatRect(100, 100, 100, 100));
displayItemList().commitNewDisplayItems();
drawRect(context, client, type2, FloatRect(100, 100, 50, 200));
drawRect(context, client, type3, FloatRect(100, 100, 50, 200));
drawRect(context, client, type1, FloatRect(100, 100, 100, 100));
drawRect(context, client, type4, FloatRect(100, 100, 100, 100));
displayItemList().commitNewDisplayItems();
}
TEST_F(DisplayItemListTest, CachedNestedSubsequenceUpdate) TEST_F(DisplayItemListTest, CachedNestedSubsequenceUpdate)
{ {
TestDisplayItemClient container1("container1"); TestDisplayItemClient container1("container1");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment