Skip to content
Permalink
Browse files
Unpainted area while scrolling in Reader is white
https://bugs.webkit.org/show_bug.cgi?id=186541
<rdar://problem/40471363>

Reviewed by Timothy Hatcher.

Source/WebCore:

New test: tiled-drawing/simple-document-with-dynamic-background-color.html

For platforms that do not use the overhang layer, we depend on
RenderView's background color to fill unpainted space.

RenderView's background color is only updated inside updateRootLayerConfiguration,
and it is possible with a simple enough page to change the document's
background color without running that code.

* page/FrameView.cpp:
(WebCore::FrameView::setTransparent):
(WebCore::FrameView::setBaseBackgroundColor):
Make use of the newly added rootBackgroundColorOrTransparencyChanged.

(WebCore::FrameView::calculateExtendedBackgroundMode const):
Update a comment, since the function it mentioned is no longer.

(WebCore::FrameView::updateTilesForExtendedBackgroundMode):
Remove this code that clears the root extended background color
if using tiles to extend in both directions. Two reasons:
1) it seems harmless to also have a root extended background color
2) this just gets clobbered by the call in RenderView::paintBoxDecorations

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateCompositingLayers):
Add a bit that will do a updateConfiguration() on the root layer if no
other work needs to be done, so that we can update the root layer's
transparency or background color without doing a full layer rebuild.

(WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
Make use of the newly added rootBackgroundColorOrTransparencyChanged.

(WebCore::RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged):
Change rootBackgroundTransparencyChanged to also cover color changes.
Fold setRootExtendedBackgroundColor in here, and make use of
setRootLayerConfigurationNeedsUpdate() instead of doing a full rebuild.
Previously, we would bail if the transparency state hadn't changed;
now, we'll also update the root layer's background color and the
exposed-to-WebKit extended background color if they change too.

(WebCore::RenderLayerCompositor::rootBackgroundTransparencyChanged): Deleted.
(WebCore::RenderLayerCompositor::setRootExtendedBackgroundColor): Deleted.

* rendering/RenderLayerCompositor.h:
Add setRootLayerConfigurationNeedsUpdate, remove setRootExtendedBackgroundColor,
and add both a bit indicating that the root layer configuration needs updating
and the cached view background color to make the early return in
rootBackgroundColorOrTransparencyChanged possible.

* rendering/RenderView.cpp:
(WebCore::RenderView::paintBoxDecorations):
Make use of the newly added rootBackgroundColorOrTransparencyChanged.

LayoutTests:

* tiled-drawing/background-transparency-toggle-expected.txt:
This is a progression; the extended background color now matches the color
of the page at this point (#CCCCCC is the specified body background, black
with 0.2 alpha, blended with the root's white background).

* tiled-drawing/simple-document-with-dynamic-background-color-expected.txt: Added.
* tiled-drawing/simple-document-with-dynamic-background-color.html: Added.
Added a test that ensures that dynamically changing the background color
actually applies to the RenderView background. Previously, the second layer
tree dump would have a black background where it should be red.


Canonical link: https://commits.webkit.org/202091@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232991 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
hortont424 committed Jun 19, 2018
1 parent 75961ba commit 3af4f32c194e1d513b652076ccc20da7a4c5e731
Showing 9 changed files with 194 additions and 45 deletions.
@@ -1,3 +1,22 @@
2018-06-19 Tim Horton <timothy_horton@apple.com>

Unpainted area while scrolling in Reader is white
https://bugs.webkit.org/show_bug.cgi?id=186541
<rdar://problem/40471363>

Reviewed by Timothy Hatcher.

* tiled-drawing/background-transparency-toggle-expected.txt:
This is a progression; the extended background color now matches the color
of the page at this point (#CCCCCC is the specified body background, black
with 0.2 alpha, blended with the root's white background).

* tiled-drawing/simple-document-with-dynamic-background-color-expected.txt: Added.
* tiled-drawing/simple-document-with-dynamic-background-color.html: Added.
Added a test that ensures that dynamically changing the background color
actually applies to the RenderView background. Previously, the second layer
tree dump would have a black background where it should be red.

2018-06-19 Michael Catanzaro <mcatanzaro@igalia.com>

Unreviewed, revert some bad gardening.
@@ -49,6 +49,7 @@ Page tiles should be transparent if the body's background has alpha.
(GraphicsLayer
(bounds 785.00 1024.00)
(contentsOpaque 1)
(backgroundColor #CCCCCC)
(tile cache coverage 0, 0 785 x 1024)
(tile size 785 x 512)
(top left tile 0, 0 tiles grid 1 x 2)
@@ -0,0 +1,33 @@
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(backgroundColor #000000)
(tile cache coverage 0, 0 800 x 600)
(tile size 800 x 600)
(top left tile 0, 0 tiles grid 1 x 1)
(in window 1)
)
)
)


(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(backgroundColor #FF0000)
(tile cache coverage 0, 0 800 x 600)
(tile size 800 x 600)
(top left tile 0, 0 tiles grid 1 x 1)
(in window 1)
)
)
)

@@ -0,0 +1,35 @@
<!DOCTYPE html>

<html>
<head>
<script>
if (window.testRunner) {
testRunner.dumpAsText();
testRunner.waitUntilDone();
}

function doTest()
{
if (!window.internals)
return;

document.body.style.backgroundColor = "black";

// The RenderView's background color should be black.
document.getElementById('layers').innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES) + "\n\n";

document.body.style.backgroundColor = "red";

// The RenderView's background color should be red.
document.getElementById('layers').innerText += internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES);

testRunner.notifyDone();
}
window.addEventListener('load', doTest, false);
</script>
</head>

