Regions outside of the fullscreen window are exposed during zoom operations
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Jun 2018 16:13:31 +0000 (16:13 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Jun 2018 16:13:31 +0000 (16:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=186330
<rdar://problem/34698009>

Reviewed by Simon Fraser.

Source/WebCore:

Test: fullscreen/full-screen-layer-dump.html

Introduce the concept of "requiresBackgroundLayer" to RenderLayerBacking, for use by
RenderFullScreen. Previously, the backgroundLayer in RenderLayerBacking was only used
by the root renderer with fixed backgrounds. Give the RenderFullScreen a background layer
that's approximately 3x as tall and wide as the renderer itself, so nothing is exposed
during pinch operations.

* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::RenderLayerBacking):
(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::RenderLayerBacking::updateGeometry):
(WebCore::RenderLayerBacking::updateDrawsContent):
(WebCore::RenderLayerBacking::setRequiresBackgroundLayer):
(WebCore::RenderLayerBacking::updateBackgroundLayer):
(WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):
(WebCore::RenderLayerBacking::paintIntoLayer):
* rendering/RenderLayerBacking.h:

LayoutTests:

* fullscreen/full-screen-layer-dump-expected.txt: Added.
* fullscreen/full-screen-layer-dump.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@232543 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fullscreen/full-screen-layer-dump-expected.txt [new file with mode: 0644]
LayoutTests/fullscreen/full-screen-layer-dump.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h

index 6a2fd1f..59d3e1c 100644 (file)
@@ -1,3 +1,14 @@
+2018-06-06  Jer Noble  <jer.noble@apple.com>
+
+        Regions outside of the fullscreen window are exposed during zoom operations
+        https://bugs.webkit.org/show_bug.cgi?id=186330
+        <rdar://problem/34698009>
+
+        Reviewed by Simon Fraser.
+
+        * fullscreen/full-screen-layer-dump-expected.txt: Added.
+        * fullscreen/full-screen-layer-dump.html: Added.
+
 2018-06-06  Alicia Boya GarcĂ­a  <aboya@igalia.com>
 
         [GTK] Unreviewed test gardening
diff --git a/LayoutTests/fullscreen/full-screen-layer-dump-expected.txt b/LayoutTests/fullscreen/full-screen-layer-dump-expected.txt
new file mode 100644 (file)
index 0000000..edcd3be
--- /dev/null
@@ -0,0 +1,27 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (bounds 800.00 600.00)
+          (children 2
+            (GraphicsLayer
+              (anchor 0.00 0.00)
+              (bounds 800.00 600.00)
+              (contents layer -800.00, -600.00 2400.00 x 1800.00)
+            )
+            (GraphicsLayer
+              (bounds 800.00 600.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/fullscreen/full-screen-layer-dump.html b/LayoutTests/fullscreen/full-screen-layer-dump.html
new file mode 100644 (file)
index 0000000..5ee2360
--- /dev/null
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+body {
+    font-family: ahem;
+    -webkit-font-smoothing: none;
+}
+</style>
+<script>
+    window.addEventListener('load', event => {
+        let out = document.querySelector('#out');
+        let target = document.querySelector('#target');
+
+        if (!window.internals || !window.testRunner || !window.eventSender) {
+            out.innerText = 'This test requires internals';
+            return;
+        }
+
+        testRunner.dumpAsText(false);
+        testRunner.waitUntilDone();
+
+        document.addEventListener('webkitfullscreenchange', event => {
+            if (document.webkitIsFullScreen) {
+                setTimeout(() => {
+                    out.innerText = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CONTENT_LAYERS);
+                    document.webkitCancelFullScreen();
+                }, 0)
+            } else 
+                testRunner.notifyDone();
+        });
+
+
+        document.addEventListener('keydown', event => {
+            target.webkitRequestFullScreen();
+        });
+        if (window.eventSender)
+            eventSender.keyDown('a');
+    });
+</script>
+</head>
+<body>
+    <div id=target></div>
+    <pre id=out></pre>
+</body>
+</html>
index caee7c6..58c67e4 100644 (file)
@@ -1,5 +1,32 @@
 2018-06-06  Jer Noble  <jer.noble@apple.com>
 
+        Regions outside of the fullscreen window are exposed during zoom operations
+        https://bugs.webkit.org/show_bug.cgi?id=186330
+        <rdar://problem/34698009>
+
+        Reviewed by Simon Fraser.
+
+        Test: fullscreen/full-screen-layer-dump.html
+
+        Introduce the concept of "requiresBackgroundLayer" to RenderLayerBacking, for use by
+        RenderFullScreen. Previously, the backgroundLayer in RenderLayerBacking was only used
+        by the root renderer with fixed backgrounds. Give the RenderFullScreen a background layer
+        that's approximately 3x as tall and wide as the renderer itself, so nothing is exposed
+        during pinch operations.
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::RenderLayerBacking):
+        (WebCore::RenderLayerBacking::updateConfiguration):
+        (WebCore::RenderLayerBacking::updateGeometry):
+        (WebCore::RenderLayerBacking::updateDrawsContent):
+        (WebCore::RenderLayerBacking::setRequiresBackgroundLayer):
+        (WebCore::RenderLayerBacking::updateBackgroundLayer):
+        (WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):
+        (WebCore::RenderLayerBacking::paintIntoLayer):
+        * rendering/RenderLayerBacking.h:
+
+2018-06-06  Jer Noble  <jer.noble@apple.com>
+
         Set the AVAssetResourceLoaderRequest's contentType to AVStreamingKeyDeliveryContentKeyType in the case of a FPS key request.
         https://bugs.webkit.org/show_bug.cgi?id=186328
         <rdar://problem/40829228>
index ac3d7c4..db39ab8 100644 (file)
@@ -217,6 +217,9 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
     }
     
     createPrimaryGraphicsLayer();
+#if ENABLE(FULLSCREEN_API)
+    setRequiresBackgroundLayer(layer.renderer().isRenderFullScreen());
+#endif
 
     if (auto* tiledBacking = this->tiledBacking()) {
         tiledBacking->setIsInWindow(renderer().page().isInWindow());
@@ -670,7 +673,7 @@ bool RenderLayerBacking::updateConfiguration()
     setBackgroundLayerPaintsFixedRootBackground(compositor().needsFixedRootBackgroundLayer(m_owningLayer));
     
     // The background layer is currently only used for fixed root backgrounds.
-    if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
+    if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground || m_requiresBackgroundLayer))
         layerConfigChanged = true;
 
     if (updateForegroundLayer(compositor().needsContentsCompositingLayer(m_owningLayer)))
