blob: 5b8c64a5af35f2eee45f3292db8307fc08108840 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "core/layout/compositing/CompositedLayerMapping.h"
#include "core/paint/PaintControllerPaintTest.h"
#include "platform/graphics/GraphicsContext.h"
namespace blink {
class PaintLayerPainterTest
: public PaintControllerPaintTest
, public testing::WithParamInterface<FrameSettingOverrideFunction> {
USING_FAST_MALLOC(PaintLayerPainterTest);
public:
FrameSettingOverrideFunction settingOverrider() const override { return GetParam(); }
};
INSTANTIATE_TEST_CASE_P(All, PaintLayerPainterTest, ::testing::Values(
nullptr,
RootLayerScrollsFrameSettingOverride));
TEST_P(PaintLayerPainterTest, CachedSubsequence)
{
RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(true);
setBodyInnerHTML(
"<div id='container1' style='position: relative; z-index: 1; width: 200px; height: 200px; background-color: blue'>"
" <div id='content1' style='position: absolute; width: 100px; height: 100px; background-color: red'></div>"
"</div>"
"<div id='container2' style='position: relative; z-index: 1; width: 200px; height: 200px; background-color: blue'>"
" <div id='content2' style='position: absolute; width: 100px; height: 100px; background-color: green'></div>"
"</div>");
document().view()->updateAllLifecyclePhases();
bool rootLayerScrolls = document().frame()->settings()->rootLayerScrolls();
PaintLayer& rootLayer = *layoutView().layer();
PaintLayer& htmlLayer = *toLayoutBoxModelObject(document().documentElement()->layoutObject())->layer();
LayoutObject& container1 = *document().getElementById("container1")->layoutObject();
PaintLayer& container1Layer = *toLayoutBoxModelObject(container1).layer();
LayoutObject& content1 = *document().getElementById("content1")->layoutObject();
LayoutObject& container2 = *document().getElementById("container2")->layoutObject();
PaintLayer& container2Layer = *toLayoutBoxModelObject(container2).layer();
LayoutObject& content2 = *document().getElementById("content2")->layoutObject();
if (rootLayerScrolls) {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 7,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2, backgroundType),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
} else {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 13,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
TestDisplayItem(container1Layer, DisplayItem::Subsequence),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
TestDisplayItem(container2Layer, DisplayItem::Subsequence),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2, backgroundType),
TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
}
toHTMLElement(content1.node())->setAttribute(HTMLNames::styleAttr, "position: absolute; width: 100px; height: 100px; background-color: green");
updateLifecyclePhasesBeforePaint();
paint();
if (rootLayerScrolls) {
EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 7,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), cachedBackgroundType),
TestDisplayItem(container1, cachedBackgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container2, cachedBackgroundType),
TestDisplayItem(content2, cachedBackgroundType),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
} else {
EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 10,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), cachedBackgroundType),
TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
TestDisplayItem(container1Layer, DisplayItem::Subsequence),
TestDisplayItem(container1, cachedBackgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
TestDisplayItem(container2Layer, DisplayItem::CachedSubsequence),
TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
}
commit();
if (rootLayerScrolls) {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 7,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2, backgroundType),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
} else {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 13,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
TestDisplayItem(container1Layer, DisplayItem::Subsequence),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
TestDisplayItem(container2Layer, DisplayItem::Subsequence),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2, backgroundType),
TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
}
}
TEST_P(PaintLayerPainterTest, CachedSubsequenceOnInterestRectChange)
{
RuntimeEnabledFeatures::setSlimmingPaintSynchronizedPaintingEnabled(true);
setBodyInnerHTML(
"<div id='container1' style='position: relative; z-index: 1; width: 200px; height: 200px; background-color: blue'>"
" <div id='content1' style='position: absolute; width: 100px; height: 100px; background-color: green'></div>"
"</div>"
"<div id='container2' style='position: relative; z-index: 1; width: 200px; height: 200px; background-color: blue'>"
" <div id='content2a' style='position: absolute; width: 100px; height: 100px; background-color: green'></div>"
" <div id='content2b' style='position: absolute; top: 200px; width: 100px; height: 100px; background-color: green'></div>"
"</div>"
"<div id='container3' style='position: absolute; z-index: 2; left: 300px; top: 0; width: 200px; height: 200px; background-color: blue'>"
" <div id='content3' style='position: absolute; width: 200px; height: 200px; background-color: green'></div>"
"</div>");
rootPaintController().invalidateAll();
bool rootLayerScrolls = document().frame()->settings()->rootLayerScrolls();
PaintLayer& rootLayer = *layoutView().layer();
PaintLayer& htmlLayer = *toLayoutBoxModelObject(document().documentElement()->layoutObject())->layer();
LayoutObject& container1 = *document().getElementById("container1")->layoutObject();
PaintLayer& container1Layer = *toLayoutBoxModelObject(container1).layer();
LayoutObject& content1 = *document().getElementById("content1")->layoutObject();
LayoutObject& container2 = *document().getElementById("container2")->layoutObject();
PaintLayer& container2Layer = *toLayoutBoxModelObject(container2).layer();
LayoutObject& content2a = *document().getElementById("content2a")->layoutObject();
LayoutObject& content2b = *document().getElementById("content2b")->layoutObject();
LayoutObject& container3 = *document().getElementById("container3")->layoutObject();
PaintLayer& container3Layer = *toLayoutBoxModelObject(container3).layer();
LayoutObject& content3 = *document().getElementById("content3")->layoutObject();
updateLifecyclePhasesBeforePaint();
IntRect interestRect(0, 0, 400, 300);
paint(&interestRect);
commit();
// Container1 is fully in the interest rect;
// Container2 is partly (including its stacking chidren) in the interest rect;
// Content2b is out of the interest rect and output nothing;
// Container3 is partly in the interest rect.
if (rootLayerScrolls) {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 9,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2a, backgroundType),
TestDisplayItem(container3, backgroundType),
TestDisplayItem(content3, backgroundType),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
} else {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 17,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
TestDisplayItem(container1Layer, DisplayItem::Subsequence),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
TestDisplayItem(container2Layer, DisplayItem::Subsequence),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2a, backgroundType),
TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
TestDisplayItem(container3Layer, DisplayItem::Subsequence),
TestDisplayItem(container3, backgroundType),
TestDisplayItem(content3, backgroundType),
TestDisplayItem(container3Layer, DisplayItem::EndSubsequence),
TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
}
updateLifecyclePhasesBeforePaint();
IntRect newInterestRect(0, 100, 300, 1000);
paint(&newInterestRect);
// Container1 becomes partly in the interest rect, but uses cached subsequence
// because it was fully painted before;
// Container2's intersection with the interest rect changes;
// Content2b is out of the interest rect and outputs nothing;
// Container3 becomes out of the interest rect and outputs nothing.
if (rootLayerScrolls) {
EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 8,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), cachedBackgroundType),
TestDisplayItem(container1, cachedBackgroundType),
TestDisplayItem(content1, cachedBackgroundType),
TestDisplayItem(container2, cachedBackgroundType),
TestDisplayItem(content2a, cachedBackgroundType),
TestDisplayItem(content2b, backgroundType),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
} else {
EXPECT_DISPLAY_LIST(rootPaintController().newDisplayItemList(), 11,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), cachedBackgroundType),
TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
TestDisplayItem(container1Layer, DisplayItem::CachedSubsequence),
TestDisplayItem(container2Layer, DisplayItem::Subsequence),
TestDisplayItem(container2, cachedBackgroundType),
TestDisplayItem(content2a, cachedBackgroundType),
TestDisplayItem(content2b, backgroundType),
TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
}
commit();
if (rootLayerScrolls) {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 8,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2a, backgroundType),
TestDisplayItem(content2b, backgroundType),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
} else {
EXPECT_DISPLAY_LIST(rootPaintController().displayItemList(), 14,
TestDisplayItem(rootLayer, DisplayItem::Subsequence),
TestDisplayItem(layoutView(), backgroundType),
TestDisplayItem(htmlLayer, DisplayItem::Subsequence),
TestDisplayItem(container1Layer, DisplayItem::Subsequence),
TestDisplayItem(container1, backgroundType),
TestDisplayItem(content1, backgroundType),
TestDisplayItem(container1Layer, DisplayItem::EndSubsequence),
TestDisplayItem(container2Layer, DisplayItem::Subsequence),
TestDisplayItem(container2, backgroundType),
TestDisplayItem(content2a, backgroundType),
TestDisplayItem(content2b, backgroundType),
TestDisplayItem(container2Layer, DisplayItem::EndSubsequence),
TestDisplayItem(htmlLayer, DisplayItem::EndSubsequence),
TestDisplayItem(rootLayer, DisplayItem::EndSubsequence));
}
}
} // namespace blink