Commit 962c6b28 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Commit Bot

[PE] Fix performance issue in PaintController::FindOutOfOrderCachedItemForward()

I missed update of next_item_to_index_, causing cached items after
next_item_to_index_ to be added into index repeatedly for each new
valid item inserted.

(This is not a new regression but exposed by crrev.com/571251 in more
cases especially during upward composited scrolling when display items
newly appearing in the new interest rect are inserted in front of other
cached items. Before that CL the newly appearing display items were
treated as not cached because of their cache generation mismatching
the paint controller's. After that CL we call
FindOutOfOrderCachedItemForward().)

Bug: 873511
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I17bc3ee55ad678f968ac8d9904fbc6a9b087407f
Reviewed-on: https://chromium-review.googlesource.com/1173405Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582929}
parent ecc52c96
......@@ -387,6 +387,7 @@ size_t PaintController::FindOutOfOrderCachedItemForward(
++num_indexed_items_;
#endif
AddToIndicesByClientMap(item.Client(), i, out_of_order_item_indices_);
next_item_to_index_ = i + 1;
}
}
......
......@@ -1527,6 +1527,81 @@ TEST_P(PaintControllerTest, InvalidateAll) {
EXPECT_TRUE(GetPaintController().CacheIsAllInvalid());
}
TEST_P(PaintControllerTest, InsertValidItemInFront) {
FakeDisplayItemClient first("first", LayoutRect(100, 100, 300, 300));
FakeDisplayItemClient second("second", LayoutRect(100, 100, 200, 200));
FakeDisplayItemClient third("third", LayoutRect(100, 100, 100, 100));
FakeDisplayItemClient fourth("fourth", LayoutRect(100, 100, 50, 50));
GraphicsContext context(GetPaintController());
InitRootChunk();
DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 300, 300));
DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
DrawRect(context, third, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, fourth, kBackgroundType, FloatRect(100, 100, 50, 50));
EXPECT_EQ(0, NumCachedNewItems());
CommitAndFinishCycle();
EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 4,
TestDisplayItem(first, kBackgroundType),
TestDisplayItem(second, kBackgroundType),
TestDisplayItem(third, kBackgroundType),
TestDisplayItem(fourth, kBackgroundType));
EXPECT_TRUE(first.IsValid());
EXPECT_TRUE(second.IsValid());
EXPECT_TRUE(third.IsValid());
EXPECT_TRUE(fourth.IsValid());
// Simulate that a composited scrolling element is scrolled down, and "first"
// and "second" are scrolled out of the interest rect.
InitRootChunk();
DrawRect(context, third, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, fourth, kBackgroundType, FloatRect(100, 100, 50, 50));
EXPECT_EQ(2, NumCachedNewItems());
#if DCHECK_IS_ON()
EXPECT_EQ(2, NumSequentialMatches());
EXPECT_EQ(0, NumOutOfOrderMatches());
// We indexed "first" and "second" when finding the cached item for "third".
EXPECT_EQ(2, NumIndexedItems());
#endif
CommitAndFinishCycle();
EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 2,
TestDisplayItem(third, kBackgroundType),
TestDisplayItem(fourth, kBackgroundType));
EXPECT_TRUE(first.IsValid());
EXPECT_TRUE(second.IsValid());
EXPECT_TRUE(third.IsValid());
EXPECT_TRUE(fourth.IsValid());
// Simulate "first" and "second" are scrolled back into the interest rect.
InitRootChunk();
DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 300, 300));
DrawRect(context, second, kBackgroundType, FloatRect(100, 100, 200, 200));
DrawRect(context, third, kBackgroundType, FloatRect(100, 100, 100, 100));
DrawRect(context, fourth, kBackgroundType, FloatRect(100, 100, 50, 50));
EXPECT_EQ(2, NumCachedNewItems());
#if DCHECK_IS_ON()
EXPECT_EQ(2, NumSequentialMatches());
EXPECT_EQ(0, NumOutOfOrderMatches());
// We indexed "third" and "fourth" when finding the cached item for "first".
EXPECT_EQ(2, NumIndexedItems());
#endif
CommitAndFinishCycle();
EXPECT_DISPLAY_LIST(GetPaintController().GetDisplayItemList(), 4,
TestDisplayItem(first, kBackgroundType),
TestDisplayItem(second, kBackgroundType),
TestDisplayItem(third, kBackgroundType),
TestDisplayItem(fourth, kBackgroundType));
EXPECT_TRUE(first.IsValid());
EXPECT_TRUE(second.IsValid());
EXPECT_TRUE(third.IsValid());
EXPECT_TRUE(fourth.IsValid());
}
// Death tests don't work properly on Android.
#if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
......
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