@@ -1031,7 +1034,7 @@ void RenderLayerBacking::updateGeometry()
         positionOverflowControlsLayers();
     }
 
-    if (!m_isMainFrameRenderViewLayer && !m_isFrameLayerWithTiledBacking) {
+    if (!m_isMainFrameRenderViewLayer && !m_isFrameLayerWithTiledBacking && !m_requiresBackgroundLayer) {
         // For non-root layers, background is always painted by the primary graphics layer.
         ASSERT(!m_backgroundLayer);
         // Subpixel offset from graphics layer or size changed.
@@ -1120,6 +1123,10 @@ void RenderLayerBacking::updateGeometry()
             const FrameView& frameView = renderer().view().frameView();
             backgroundPosition = frameView.scrollPositionForFixedPosition();
             backgroundSize = frameView.layoutSize();
+        } else {
+            auto boundingBox = renderer().objectBoundingBox();
+            backgroundPosition = boundingBox.location();
+            backgroundSize = boundingBox.size();
         }
         m_backgroundLayer->setPosition(backgroundPosition);
         m_backgroundLayer->setSize(backgroundSize);
@@ -1386,7 +1393,7 @@ void RenderLayerBacking::updateDrawsContent(PaintedContentsInfo& contentsInfo)
         m_graphicsLayer->setSupportsSubpixelAntialiasedText(m_paintsSubpixelAntialiasedText);
 
     if (m_backgroundLayer)
-        m_backgroundLayer->setDrawsContent(hasPaintedContent);
+        m_backgroundLayer->setDrawsContent(m_backgroundLayerPaintsFixedRootBackground ? hasPaintedContent : contentsInfo.paintsBoxDecorations());
 }
 
 // Return true if the layer changed.