<body>
<pre id="layers">Layer tree goes here</p>
</body>
</html>
@@ -1,3 +1,64 @@
2018-06-19 Tim Horton <timothy_horton@apple.com>

Unpainted area while scrolling in Reader is white
https://bugs.webkit.org/show_bug.cgi?id=186541
<rdar://problem/40471363>

Reviewed by Timothy Hatcher.

New test: tiled-drawing/simple-document-with-dynamic-background-color.html

For platforms that do not use the overhang layer, we depend on
RenderView's background color to fill unpainted space.

RenderView's background color is only updated inside updateRootLayerConfiguration,
and it is possible with a simple enough page to change the document's
background color without running that code.

* page/FrameView.cpp:
(WebCore::FrameView::setTransparent):
(WebCore::FrameView::setBaseBackgroundColor):
Make use of the newly added rootBackgroundColorOrTransparencyChanged.

(WebCore::FrameView::calculateExtendedBackgroundMode const):
Update a comment, since the function it mentioned is no longer.

(WebCore::FrameView::updateTilesForExtendedBackgroundMode):
Remove this code that clears the root extended background color
if using tiles to extend in both directions. Two reasons:
1) it seems harmless to also have a root extended background color
2) this just gets clobbered by the call in RenderView::paintBoxDecorations

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateCompositingLayers):
Add a bit that will do a updateConfiguration() on the root layer if no
other work needs to be done, so that we can update the root layer's
transparency or background color without doing a full layer rebuild.

(WebCore::RenderLayerCompositor::rootOrBodyStyleChanged):
Make use of the newly added rootBackgroundColorOrTransparencyChanged.

(WebCore::RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged):
Change rootBackgroundTransparencyChanged to also cover color changes.
Fold setRootExtendedBackgroundColor in here, and make use of
setRootLayerConfigurationNeedsUpdate() instead of doing a full rebuild.
Previously, we would bail if the transparency state hadn't changed;
now, we'll also update the root layer's background color and the
exposed-to-WebKit extended background color if they change too.

(WebCore::RenderLayerCompositor::rootBackgroundTransparencyChanged): Deleted.
(WebCore::RenderLayerCompositor::setRootExtendedBackgroundColor): Deleted.

* rendering/RenderLayerCompositor.h:
Add setRootLayerConfigurationNeedsUpdate, remove setRootExtendedBackgroundColor,
and add both a bit indicating that the root layer configuration needs updating
and the cached view background color to make the early return in
rootBackgroundColorOrTransparencyChanged possible.

* rendering/RenderView.cpp:
(WebCore::RenderView::paintBoxDecorations):
Make use of the newly added rootBackgroundColorOrTransparencyChanged.

2018-06-19 Youenn Fablet <youenn@apple.com>

Need to properly handle removal of worker in SWServer::unregisterServiceWorkerClient timer lambda
@@ -2896,7 +2896,7 @@ void FrameView::setTransparent(bool isTransparent)
if (!isViewForDocumentInFrame())
return;

renderView()->compositor().rootBackgroundTransparencyChanged();
renderView()->compositor().rootBackgroundColorOrTransparencyChanged();
setNeedsLayout();
}

@@ -2912,21 +2912,15 @@ Color FrameView::baseBackgroundColor() const

void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
{
bool wasOpaque = m_baseBackgroundColor.isOpaque();

if (!backgroundColor.isValid())
m_baseBackgroundColor = Color::white;
else
m_baseBackgroundColor = backgroundColor;
m_baseBackgroundColor = backgroundColor.isValid() ? backgroundColor : Color::white;

if (!isViewForDocumentInFrame())
return;

recalculateScrollbarOverlayStyle();
setNeedsLayout();

if (m_baseBackgroundColor.isOpaque() != wasOpaque)
renderView()->compositor().rootBackgroundTransparencyChanged();
renderView()->compositor().rootBackgroundColorOrTransparencyChanged();
}

