Title: [183775] trunk
Revision
183775
Author
[email protected]
Date
2015-05-04 15:53:10 -0700 (Mon, 04 May 2015)

Log Message

Fix updating of tiled backing opaquenss when the page background color changes
https://bugs.webkit.org/show_bug.cgi?id=144600
rdar://problem/20723035

Reviewed by Tim Horton.

Source/WebCore:

RenderLayerCompositor makes the page tiles opaque or not based on the result of
viewHasTransparentBackground(), which consults the view transparency, and
FrameView::documentBackgroundColor(). documentBackgroundColor() in turn is based
on the root and/or body background colors.

We thus need to re-evaluate whether page tiles are opaque when any of these inputs
change, but were failing to do so for the FrameView's baseBackgroundColor, and
the page root background color.

Fix by having FrameView::setBaseBackgroundColor(), and RenderBox::styleDidChange()
(for the root) trigger a compositing update when necessary.

Added setViewBaseBackgroundColor() on Internals for testing.

Test: platform/mac-wk2/tiled-drawing/background-transparency-toggle.html

* page/FrameView.cpp:
(WebCore::FrameView::setTransparent): Use the isViewForDocumentInFrame() helper.
(WebCore::FrameView::setBaseBackgroundColor): Bail if we're not the view for the
frame's document, and trigger a compositing update check if the alpha changed.
(WebCore::FrameView::isViewForDocumentInFrame): Helper that checks to see if
this FrameView is associated with the Document being displayed in the FrameView's
Frame. This returns false when we're setting up a new FrameView (its Frame still
points to the old document, so renderView() returns the RenderView for the Frame's
existing Document).
* page/FrameView.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::styleDidChange): Have the compositor check to see if it needs
to do an update.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::rootBackgroundTransparencyChanged): If the result
of documentBackgroundColor() changed in alpha since the last time, trigger a compositing
update.
* rendering/RenderLayerCompositor.h:
* testing/Internals.cpp:
(WebCore::Internals::setViewBaseBackgroundColor):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

Test that dumps layers with various baseBackgroundColor and body background color
combinations.

* platform/mac-wk2/tiled-drawing/background-transparency-toggle-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/background-transparency-toggle.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (183774 => 183775)


--- trunk/LayoutTests/ChangeLog	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/LayoutTests/ChangeLog	2015-05-04 22:53:10 UTC (rev 183775)
@@ -1,3 +1,17 @@
+2015-05-04  Simon Fraser  <[email protected]>
+
+        Fix updating of tiled backing opaquenss when the page background color changes
+        https://bugs.webkit.org/show_bug.cgi?id=144600
+        rdar://problem/20723035
+
+        Reviewed by Tim Horton.
+
+        Test that dumps layers with various baseBackgroundColor and body background color
+        combinations.
+
+        * platform/mac-wk2/tiled-drawing/background-transparency-toggle-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/background-transparency-toggle.html: Added.
+
 2015-05-04  Ryosuke Niwa  <[email protected]>
 
         Fix the test after r183758 since shouldNotBe is not supported in the standalone testing.

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/background-transparency-toggle-expected.txt (0 => 183775)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/background-transparency-toggle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/background-transparency-toggle-expected.txt	2015-05-04 22:53:10 UTC (rev 183775)
@@ -0,0 +1,56 @@
+Page tiles should be transparent if the body's background has alpha.
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (tile cache coverage 0, 0 800 x 600)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
+    )
+  )
+)
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (backgroundColor #00000033)
+      (tile cache coverage 0, 0 800 x 600)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
+    )
+  )
+)
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (tile cache coverage 0, 0 800 x 600)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
+    )
+  )
+)
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 785.00 648.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 785.00 648.00)
+      (contentsOpaque 1)
+      (backgroundColor #CCCCCC)
+      (tile cache coverage 0, 0 785 x 648)
+      (tile size 512 x 512)
+      (top left tile 0, 0 tiles grid 2 x 2)
+    )
+  )
+)
+

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/background-transparency-toggle.html (0 => 183775)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/background-transparency-toggle.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/background-transparency-toggle.html	2015-05-04 22:53:10 UTC (rev 183775)
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            background-color: white;
+        }
+        
+        body.transparent {
+            background-color: rgba(0, 0, 0, 0.2);
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function documentLoaded()
+        {
+            window.setTimeout(doTest, 0);
+        }
+        
+        function appendLayerDump()
+        {
+            if (window.internals)
+                document.getElementById('output').textContent += window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_TILE_CACHES);
+        }
+
+        function doTest()
+        {
+            if (window.internals)
+                internals.setViewBaseBackgroundColor('transparent');
+            appendLayerDump();
+
+            document.body.classList.add('transparent');
+            appendLayerDump();
+
+            document.body.classList.remove('transparent');
+            appendLayerDump();
+
+            if (window.internals)
+                internals.setViewBaseBackgroundColor('white');
+
+            document.body.classList.add('transparent');
+            appendLayerDump();
+
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+
+        window.addEventListener('load', documentLoaded, false);
+    </script>
+</head>
+<body>
+
+<p>Page tiles should be transparent if the body's background has alpha.</p>
+<div id="test"></div>
+<pre id="output"></pre>
+
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (183774 => 183775)


--- trunk/Source/WebCore/ChangeLog	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/ChangeLog	2015-05-04 22:53:10 UTC (rev 183775)
@@ -1,3 +1,50 @@
+2015-05-04  Simon Fraser  <[email protected]>
+
+        Fix updating of tiled backing opaquenss when the page background color changes
+        https://bugs.webkit.org/show_bug.cgi?id=144600
+        rdar://problem/20723035
+
+        Reviewed by Tim Horton.
+
+        RenderLayerCompositor makes the page tiles opaque or not based on the result of
+        viewHasTransparentBackground(), which consults the view transparency, and
+        FrameView::documentBackgroundColor(). documentBackgroundColor() in turn is based
+        on the root and/or body background colors.
+
+        We thus need to re-evaluate whether page tiles are opaque when any of these inputs
+        change, but were failing to do so for the FrameView's baseBackgroundColor, and
+        the page root background color.
+        
+        Fix by having FrameView::setBaseBackgroundColor(), and RenderBox::styleDidChange()
+        (for the root) trigger a compositing update when necessary.
+
+        Added setViewBaseBackgroundColor() on Internals for testing.
+
+        Test: platform/mac-wk2/tiled-drawing/background-transparency-toggle.html
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setTransparent): Use the isViewForDocumentInFrame() helper.
+        (WebCore::FrameView::setBaseBackgroundColor): Bail if we're not the view for the 
+        frame's document, and trigger a compositing update check if the alpha changed.
+        (WebCore::FrameView::isViewForDocumentInFrame): Helper that checks to see if
+        this FrameView is associated with the Document being displayed in the FrameView's
+        Frame. This returns false when we're setting up a new FrameView (its Frame still
+        points to the old document, so renderView() returns the RenderView for the Frame's
+        existing Document).
+        * page/FrameView.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::styleDidChange): Have the compositor check to see if it needs
+        to do an update.
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::rootBackgroundTransparencyChanged): If the result
+        of documentBackgroundColor() changed in alpha since the last time, trigger a compositing
+        update.
+        * rendering/RenderLayerCompositor.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::setViewBaseBackgroundColor):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2015-05-04  Jer Noble  <[email protected]>
 
         [iOS] Crash in -[WebCALayerHostWrapper resolveBounds]