@@ -1444,6 +1451,11 @@ void RenderLayerBacking::setBackgroundLayerPaintsFixedRootBackground(bool backgr
     }
 }
 
+void RenderLayerBacking::setRequiresBackgroundLayer(bool requiresBackgroundLayer)
+{
+    m_requiresBackgroundLayer = requiresBackgroundLayer;
+}
+
 bool RenderLayerBacking::requiresHorizontalScrollbarLayer() const
 {
     if (!m_owningLayer.hasOverlayScrollbars() && !m_owningLayer.needsCompositedScrolling())
@@ -1640,8 +1652,9 @@ bool RenderLayerBacking::updateBackgroundLayer(bool needsBackgroundLayer)
     
     if (layerChanged) {
         m_graphicsLayer->setNeedsDisplay();
-        // This assumes that the background layer is only used for fixed backgrounds, which is currently a correct assumption.
-        compositor().fixedRootBackgroundLayerChanged();
+
+        if (m_backgroundLayerPaintsFixedRootBackground)
+            compositor().fixedRootBackgroundLayerChanged();
     }
     
     return layerChanged;
@@ -1890,6 +1903,19 @@ Color RenderLayerBacking::rendererBackgroundColor() const
 
 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(PaintedContentsInfo& contentsInfo, bool& didUpdateContentsRect)
 {
+    if (m_backgroundLayer && !m_backgroundLayerPaintsFixedRootBackground && !contentsInfo.paintsBoxDecorations()) {
+        m_graphicsLayer->setContentsToSolidColor(Color());
+        m_backgroundLayer->setContentsToSolidColor(rendererBackgroundColor());
+
+        FloatRect contentsRect = backgroundBoxForSimpleContainerPainting();
+        // NOTE: This is currently only used by RenderFullScreen, which we want to be
+        // big enough to hide overflow areas of the root.
+        contentsRect.inflate(contentsRect.size());
+        m_backgroundLayer->setContentsRect(contentsRect);
+        m_backgroundLayer->setContentsClippingRect(FloatRoundedRect(contentsRect));
+        return;
+    }
+
     if (!contentsInfo.isSimpleContainer() || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
         m_graphicsLayer->setContentsToSolidColor(Color());
         return;
@@ -2519,7 +2545,7 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
     if (paintingPhase & GraphicsLayerPaintCompositedScroll)
         paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
 
-    if (graphicsLayer == m_backgroundLayer.get())
+    if (graphicsLayer == m_backgroundLayer.get() && m_backgroundLayerPaintsFixedRootBackground)
         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.
     else if (compositor().fixedRootBackgroundLayer())
         paintFlags |= RenderLayer::PaintLayerPaintingSkipRootBackground;
index d9c26a4..f7071af 100644 (file)
@@ -98,6 +98,9 @@ public:
     GraphicsLayer* foregroundLayer() const { return m_foregroundLayer.get(); }
     GraphicsLayer* backgroundLayer() const { return m_backgroundLayer.get(); }
     bool backgroundLayerPaintsFixedRootBackground() const { return m_backgroundLayerPaintsFixedRootBackground; }
+
+    bool requiresBackgroundLayer() const { return m_requiresBackgroundLayer; }
+    void setRequiresBackgroundLayer(bool);
     
     bool hasScrollingLayer() const { return m_scrollingLayer != nullptr; }
     GraphicsLayer* scrollingLayer() const { return m_scrollingLayer.get(); }
@@ -384,6 +387,7 @@ private:
     bool m_canCompositeBackdropFilters { false };
 #endif
     bool m_backgroundLayerPaintsFixedRootBackground { false };
+    bool m_requiresBackgroundLayer { false };
     bool m_paintsSubpixelAntialiasedText { false }; // This is for logging only.
 };