void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
@@ -2970,7 +2964,7 @@ FrameView::ExtendedBackgroundMode FrameView::calculateExtendedBackgroundMode() c

// Just because Settings::backgroundShouldExtendBeyondPage() is true does not necessarily mean
// that the background rect needs to be extended for painting. Simple backgrounds can be extended
// just with RenderLayerCompositor::setRootExtendedBackgroundColor(). More complicated backgrounds,
// just with RenderLayerCompositor's rootExtendedBackgroundColor. More complicated backgrounds,
// such as images, require extending the background rect to continue painting into the extended
// region. This function finds out if it is necessary to extend the background rect for painting.

@@ -3024,7 +3018,6 @@ void FrameView::updateTilesForExtendedBackgroundMode(ExtendedBackgroundMode mode
if (existingMode == mode)
return;

renderView->compositor().setRootExtendedBackgroundColor(mode == ExtendedBackgroundModeAll ? Color() : documentBackgroundColor());
backing->setTiledBackingHasMargins(mode & ExtendedBackgroundModeHorizontal, mode & ExtendedBackgroundModeVertical);
}

@@ -669,6 +669,7 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update

bool checkForHierarchyUpdate = m_reevaluateCompositingAfterLayout;
bool needGeometryUpdate = false;
bool needRootLayerConfigurationUpdate = m_rootLayerConfigurationNeedsUpdate;

switch (updateType) {
case CompositingUpdateType::AfterStyleChange:
@@ -683,14 +684,15 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
break;
}

if (!checkForHierarchyUpdate && !needGeometryUpdate)
if (!checkForHierarchyUpdate && !needGeometryUpdate && !needRootLayerConfigurationUpdate)
return false;

bool needHierarchyUpdate = m_compositingLayersNeedRebuild;
bool isFullUpdate = !updateRoot;

// Only clear the flag if we're updating the entire hierarchy.
m_compositingLayersNeedRebuild = false;
m_rootLayerConfigurationNeedsUpdate = false;
updateRoot = &rootRenderLayer();

if (isFullUpdate && updateType == CompositingUpdateType::AfterLayout)
@@ -752,7 +754,8 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
// most of the time, geometry is updated via RenderLayer::styleChanged().
updateLayerTreeGeometry(*updateRoot, 0);
ASSERT(!isFullUpdate || !m_subframeScrollLayersNeedReattach);
}
} else if (needRootLayerConfigurationUpdate)
m_renderView.layer()->backing()->updateConfiguration();

