Fix painting phases for composited scrolling
https://bugs.webkit.org/show_bug.cgi?id=107618

Reviewed by Simon Fraser.

With composited scrolling, the scrolling contents layer paints the
foreground and the main graphics layer paints the background. This
causes a few problems:

  1) If we create a foreground layer, we end up with two layers painting
     the foreground phase.
  2) Focus rings / outlines paint into the foreground layer, so they end
     up moving around with the scrolling contents.
  3) Neg z-order descendants paint in the the main graphics layer and
     will therefore not scroll.

To deal with 1) we need to stop painting the foreground into both the
foreground and scrolling contents layers. We also need to ensure that
the foreground layer is the right size and has the right offset from
renderer if we're on the composited scrolling path.

To deal with 2) and 3), I have added a new graphics layer painting phase
flag -- GraphicsLayerPaintCompositedScroll -- and applied it to two
layers in the subtree created by RenderLayerBacking. This ultimately
affects the paint phase passed to RenderLayer::paintLayerContents and
allows us to paint the focus rings, outlines and negative z-order
descendants into the proper layers.

Source/WebCore:

Tests: compositing/overflow/composited-scrolling-paint-phases.html
       compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html
       compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html

* page/Frame.h:
  Added a flag for including painting phases in the layer tree dump.
(WebCore::GraphicsLayer::dumpProperties):
  Can now dump painting phase information, but only if requested.
* platform/graphics/GraphicsLayerClient.h:
  Added a new entry to GraphicsLayerPaintingPhaseFlags for comp-scroll.
(WebCore::RenderLayer::paintLayerContents):
  Updated the logic to account for the new comp-scroll-related paint
  phase flag.
* rendering/RenderLayer.h:
  Added the RenderLayer painting phase counterpart to
  GraphicsLayerPaintCompositedScroll.
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
  Ensures that the foreground layer is sized correctly for comp-scroll.
(WebCore::RenderLayerBacking::updateScrollingLayers):
  If we have a foreground layer, the scrolling contents layer no
  longer gets assigned the foreground painting phase.
(WebCore::RenderLayerBacking::paintingPhaseForPrimaryLayer):
  If we're comp-scrolling, then the primary layer gets the new phase.
(WebCore::RenderLayerBacking::paintIntoLayer):
  Simply translates the new graphics layer painting phase to its
  render layer counterpart.
(WebCore::RenderLayerCompositor::layerTreeAsText):
* testing/Internals.cpp:
(WebCore::Internals::layerTreeAsText):
* testing/Internals.h:
* testing/Internals.idl:
  The above changes are solely plumbing to allow layout tests to
  request that paint phase information be included in the layer tree
  dump.

LayoutTests:

* compositing/overflow/composited-scrolling-paint-phases-expected.txt: Added.
* compositing/overflow/composited-scrolling-paint-phases.html: Added.
* platform/mac/compositing/overflom/composited-scrolling-paint-phases-expected.txt: Added.
  This is a text-based test that checks that the graphics layer
  painting phases are correct with composited scrolling + foreground
  layers.
* compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html: Added.
* compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html: Added.
  These tests cover cases 2) and 3) above.
* platform/chromium/TestExpectations:
* platform/mac-wk2/TestExpectations:
* platform/mac/TestExpectations:
  These have been updated to reflect the missing baselines.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@145067 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index b364a06..c253a59 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -813,6 +813,13 @@
         m_scrollingContentsLayer->setSize(scrollSize);
         // FIXME: The paint offset and the scroll offset should really be separate concepts.
         m_scrollingContentsLayer->setOffsetFromRenderer(scrollingContentsOffset, GraphicsLayer::DontSetNeedsDisplay);
+
+        if (m_foregroundLayer) {
+            if (m_foregroundLayer->size() != m_scrollingContentsLayer->size())
+                m_foregroundLayer->setSize(m_scrollingContentsLayer->size());
+            m_foregroundLayer->setNeedsDisplay();
+            m_foregroundLayer->setOffsetFromRenderer(m_scrollingContentsLayer->offsetFromRenderer());
+        }
     }
 
     // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
@@ -1211,7 +1218,10 @@
             // Inner layer which renders the content that scrolls.
             m_scrollingContentsLayer = createGraphicsLayer("Scrolled Contents");
             m_scrollingContentsLayer->setDrawsContent(true);
-            m_scrollingContentsLayer->setPaintingPhase(GraphicsLayerPaintForeground | GraphicsLayerPaintOverflowContents);
+            GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
+            if (!m_foregroundLayer)
+                paintPhase |= GraphicsLayerPaintForeground;
+            m_scrollingContentsLayer->setPaintingPhase(paintPhase);
             m_scrollingLayer->addChild(m_scrollingContentsLayer.get());
 
             layerChanged = true;
@@ -1281,8 +1291,10 @@
     if (!m_maskLayer)
         phase |= GraphicsLayerPaintMask;
 
-    if (m_scrollingContentsLayer)
+    if (m_scrollingContentsLayer) {
         phase &= ~GraphicsLayerPaintForeground;
+        phase |= GraphicsLayerPaintCompositedScroll;
+    }
 
     return static_cast<GraphicsLayerPaintingPhase>(phase);
 }
@@ -1813,6 +1825,8 @@
         paintFlags |= RenderLayer::PaintLayerPaintingCompositingMaskPhase;
     if (paintingPhase & GraphicsLayerPaintOverflowContents)
         paintFlags |= RenderLayer::PaintLayerPaintingOverflowContents;
+    if (paintingPhase & GraphicsLayerPaintCompositedScroll)
+        paintFlags |= RenderLayer::PaintLayerPaintingCompositingScrollingPhase;
 
     if (graphicsLayer == m_backgroundLayer)
         paintFlags |= (RenderLayer::PaintLayerPaintingRootBackgroundOnly | RenderLayer::PaintLayerPaintingCompositingForegroundPhase); // Need PaintLayerPaintingCompositingForegroundPhase to walk child layers.