Reviewers: Stephen Chennney
CL:
https://codereview.chromium.org/2266103002/Message:
PTAL, this handles repainting when the background becomes no longer painted into
the scrolling contents layer.
Description:
Repaint when background switches painting from/to scrolling contents layer.
BUG=639886
TEST=paint/invalidation/composited-overflow-local-background-removed.html
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Base URL:
https://chromium.googlesource.com/chromium/src.git@masterAffected files (+37, -8 lines):
A + third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed.html
A third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed-expected.html
M third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
M third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
M third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
Index: third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed-expected.html
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed-expected.html
new file mode 100644
index 0000000000000000000000000000000000000000..89a57b207b990e351125143cd13bed2700afa5c3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed-expected.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<style>
+#scroller {
+ overflow: scroll;
+ width: 200px;
+ height: 200px;
+}
+
+.spacer {
+ height: 300px;
+}
+</style>
+<div id="scroller">
+ <div class="spacer"></div>
+</div>
Index: third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed.html
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background.html b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed.html
similarity index 72%
copy from third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background.html
copy to third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed.html
index 1f3dd06c2d6ad1ec10dff7363459d535f0858608..9c24e6ac6789840d058d8bae5e2027b603d29831 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background.html
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-local-background-removed.html
@@ -2,13 +2,12 @@
<script src="../../fast/repaint/resources/text-based-repaint.js"></script>
<script>
function repaintTest() {
- scroller.style.background = 'green local';
+ scroller.style.background = '';
}
onload = runRepaintAndPixelTest;
</script>
<style>
#scroller {
- background: red local;
overflow: scroll;
width: 200px;
height: 200px;
@@ -20,7 +19,7 @@ onload = runRepaintAndPixelTest;
}
</style>
<!-- #scroller has a locally attached background which will be painted into the
- scrolling contents layer. When the color changes it should repaint. -->
-<div id="scroller">
+ scrolling contents layer. When the color is removed it should be cleared. -->
+<div id="scroller" style="background: red local;">
<div class="spacer"></div>
</div>
Index: third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
index d83f1633504c0f04c338ede0370b2395be6c27fd..d52fa0529b284cb454a5617c79ef0793aa0f768a 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -434,7 +434,7 @@ void LayoutBoxModelObject::setBackingNeedsPaintInvalidationInRect(const LayoutRe
} else if (object.compositedScrollsWithRespectTo(*this)) {
layer()->compositedLayerMapping()->setScrollingContentsNeedDisplayInRect(r, invalidationReason, object);
} else if (usesCompositedScrolling()) {
- if (layer()->compositedLayerMapping()->shouldPaintBackgroundOntoScrollingContentsLayer()) {
+ if (layer()->compositedLayerMapping()->backgroundPaintsOntoScrollingContentsLayer()) {
// TODO(flackr): Get a correct rect in the context of the scrolling contents layer to update
// rather than updating the entire rect.
const LayoutRect& scrollingContentsRect = toLayoutBox(this)->layoutOverflowRect();
Index: third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
index c070f17b691aaa55202e27bd01b0c065aeb2c101..0e7f4cff92544fb4bd6c322bbb9369d3185b1af8 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -173,6 +173,7 @@ CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
, m_isMainFrameLayoutViewLayer(false)
, m_backgroundLayerPaintsFixedRootBackground(false)
, m_scrollingContentsAreEmpty(false)
+ , m_backgroundPaintsOntoScrollingContentsLayer(false)
{
if (layer.isRootLayer() && layoutObject()->frame()->isMainFrame())
m_isMainFrameLayoutViewLayer = true;
@@ -293,9 +294,15 @@ void CompositedLayerMapping::updateIsRootForIsolatedGroup()
m_graphicsLayer->setIsRootForIsolatedGroup(isolate);
}
+void CompositedLayerMapping::updateBackgroundPaintingLayer()
+{
+ bool backgroundLayerPaintsOntoScrollingContentsLayer = shouldPaintBackgroundOntoScrollingContentsLayer();
+ if (backgroundLayerPaintsOntoScrollingContentsLayer != m_backgroundPaintsOntoScrollingContentsLayer)
+ m_owningLayer.setNeedsRepaint();
+}
+
void CompositedLayerMapping::updateContentsOpaque()
{
- ASSERT(m_isMainFrameLayoutViewLayer || !m_backgroundLayer);
if (isAcceleratedCanvas(layoutObject())) {
// Determine whether the rendering context's external texture layer is opaque.
CanvasRenderingContext* context = toHTMLCanvasElement(layoutObject()->node())->renderingContext();
@@ -311,7 +318,7 @@ void CompositedLayerMapping::updateContentsOpaque()
} else {
// For non-root layers, background is painted by the scrolling contents layer if all backgrounds
// are background attachment local, otherwise background is painted by the primary graphics layer.
- if (hasScrollingLayer() && shouldPaintBackgroundOntoScrollingContentsLayer()) {
+ if (hasScrollingLayer() && m_backgroundPaintsOntoScrollingContentsLayer) {
// Backgrounds painted onto the foreground are clipped by the padding box rect.
// TODO(flackr): This should actually check the entire overflow rect within the
// scrolling contents layer but since we currently only trigger this for solid
@@ -768,6 +775,7 @@ void CompositedLayerMapping::updateGraphicsLayerGeometry(const PaintLayer* compo
updateBackgroundColor();
updateDrawsContent();
updateElementIdAndCompositorMutableProperties();
+ updateBackgroundPaintingLayer();
updateContentsOpaque();
updateAfterPartResize();
updateRenderingContext();
@@ -2460,7 +2468,7 @@ void CompositedLayerMapping::paintContents(const GraphicsLayer* graphicsLayer, G
|| graphicsLayer == m_childClippingMaskLayer.get()
|| graphicsLayer == m_scrollingContentsLayer.get()) {
- bool paintRootBackgroundOntoScrollingContentsLayer = shouldPaintBackgroundOntoScrollingContentsLayer();
+ bool paintRootBackgroundOntoScrollingContentsLayer = m_backgroundPaintsOntoScrollingContentsLayer;
DCHECK(!paintRootBackgroundOntoScrollingContentsLayer || (!m_backgroundLayer && !m_foregroundLayer));
if (paintRootBackgroundOntoScrollingContentsLayer) {
if (graphicsLayer == m_scrollingContentsLayer.get())
Index: third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
index bd7baaed155b2d2f464dc65f7a080baf4aa48cbb..6afcfbc014411007dc9d79d12102f1aae8dcc39f 100644
--- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
+++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -87,6 +87,9 @@ public:
bool updateGraphicsLayerConfiguration();
void updateGraphicsLayerGeometry(const PaintLayer* compositingContainer, const PaintLayer* compositingStackingContext, Vector<PaintLayer*>& layersNeedingPaintInvalidation);
+ // Update whether background paints onto scrolling contents layer.
+ void updateBackgroundPaintingLayer();
+
// Update whether layer needs blending.
void updateContentsOpaque();
@@ -223,6 +226,7 @@ public:
// opaque this allows us to composite the scroller even on low DPI as we can
// draw with subpixel anti-aliasing.
bool shouldPaintBackgroundOntoScrollingContentsLayer() const;
+ bool backgroundPaintsOntoScrollingContentsLayer() { return m_backgroundPaintsOntoScrollingContentsLayer; }
private:
IntRect recomputeInterestRect(const GraphicsLayer*) const;
@@ -461,6 +465,9 @@ private:
unsigned m_backgroundLayerPaintsFixedRootBackground : 1;
unsigned m_scrollingContentsAreEmpty : 1;
+ // Keep track of whether the background is painted onto the scrolling contents layer for invalidations.
+ unsigned m_backgroundPaintsOntoScrollingContentsLayer : 1;
+
friend class CompositedLayerMappingTest;
};