#if !LOG_DISABLED
if (compositingLogEnabled() && isFullUpdate && (needHierarchyUpdate || needGeometryUpdate)) {
@@ -3106,7 +3109,7 @@ void RenderLayerCompositor::rootOrBodyStyleChanged(RenderElement& renderer, cons
oldBackgroundColor = oldStyle->visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor);

if (oldBackgroundColor != renderer.style().visitedDependentColorWithColorFilter(CSSPropertyBackgroundColor))
rootBackgroundTransparencyChanged();
rootBackgroundColorOrTransparencyChanged();

bool hadFixedBackground = oldStyle && oldStyle->hasEntirelyFixedBackground();
if (hadFixedBackground != renderer.style().hasEntirelyFixedBackground()) {
@@ -3115,42 +3118,44 @@ void RenderLayerCompositor::rootOrBodyStyleChanged(RenderElement& renderer, cons
}
}

void RenderLayerCompositor::rootBackgroundTransparencyChanged()
void RenderLayerCompositor::rootBackgroundColorOrTransparencyChanged()
{
if (!inCompositingMode())
return;

bool isTransparent = viewHasTransparentBackground();
Color backgroundColor;
bool isTransparent = viewHasTransparentBackground(&backgroundColor);

Color extendedBackgroundColor = m_renderView.settings().backgroundShouldExtendBeyondPage() ? backgroundColor : Color();

bool transparencyChanged = m_viewBackgroundIsTransparent != isTransparent;
bool backgroundColorChanged = m_viewBackgroundColor != backgroundColor;
bool extendedBackgroundColorChanged = m_rootExtendedBackgroundColor != extendedBackgroundColor;

LOG(Compositing, "RenderLayerCompositor %p rootBackgroundTransparencyChanged. isTransparent=%d, changed=%d", this, isTransparent, m_viewBackgroundIsTransparent != isTransparent);
if (m_viewBackgroundIsTransparent == isTransparent)
LOG(Compositing, "RenderLayerCompositor %p rootBackgroundColorOrTransparencyChanged. isTransparent=%d, transparencyChanged=%d, backgroundColorChanged=%d, extendedBackgroundColorChanged=%d", this, isTransparent, transparencyChanged, backgroundColorChanged, extendedBackgroundColorChanged);
if (!transparencyChanged && !backgroundColorChanged && !extendedBackgroundColorChanged)
return;

m_viewBackgroundIsTransparent = isTransparent;

// FIXME: We should do something less expensive than a full layer rebuild.
setCompositingLayersNeedRebuild();
scheduleCompositingLayerUpdate();
}

void RenderLayerCompositor::setRootExtendedBackgroundColor(const Color& color)
{
if (color == m_rootExtendedBackgroundColor)
return;

m_rootExtendedBackgroundColor = color;

page().chrome().client().pageExtendedBackgroundColorDidChange(color);

m_viewBackgroundColor = backgroundColor;
m_rootExtendedBackgroundColor = extendedBackgroundColor;

if (extendedBackgroundColorChanged) {
page().chrome().client().pageExtendedBackgroundColorDidChange(m_rootExtendedBackgroundColor);

#if ENABLE(RUBBER_BANDING)
if (!m_layerForOverhangAreas)
return;

m_layerForOverhangAreas->setBackgroundColor(m_rootExtendedBackgroundColor);

if (!m_rootExtendedBackgroundColor.isValid())
m_layerForOverhangAreas->setCustomAppearance(GraphicsLayer::ScrollingOverhang);
if (!m_layerForOverhangAreas)
return;
m_layerForOverhangAreas->setBackgroundColor(m_rootExtendedBackgroundColor);
if (!m_rootExtendedBackgroundColor.isValid())
m_layerForOverhangAreas->setCustomAppearance(GraphicsLayer::ScrollingOverhang);
#endif
}

setRootLayerConfigurationNeedsUpdate();
scheduleCompositingLayerUpdate();
}

void RenderLayerCompositor::updateOverflowControlsLayers()
@@ -165,7 +165,7 @@ class RenderLayerCompositor final : public GraphicsLayerClient, public GraphicsL
void rootOrBodyStyleChanged(RenderElement&, const RenderStyle* oldStyle);

// Called after the view transparency, or the document or base background color change.
void rootBackgroundTransparencyChanged();
void rootBackgroundColorOrTransparencyChanged();

// Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
void repaintOnCompositingChange(RenderLayer&);
@@ -313,7 +313,6 @@ class RenderLayerCompositor final : public GraphicsLayerClient, public GraphicsL

void didPaintBacking(RenderLayerBacking*);

void setRootExtendedBackgroundColor(const Color&);
const Color& rootExtendedBackgroundColor() const { return m_rootExtendedBackgroundColor; }

void updateRootContentLayerClipping();
@@ -481,6 +480,8 @@ class RenderLayerCompositor final : public GraphicsLayerClient, public GraphicsL

bool documentUsesTiledBacking() const;
bool isMainFrameCompositor() const;

void setRootLayerConfigurationNeedsUpdate() { m_rootLayerConfigurationNeedsUpdate = true; }

private:
RenderView& m_renderView;
@@ -501,6 +502,7 @@ class RenderLayerCompositor final : public GraphicsLayerClient, public GraphicsL

bool m_compositing { false };
bool m_compositingLayersNeedRebuild { false };
bool m_rootLayerConfigurationNeedsUpdate { false };
bool m_flushingLayers { false };
bool m_shouldFlushOnReattach { false };
bool m_forceCompositingMode { false };
@@ -561,6 +563,7 @@ class RenderLayerCompositor final : public GraphicsLayerClient, public GraphicsL
double m_secondaryBackingStoreBytes { 0 };
#endif

Color m_viewBackgroundColor;
Color m_rootExtendedBackgroundColor;

HashMap<ScrollingNodeID, RenderLayer*> m_scrollingNodeToLayerMap;
@@ -454,8 +454,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
rootObscuresBackground = rendererObscuresBackground(*rootRenderer);
}

bool backgroundShouldExtendBeyondPage = settings().backgroundShouldExtendBeyondPage();
compositor().setRootExtendedBackgroundColor(backgroundShouldExtendBeyondPage ? frameView().documentBackgroundColor() : Color());
compositor().rootBackgroundColorOrTransparencyChanged();

Page* page = document().page();
float pageScaleFactor = page ? page->pageScaleFactor() : 1;
@@ -474,7 +473,7 @@ void RenderView::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint&)
frameView().setCannotBlitToWindow(); // The parent must show behind the child.
else {
const Color& documentBackgroundColor = frameView().documentBackgroundColor();
const Color& backgroundColor = (backgroundShouldExtendBeyondPage && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView().baseBackgroundColor();
const Color& backgroundColor = (settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView().baseBackgroundColor();
if (backgroundColor.isVisible()) {
CompositeOperator previousOperator = paintInfo.context().compositeOperation();
paintInfo.context().setCompositeOperation(CompositeCopy);

0 comments on commit 3af4f32

Please sign in to comment.