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

Unified Diff: Source/platform/graphics/paint/DisplayItemListTest.cpp

Issue 1294233004: Subtree caching implementation in blink-core (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Add a complex-subtree-update test Created 5 years, 4 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: Source/platform/graphics/paint/DisplayItemListTest.cpp
diff --git a/Source/platform/graphics/paint/DisplayItemListTest.cpp b/Source/platform/graphics/paint/DisplayItemListTest.cpp
index 59e7642e15a0df630c18a0e3f31dec68c67c752b..b4d9437e617a7834cb2568729ae9fd5d70dbbcab 100644
--- a/Source/platform/graphics/paint/DisplayItemListTest.cpp
+++ b/Source/platform/graphics/paint/DisplayItemListTest.cpp
@@ -12,11 +12,40 @@
#include "platform/graphics/paint/ClipRecorder.h"
#include "platform/graphics/paint/DrawingDisplayItem.h"
#include "platform/graphics/paint/DrawingRecorder.h"
-#include "platform/graphics/paint/SubtreeRecorder.h"
+#include "platform/graphics/paint/SubtreeDisplayItem.h"
#include <gtest/gtest.h>
namespace blink {
+class SimpleSubtreeRecorder {
+public:
+ static bool useCachedSubtreeIfPossible(DisplayItemList& displayItemList, const DisplayItemClientWrapper& client, int paintPhase)
+ {
+ if (displayItemList.subtreeCacheIsValid(client.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(paintPhase))) {
+ displayItemList.createAndAppend<CachedDisplayItem>(client, DisplayItem::paintPhaseToCachedSubtreeType(paintPhase));
+ return true;
+ }
+ return false;
+ }
+
+ SimpleSubtreeRecorder(DisplayItemList& displayItemList, const DisplayItemClientWrapper& client, int paintPhase)
+ : m_displayItemList(displayItemList)
+ , m_client(client)
+ , m_paintPhase(paintPhase)
+ {
+ displayItemList.createAndAppend<BeginSubtreeDisplayItem>(client, DisplayItem::paintPhaseToBeginSubtreeType(paintPhase));
+ }
+ ~SimpleSubtreeRecorder()
+ {
+ m_displayItemList.createAndAppend<EndSubtreeDisplayItem>(m_client, DisplayItem::paintPhaseToEndSubtreeType(m_paintPhase));
+ }
+
+private:
+ DisplayItemList& m_displayItemList;
+ const DisplayItemClientWrapper m_client;
+ const int m_paintPhase;
+};
+
class DisplayItemListTest : public ::testing::Test {
public:
DisplayItemListTest()
@@ -462,26 +491,22 @@ TEST_F(DisplayItemListTest, CachedSubtreeSwapOrder)
const int foregroundPaintPhase = foregroundDrawingType - DisplayItem::DrawingPaintPhaseFirst;
{
- SubtreeRecorder r(context, container1, backgroundPaintPhase);
- EXPECT_FALSE(r.canUseCache());
+ SimpleSubtreeRecorder r(displayItemList(), container1, backgroundPaintPhase);
drawRect(context, container1, backgroundDrawingType, FloatRect(100, 100, 100, 100));
drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200));
}
{
- SubtreeRecorder r(context, container1, foregroundPaintPhase);
- EXPECT_FALSE(r.canUseCache());
+ SimpleSubtreeRecorder r(displayItemList(), container1, foregroundPaintPhase);
drawRect(context, content1, foregroundDrawingType, FloatRect(100, 100, 50, 200));
drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
}
{
- SubtreeRecorder r(context, container2, backgroundPaintPhase);
- EXPECT_FALSE(r.canUseCache());
+ SimpleSubtreeRecorder r(displayItemList(), container2, backgroundPaintPhase);
drawRect(context, container2, backgroundDrawingType, FloatRect(100, 200, 100, 100));
drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
}
{
- SubtreeRecorder r(context, container2, foregroundPaintPhase);
- EXPECT_FALSE(r.canUseCache());
+ SimpleSubtreeRecorder r(displayItemList(), container2, foregroundPaintPhase);
drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
drawRect(context, container2, foregroundDrawingType, FloatRect(100, 200, 100, 100));
}
@@ -509,17 +534,17 @@ TEST_F(DisplayItemListTest, CachedSubtreeSwapOrder)
TestDisplayItem(container2, DisplayItem::paintPhaseToEndSubtreeType(foregroundPaintPhase)));
// Simulate the situation when container1 e.g. gets a z-index that is now greater than container2.
- displayItemList().createAndAppend<CachedDisplayItem>(container2, DisplayItem::paintPhaseToCachedSubtreeType(backgroundPaintPhase));
+ EXPECT_TRUE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), container2, backgroundPaintPhase));
EXPECT_EQ((size_t)1, newPaintListBeforeUpdate().size());
EXPECT_TRUE(newPaintListBeforeUpdate().last().isCachedSubtree());
- displayItemList().createAndAppend<CachedDisplayItem>(container2, DisplayItem::paintPhaseToCachedSubtreeType(foregroundPaintPhase));
+ EXPECT_TRUE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), container2, foregroundPaintPhase));
EXPECT_EQ((size_t)2, newPaintListBeforeUpdate().size());
EXPECT_TRUE(newPaintListBeforeUpdate().last().isCachedSubtree());
- displayItemList().createAndAppend<CachedDisplayItem>(container1, DisplayItem::paintPhaseToCachedSubtreeType(backgroundPaintPhase));
+ EXPECT_TRUE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), container1, backgroundPaintPhase));
EXPECT_EQ((size_t)3, newPaintListBeforeUpdate().size());
EXPECT_TRUE(newPaintListBeforeUpdate().last().isCachedSubtree());
- displayItemList().createAndAppend<CachedDisplayItem>(container1, DisplayItem::paintPhaseToCachedSubtreeType(foregroundPaintPhase));
+ EXPECT_TRUE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), container1, foregroundPaintPhase));
EXPECT_EQ((size_t)4, newPaintListBeforeUpdate().size());
EXPECT_TRUE(newPaintListBeforeUpdate().last().isCachedSubtree());
displayItemList().commitNewDisplayItems();
@@ -546,6 +571,108 @@ TEST_F(DisplayItemListTest, CachedSubtreeSwapOrder)
TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(foregroundDrawingType)));
}
+TEST_F(DisplayItemListTest, CachedNestedSubtreeUpdate)
+{
+ TestDisplayItemClient container1("container1");
+ TestDisplayItemClient content1("content1");
+ TestDisplayItemClient container2("container2");
+ TestDisplayItemClient content2("content2");
+ GraphicsContext context(&displayItemList());
+ const int backgroundPaintPhase = backgroundDrawingType - DisplayItem::DrawingPaintPhaseFirst;
+ const int foregroundPaintPhase = foregroundDrawingType - DisplayItem::DrawingPaintPhaseFirst;
+
+ {
+ SimpleSubtreeRecorder r(displayItemList(), container1, backgroundPaintPhase);
+ drawRect(context, container1, backgroundDrawingType, FloatRect(100, 100, 100, 100));
+ {
+ SimpleSubtreeRecorder r(displayItemList(), content1, backgroundPaintPhase);
+ drawRect(context, content1, backgroundDrawingType, FloatRect(100, 100, 50, 200));
+ }
+ }
+ {
+ SimpleSubtreeRecorder r(displayItemList(), container1, foregroundPaintPhase);
+ {
+ SimpleSubtreeRecorder r(displayItemList(), content1, foregroundPaintPhase);
+ drawRect(context, content1, foregroundDrawingType, FloatRect(100, 100, 50, 200));
+ }
+ drawRect(context, container1, foregroundDrawingType, FloatRect(100, 100, 100, 100));
+ }
+ {
+ SimpleSubtreeRecorder r(displayItemList(), container2, backgroundPaintPhase);
+ drawRect(context, container2, backgroundDrawingType, FloatRect(100, 200, 100, 100));
+ {
+ SimpleSubtreeRecorder r(displayItemList(), content2, backgroundPaintPhase);
+ drawRect(context, content2, backgroundDrawingType, FloatRect(100, 200, 50, 200));
+ }
+ }
+ displayItemList().commitNewDisplayItems();
+
+ EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 18,
+ TestDisplayItem(container1, DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(container1, backgroundDrawingType),
+ TestDisplayItem(content1, DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(content1, backgroundDrawingType),
+ TestDisplayItem(content1, DisplayItem::paintPhaseToEndSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(backgroundPaintPhase)),
+
+ TestDisplayItem(container1, DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)),
+ TestDisplayItem(content1, DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)),
+ TestDisplayItem(content1, foregroundDrawingType),
+ TestDisplayItem(content1, DisplayItem::paintPhaseToEndSubtreeType(foregroundPaintPhase)),
+ TestDisplayItem(container1, foregroundDrawingType),
+ TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(foregroundPaintPhase)),
+
+ TestDisplayItem(container2, DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(container2, backgroundDrawingType),
+ TestDisplayItem(content2, DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(content2, backgroundDrawingType),
+ TestDisplayItem(content2, DisplayItem::paintPhaseToEndSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(container2, DisplayItem::paintPhaseToEndSubtreeType(backgroundPaintPhase)));
+
+ // Container2 itself now becomes empty (but still has the 'content2' child), and chooses not to output subtree info.
+ displayItemList().invalidate(container2.displayItemClient());
+ displayItemList().invalidate(content2.displayItemClient());
+ EXPECT_FALSE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), container2, backgroundPaintPhase));
+ EXPECT_FALSE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), content2, backgroundPaintPhase));
+ // Content2 now outputs foreground.
+ EXPECT_FALSE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), content2, foregroundPaintPhase));
+ {
+ SimpleSubtreeRecorder r(displayItemList(), content2, foregroundPaintPhase);
+ drawRect(context, content2, foregroundDrawingType, FloatRect(100, 200, 50, 200));
+ }
+ EXPECT_EQ((size_t)3, newPaintListBeforeUpdate().size());
+
+ // Container1 subtree now uses cached background, but not cached foreground.
+ // The merge algorithm allows changing subtree without invalidating the displayItemClient.
+ EXPECT_TRUE(SimpleSubtreeRecorder::useCachedSubtreeIfPossible(displayItemList(), container1, backgroundPaintPhase));
+ EXPECT_EQ((size_t)4, newPaintListBeforeUpdate().size());
+ EXPECT_TRUE(newPaintListBeforeUpdate().last().isCachedSubtree());
+
+ displayItemList().commitNewDisplayItems();
+
+ EXPECT_DISPLAY_LIST(displayItemList().displayItems(), 9,
+ TestDisplayItem(content2, DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)),
+ TestDisplayItem(content2, foregroundDrawingType),
+ TestDisplayItem(content2, DisplayItem::paintPhaseToEndSubtreeType(foregroundPaintPhase)),
+
+ TestDisplayItem(container1, DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(container1, backgroundDrawingType),
+ TestDisplayItem(content1, DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(content1, backgroundDrawingType),
+ TestDisplayItem(content1, DisplayItem::paintPhaseToEndSubtreeType(backgroundPaintPhase)),
+ TestDisplayItem(container1, DisplayItem::paintPhaseToEndSubtreeType(backgroundPaintPhase)));
+
+ EXPECT_TRUE(displayItemList().subtreeCacheIsValid(container1.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)));
+ EXPECT_TRUE(displayItemList().subtreeCacheIsValid(content1.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)));
+ EXPECT_FALSE(displayItemList().subtreeCacheIsValid(container1.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)));
+ EXPECT_FALSE(displayItemList().subtreeCacheIsValid(content1.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)));
+
+ EXPECT_FALSE(displayItemList().subtreeCacheIsValid(container2.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)));
+ EXPECT_FALSE(displayItemList().subtreeCacheIsValid(content2.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(backgroundPaintPhase)));
+ EXPECT_FALSE(displayItemList().subtreeCacheIsValid(container2.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)));
+ EXPECT_TRUE(displayItemList().subtreeCacheIsValid(content2.displayItemClient(), DisplayItem::paintPhaseToBeginSubtreeType(foregroundPaintPhase)));
+}
+
TEST_F(DisplayItemListTest, Scope)
{
TestDisplayItemClient multicol("multicol");

Powered by Google App Engine
This is Rietveld 408576698