Modified: trunk/Source/WebCore/page/FrameView.cpp (183774 => 183775)


--- trunk/Source/WebCore/page/FrameView.cpp	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/page/FrameView.cpp	2015-05-04 22:53:10 UTC (rev 183775)
@@ -2678,20 +2678,14 @@
 
     m_isTransparent = isTransparent;
 
-    RenderView* renderView = this->renderView();
-    if (!renderView)
-        return;
-
     // setTransparent can be called in the window between FrameView initialization
     // and switching in the new Document; this means that the RenderView that we
     // retrieve is actually attached to the previous Document, which is going away,
     // and must not update compositing layers.
-    if (&renderView->frameView() != this)
+    if (!isViewForDocumentInFrame())
         return;
 
-    RenderLayerCompositor& compositor = renderView->compositor();
-    compositor.setCompositingLayersNeedRebuild();
-    compositor.scheduleCompositingLayerUpdate();
+    renderView()->compositor().rootBackgroundTransparencyChanged();
 }
 
 bool FrameView::hasOpaqueBackground() const
@@ -2706,12 +2700,20 @@
 
 void FrameView::setBaseBackgroundColor(const Color& backgroundColor)
 {
+    bool hadAlpha = m_baseBackgroundColor.hasAlpha();
+    
     if (!backgroundColor.isValid())
         m_baseBackgroundColor = Color::white;
     else
         m_baseBackgroundColor = backgroundColor;
 
+    if (!isViewForDocumentInFrame())
+        return;
+
     recalculateScrollbarOverlayStyle();
+
+    if (m_baseBackgroundColor.hasAlpha() != hadAlpha)
+        renderView()->compositor().rootBackgroundTransparencyChanged();
 }
 
 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
@@ -4110,6 +4112,15 @@
     adjustTiledBackingCoverage();
 }
 
+bool FrameView::isViewForDocumentInFrame() const
+{
+    RenderView* renderView = this->renderView();
+    if (!renderView)
+        return false;
+
+    return &renderView->frameView() == this;
+}
+
 void FrameView::enableAutoSizeMode(bool enable, const IntSize& minSize, const IntSize& maxSize)
 {
     ASSERT(!enable || !minSize.isEmpty());

Modified: trunk/Source/WebCore/page/FrameView.h (183774 => 183775)


--- trunk/Source/WebCore/page/FrameView.h	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/page/FrameView.h	2015-05-04 22:53:10 UTC (rev 183775)
@@ -648,6 +648,7 @@
     bool isFrameFlatteningValidForThisFrame() const;
 
     bool qualifiesAsVisuallyNonEmpty() const;
+    bool isViewForDocumentInFrame() const;
 
     AXObjectCache* axObjectCache() const;
     void notifyWidgetsInAllFrames(WidgetNotification);

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (183774 => 183775)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2015-05-04 22:53:10 UTC (rev 183775)
@@ -425,6 +425,9 @@
         
         if (rootStyleChanged && is<RenderBlockFlow>(rootRenderer) && downcast<RenderBlockFlow>(*rootRenderer).multiColumnFlowThread())
             downcast<RenderBlockFlow>(*rootRenderer).updateStylesForColumnChildren();
+
+        if (diff != StyleDifferenceEqual)
+            view().compositor().rootBackgroundTransparencyChanged();
     }
 
 #if ENABLE(CSS_SHAPES)

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (183774 => 183775)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2015-05-04 22:53:10 UTC (rev 183775)
@@ -3214,6 +3214,17 @@
     return documentBackgroundColor.hasAlpha();
 }
 
+void RenderLayerCompositor::rootBackgroundTransparencyChanged()
+{
+    Color documentBackgroundColor = m_renderView.frameView().documentBackgroundColor();
+    if (m_lastDocumentBackgroundColor.isValid() && documentBackgroundColor.hasAlpha() == m_lastDocumentBackgroundColor.hasAlpha())
+        return;
+
+    // FIXME: We should do something less expensive than a full layer rebuild.
+    setCompositingLayersNeedRebuild();
+    scheduleCompositingLayerUpdate();
+}
+
 void RenderLayerCompositor::setRootExtendedBackgroundColor(const Color& color)
 {
     if (color == m_rootExtendedBackgroundColor)

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (183774 => 183775)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2015-05-04 22:53:10 UTC (rev 183775)
@@ -165,6 +165,9 @@
     bool needsFixedRootBackgroundLayer(const RenderLayer&) const;
     GraphicsLayer* fixedRootBackgroundLayer() const;
     
+    // Called after the view transparency, or the document or base background color change.
+    void rootBackgroundTransparencyChanged();
+    
     // Repaint the appropriate layers when the given RenderLayer starts or stops being composited.
     void repaintOnCompositingChange(RenderLayer&);
     
@@ -554,6 +557,7 @@
 #endif
 
     Color m_rootExtendedBackgroundColor;
+    Color m_lastDocumentBackgroundColor;
 
     HashMap<ScrollingNodeID, RenderLayer*> m_scrollingNodeToLayerMap;
 };

Modified: trunk/Source/WebCore/testing/Internals.cpp (183774 => 183775)


--- trunk/Source/WebCore/testing/Internals.cpp	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/testing/Internals.cpp	2015-05-04 22:53:10 UTC (rev 183775)
@@ -987,6 +987,17 @@
     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
 }
 
+void Internals::setViewBaseBackgroundColor(const String& colorValue, ExceptionCode& ec)
+{
+    Document* document = contextDocument();
+    if (!document || !document->view()) {
+        ec = INVALID_ACCESS_ERR;
+        return;
+    }
+
+    document->view()->setBaseBackgroundColor(Color(colorValue));
+}
+
 void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
 {
     Document* document = contextDocument();

Modified: trunk/Source/WebCore/testing/Internals.h (183774 => 183775)


--- trunk/Source/WebCore/testing/Internals.h	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/testing/Internals.h	2015-05-04 22:53:10 UTC (rev 183775)
@@ -157,6 +157,8 @@
     void invalidateFontCache();
 
     void setScrollViewPosition(long x, long y, ExceptionCode&);
+    void setViewBaseBackgroundColor(const String& colorValue, ExceptionCode&);
+
     void setPagination(const String& mode, int gap, ExceptionCode& ec) { setPagination(mode, gap, 0, ec); }
     void setPagination(const String& mode, int gap, int pageLength, ExceptionCode&);
     String configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode&);

Modified: trunk/Source/WebCore/testing/Internals.idl (183774 => 183775)


--- trunk/Source/WebCore/testing/Internals.idl	2015-05-04 22:14:33 UTC (rev 183774)
+++ trunk/Source/WebCore/testing/Internals.idl	2015-05-04 22:53:10 UTC (rev 183775)
@@ -122,6 +122,8 @@
 
     [RaisesException] void setScrollViewPosition(long x, long y);
 
+    [RaisesException] void setViewBaseBackgroundColor(DOMString colorValue);
+
     [RaisesException] void setPagination(DOMString mode, long gap, optional long pageLength);
 
     [RaisesException] DOMString configurationForViewport(unrestricted float devicePixelRatio,
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to