Fix painting phases for composited scrolling
authorvollick@chromium.org <vollick@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Mar 2013 14:00:57 +0000 (14:00 +0000)
committervollick@chromium.org <vollick@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 Mar 2013 14:00:57 +0000 (14:00 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@145067 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/overflow/composited-scrolling-paint-phases-expected.txt [new file with mode: 0644]
LayoutTests/compositing/overflow/composited-scrolling-paint-phases.html [new file with mode: 0644]
LayoutTests/compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [new file with mode: 0644]
LayoutTests/compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
LayoutTests/platform/mac-wk2/TestExpectations
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/mac/compositing/overflow/composited-scrolling-paint-phases-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/Frame.h
Source/WebCore/platform/graphics/GraphicsLayer.cpp
Source/WebCore/platform/graphics/GraphicsLayer.h
Source/WebCore/platform/graphics/GraphicsLayerClient.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl

index d21092f..3707870 100644 (file)
@@ -1,3 +1,47 @@
+2013-03-07  Ian Vollick  <vollick@chromium.org>
+
+        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.
+
+        * 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.
+
 2013-03-07  Antoine Quint  <graouts@apple.com>
 
         Web Inspector: identify layers for CSS generated content in LayerTreeAgent
diff --git a/LayoutTests/compositing/overflow/composited-scrolling-paint-phases-expected.txt b/LayoutTests/compositing/overflow/composited-scrolling-paint-phases-expected.txt
new file mode 100644 (file)
index 0000000..11a5c87
--- /dev/null
@@ -0,0 +1,102 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (paintingPhases
+    GraphicsLayerPaintBackground
+    GraphicsLayerPaintForeground
+    GraphicsLayerPaintMask
+  )
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (paintingPhases
+        GraphicsLayerPaintBackground
+        GraphicsLayerPaintForeground
+        GraphicsLayerPaintMask
+      )
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 202.00 202.00)
+          (drawsContent 1)
+          (paintingPhases
+            GraphicsLayerPaintBackground
+            GraphicsLayerPaintMask
+            GraphicsLayerPaintCompositedScroll
+          )
+          (children 4
+            (GraphicsLayer
+              (position 1.00 1.00)
+              (bounds 200.00 200.00)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+              (children 1
+                (GraphicsLayer
+                  (bounds 185.00 715.00)
+                  (drawsContent 1)
+                  (paintingPhases
+                    GraphicsLayerPaintOverflowContents
+                    GraphicsLayerPaintCompositedScroll
+                  )
+                  (children 2
+                    (GraphicsLayer
+                      (position 0.00 10.00)
+                      (bounds 80.00 10.00)
+                      (contentsOpaque 1)
+                      (drawsContent 1)
+                      (paintingPhases
+                        GraphicsLayerPaintBackground
+                        GraphicsLayerPaintForeground
+                        GraphicsLayerPaintMask
+                      )
+                    )
+                    (GraphicsLayer
+                      (bounds 185.00 715.00)
+                      (drawsContent 1)
+                      (paintingPhases
+                        GraphicsLayerPaintForeground
+                      )
+                    )
+                  )
+                )
+              )
+            )
+            (GraphicsLayer
+              (position 1.00 186.00)
+              (bounds 185.00 15.00)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+            )
+            (GraphicsLayer
+              (position 186.00 1.00)
+              (bounds 15.00 185.00)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+            )
+            (GraphicsLayer
+              (position 186.00 186.00)
+              (bounds 15.00 15.00)
+              (drawsContent 1)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
+
diff --git a/LayoutTests/compositing/overflow/composited-scrolling-paint-phases.html b/LayoutTests/compositing/overflow/composited-scrolling-paint-phases.html
new file mode 100644 (file)
index 0000000..e5d4725
--- /dev/null
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <title>Composited scrolling paint phases</title>
+  <style type="text/css" media="screen">
+    .container {
+      width: 200px;
+      height: 200px;
+      overflow: scroll;
+      margin: 20px;
+      border: 1px solid black;
+    }
+
+    .composited {
+      width: 80px;
+      height: 10px;
+      position: relative;
+      top: 10px;
+      -webkit-transform: translateZ(0);
+      background-color: green;
+      z-index: -1;
+    }
+
+    .not-composited {
+      width: 80px;
+      height: 20px;
+      margin: 5px;
+      background-color: blue;
+    }
+  </style>
+  <script>
+    if (window.testRunner)
+      window.testRunner.dumpAsText(false);
+
+    if (window.internals)
+      window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true);
+
+    function write(str)
+    {
+      var pre = document.getElementById('console');
+      var text = document.createTextNode(str + '\n');
+      pre.appendChild(text);
+    }
+
+    function doTest()
+    {
+      write(window.internals.layerTreeAsText(document, window.internals.LAYER_TREE_INCLUDES_PAINTING_PHASES));
+      if (window.testRunner)
+        window.testRunner.notifyDone(); 
+    }
+
+    window.addEventListener('load', doTest, false);
+
+    if (window.testRunner)
+      window.testRunner.waitUntilDone();
+  </script>
+</head>
+<body>
+  <div class="container">
+    <div class="composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+    <div class="not-composited"></div>
+  </div>
+  <pre id="console"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html b/LayoutTests/compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html
new file mode 100644 (file)
index 0000000..a412eab
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <title>Don't draw outlines into scrolling contents layer</title>
+  <!--
+    If this test succeeds, you should not see the focus ring in the scrolled
+    contents.
+  -->
+  <script type="text/javascript" charset="utf-8">
+    if (window.testRunner)
+      window.testRunner.dumpAsText(true);
+
+    if (window.internals)
+      window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true);
+
+    function endTest()
+    {
+      var textarea = document.getElementById('text');
+      textarea.scrollTop = 80;
+      if (window.testRunner)
+        window.testRunner.notifyDone();
+    }
+
+    function doTest()
+    {
+      var textarea = document.getElementById('text');
+      textarea.focus();
+      textarea.selectionStart = textarea.selectionEnd = 0;
+      if (window.testRunner)
+        window.testRunner.display();
+      window.setTimeout(endTest, 100);
+    }
+
+    window.addEventListener('load', doTest, false);
+
+    if (window.testRunner)
+      testRunner.waitUntilDone();
+  </script>
+</head>
+<body>
+  <textarea rows="6" cols="50" id="text">
+  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+
+  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+  </textarea>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html b/LayoutTests/compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html
new file mode 100644 (file)
index 0000000..a6611bb
--- /dev/null
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+  <title>Paint neg z-order descendants into the composited scrolling layer</title>
+  <style>
+    .scrollable {
+      overflow: scroll;
+    }
+
+    .scrolled {
+      position: relative;
+      z-index: -1;
+    }
+
+    #container {
+      position: absolute;
+      top: 10px;
+      left: 10px;
+      width: 200px;
+      height: 200px;
+      border: 1px black solid;
+    }
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.testRunner)
+      window.testRunner.dumpAsText(true);
+
+    if (window.internals)
+      window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true);
+
+    function endTest()
+    {
+      var textarea = document.getElementById('container');
+      textarea.scrollTop = 40;
+      if (window.testRunner)
+        window.testRunner.notifyDone();
+      window.testRunner.display();
+    }
+
+    function doTest()
+    {
+      var textarea = document.getElementById('container');
+      textarea.focus();
+      textarea.selectionStart = textarea.selectionEnd = 0;
+      if (window.testRunner)
+        window.testRunner.display();
+      window.setTimeout(endTest, 100);
+    }
+
+    window.addEventListener('load', doTest, false);
+
+    if (window.testRunner)
+      testRunner.waitUntilDone();
+  </script>
+</head>
+<body>
+  <div class="scrollable" id="container">
+    <div class="scrolled">
+  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+    </div>
+    <div class="scrolled">
+  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+    </div>
+    <div class="scrolled">
+  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
+    </div>
+  </div>
+</body>
+</html>
+
index 121f5f2..574dca0 100644 (file)
@@ -2870,6 +2870,17 @@ crbug.com/88588 fast/lists/inlineBoxWrapperNullCheck.html [ Failure Pass ]
 crbug.com/88894 http/tests/cache/subresource-expiration-1.html [ Pass Slow ]
 crbug.com/88894 http/tests/cache/subresource-expiration-2.html [ Pass Slow ]
 
+# The following are missing baselines.
+webkit.org/b/107935 platform/chromium/virtual/gpu/compositedscrolling/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Missing ]
+webkit.org/b/107935 platform/chromium/virtual/softwarecompositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Missing ]
+webkit.org/b/107935 compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Missing ]
+webkit.org/b/107935 platform/chromium/virtual/gpu/compositedscrolling/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [ Missing ]
+webkit.org/b/107935 platform/chromium/virtual/softwarecompositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [ Missing ]
+webkit.org/b/107935 compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [ Missing ]
+webkit.org/b/107935 platform/chromium/virtual/gpu/compositedscrolling/overflow/composited-scrolling-creates-a-stacking-container.html [ Failure ]
+webkit.org/b/107935 compositing/overflow/composited-scrolling-creates-a-stacking-container.html [ Failure ]
+webkit.org/b/107935 platform/chromium/virtual/softwarecompositing/overflow/composited-scrolling-creates-a-stacking-container.html [ Failure ]
+
 # V8 now follows spec on toisostring, test needs to be fixed.
 crbug.com/88936 fast/js/date-toisostring.html [ Failure ]
 
index 6a06cb3..bd11b2e 100644 (file)
@@ -292,6 +292,10 @@ webkit.org/b/105998 [ MountainLion Debug ] fast/css/sticky/sticky-both-sides.htm
 
 webkit.org/b/93552 inspector/device-orientation-success.html [ Failure ]
 
+webkit.org/b/107935 compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Missing ]
+webkit.org/b/107935 compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [ Missing ]
+webkit.org/b/107935 compositing/overflow/composited-scrolling-creates-a-stacking-container.html [ Failure ]
+
 webkit.org/b/106405 http/tests/loading/authentication-after-redirect-stores-wrong-credentials/authentication-after-redirect-stores-wrong-credentials.html [ Failure ]
 webkit.org/b/106405 http/tests/loading/basic-auth-resend-wrong-credentials.html [ Failure ]
 webkit.org/b/106405 http/tests/loading/basic-credentials-sent-automatically.html [ Failure ]
index f5f9c4f..5408ac6 100644 (file)
@@ -753,6 +753,12 @@ fast/sub-pixel/zoomed-image-tiles.html [ ImageOnlyFailure ]
 # Needs rebaseline
 fast/sub-pixel/inline-block-with-padding.html [ Failure ]
 
+# Needs rebaseline after https://bugs.webkit.org/show_bug.cgi?id=107618
+# https://bugs.webkit.org/show_bug.cgi?id=107952
+compositing/overflow/paint-neg-z-order-descendants-into-scrolling-contents-layer.html [ Missing ]
+compositing/overflow/composited-scrolling-creates-a-stacking-container.html [ Missing ]
+compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html [ Failure ]
+
 # No CORS support for media elements is implemented yet.
 http/tests/security/video-cross-origin-readback.html
 
diff --git a/LayoutTests/platform/mac/compositing/overflow/composited-scrolling-paint-phases-expected.txt b/LayoutTests/platform/mac/compositing/overflow/composited-scrolling-paint-phases-expected.txt
new file mode 100644 (file)
index 0000000..825b21f
--- /dev/null
@@ -0,0 +1,103 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (paintingPhases
+    GraphicsLayerPaintBackground
+    GraphicsLayerPaintForeground
+    GraphicsLayerPaintMask
+  )
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (paintingPhases
+        GraphicsLayerPaintBackground
+        GraphicsLayerPaintForeground
+        GraphicsLayerPaintMask
+      )
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 202.00 202.00)
+          (drawsContent 1)
+          (paintingPhases
+            GraphicsLayerPaintBackground
+            GraphicsLayerPaintMask
+            GraphicsLayerPaintCompositedScroll
+          )
+          (children 4
+            (GraphicsLayer
+              (position 1.00 1.00)
+              (bounds 200.00 200.00)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+              (children 1
+                (GraphicsLayer
+                  (bounds 185.00 715.00)
+                  (drawsContent 1)
+                  (paintingPhases
+                    GraphicsLayerPaintOverflowContents
+                    GraphicsLayerPaintCompositedScroll
+                  )
+                  (children 2
+                    (GraphicsLayer
+                      (position 0.00 10.00)
+                      (bounds 80.00 10.00)
+                      (contentsOpaque 1)
+                      (paintingPhases
+                        GraphicsLayerPaintBackground
+                        GraphicsLayerPaintForeground
+                        GraphicsLayerPaintMask
+                      )
+                    )
+                    (GraphicsLayer
+                      (bounds 185.00 715.00)
+                      (drawsContent 1)
+                      (paintingPhases
+                        GraphicsLayerPaintForeground
+                      )
+                    )
+                  )
+                )
+              )
+            )
+            (GraphicsLayer
+              (position 1.00 186.00)
+              (bounds 185.00 15.00)
+              (drawsContent 1)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+            )
+            (GraphicsLayer
+              (position 186.00 1.00)
+              (bounds 15.00 185.00)
+              (drawsContent 1)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+            )
+            (GraphicsLayer
+              (position 186.00 186.00)
+              (bounds 15.00 15.00)
+              (drawsContent 1)
+              (paintingPhases
+                GraphicsLayerPaintBackground
+                GraphicsLayerPaintForeground
+                GraphicsLayerPaintMask
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
+
index edf48ff..eccb815 100644 (file)
@@ -1,3 +1,69 @@
+2013-03-07  Ian Vollick  <vollick@chromium.org>
+
+        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.
+
+        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.
+
 2013-03-07  Allan Sandfeld Jensen  <allan.jensen@digia.com>
 
         [Qt] Use Qt5.1 supportedMimeTypes methods.
index 7053eb2..3d909b5 100644 (file)
@@ -80,7 +80,8 @@ namespace WebCore {
         LayerTreeFlagsIncludeDebugInfo = 1 << 0,
         LayerTreeFlagsIncludeVisibleRects = 1 << 1,
         LayerTreeFlagsIncludeTileCaches = 1 << 2,
-        LayerTreeFlagsIncludeRepaintRects = 1 << 3
+        LayerTreeFlagsIncludeRepaintRects = 1 << 3,
+        LayerTreeFlagsIncludePaintingPhases = 1 << 4
     };
     typedef unsigned LayerTreeFlags;
 
index 2294e52..cbb982b 100644 (file)
@@ -704,7 +704,34 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe
         writeIndent(ts, indent + 1);
         ts << ")\n";
     }
-    
+
+    if (behavior & LayerTreeAsTextIncludePaintingPhases && paintingPhase()) {
+        writeIndent(ts, indent + 1);
+        ts << "(paintingPhases\n";
+        if (paintingPhase() & GraphicsLayerPaintBackground) {
+            writeIndent(ts, indent + 2);
+            ts << "GraphicsLayerPaintBackground\n";
+        }
+        if (paintingPhase() & GraphicsLayerPaintForeground) {
+            writeIndent(ts, indent + 2);
+            ts << "GraphicsLayerPaintForeground\n";
+        }
+        if (paintingPhase() & GraphicsLayerPaintMask) {
+            writeIndent(ts, indent + 2);
+            ts << "GraphicsLayerPaintMask\n";
+        }
+        if (paintingPhase() & GraphicsLayerPaintOverflowContents) {
+            writeIndent(ts, indent + 2);
+            ts << "GraphicsLayerPaintOverflowContents\n";
+        }
+        if (paintingPhase() & GraphicsLayerPaintCompositedScroll) {
+            writeIndent(ts, indent + 2);
+            ts << "GraphicsLayerPaintCompositedScroll\n";
+        }
+        writeIndent(ts, indent + 1);
+        ts << ")\n";
+    }
+
     dumpAdditionalProperties(ts, indent, behavior);
     
     if (m_children.size()) {
index 42d6c91..fdf8766 100644 (file)
@@ -49,7 +49,8 @@ enum LayerTreeAsTextBehaviorFlags {
     LayerTreeAsTextDebug = 1 << 0, // Dump extra debugging info like layer addresses.
     LayerTreeAsTextIncludeVisibleRects = 1 << 1,
     LayerTreeAsTextIncludeTileCaches = 1 << 2,
-    LayerTreeAsTextIncludeRepaintRects = 1 << 3
+    LayerTreeAsTextIncludeRepaintRects = 1 << 3,
+    LayerTreeAsTextIncludePaintingPhases = 1 << 4
 };
 typedef unsigned LayerTreeAsTextBehavior;
 
index 3f8c51d..1e9d296 100644 (file)
@@ -42,6 +42,7 @@ enum GraphicsLayerPaintingPhaseFlags {
     GraphicsLayerPaintForeground = (1 << 1),
     GraphicsLayerPaintMask = (1 << 2),
     GraphicsLayerPaintOverflowContents = (1 << 3),
+    GraphicsLayerPaintCompositedScroll = (1 << 4),
     GraphicsLayerPaintAllWithOverflowClip = (GraphicsLayerPaintBackground | GraphicsLayerPaintForeground | GraphicsLayerPaintMask)
 };
 typedef unsigned GraphicsLayerPaintingPhase;
index 51d2443..5134dfb 100644 (file)
@@ -3652,8 +3652,19 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     bool haveTransparency = localPaintFlags & PaintLayerHaveTransparency;
     bool isSelfPaintingLayer = this->isSelfPaintingLayer();
     bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
-    // Outline always needs to be painted even if we have no visible content.
-    bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars;
+    bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositingScrollingPhase;
+    bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingCompositingForegroundPhase;
+    bool isPaintingCompositedBackground = paintFlags & PaintLayerPaintingCompositingBackgroundPhase;
+    bool isPaintingOverflowContents = paintFlags & PaintLayerPaintingOverflowContents;
+    // Outline always needs to be painted even if we have no visible content. Also,
+    // the outline is painted in the background phase during composited scrolling.
+    // If it were painted in the foreground phase, it would move with the scrolled
+    // content. When not composited scrolling, the outline is painted in the
+    // foreground phase. Since scrolled contents are moved by repainting in this
+    // case, the outline won't get 'dragged along'.
+    bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
+        && ((isPaintingScrollingContent && isPaintingCompositedBackground)
+        || (!isPaintingScrollingContent && isPaintingCompositedForeground));
     bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
 
     GraphicsContext* transparencyLayerContext = context;
@@ -3792,28 +3803,31 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
         // fragment should paint.
         collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.region, localPaintingInfo.paintDirtyRect,
             (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
-            (localPaintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot);
+            (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot);
         updatePaintingInfoForFragments(layerFragments, localPaintingInfo, localPaintFlags, shouldPaintContent, &offsetFromRoot);
     }
     
-    if (localPaintFlags & PaintLayerPaintingCompositingBackgroundPhase) {
+    if (isPaintingCompositedBackground) {
         // Paint only the backgrounds for all of the fragments of the layer.
         if (shouldPaintContent && !selectionOnly)
             paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
                 localPaintingInfo, paintBehavior, paintingRootForRenderer);
+    }
 
-        // Now walk the sorted list of children with negative z-indices.
+    // Now walk the sorted list of children with negative z-indices.
+    if ((isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground))
         paintList(negZOrderList(), context, localPaintingInfo, localPaintFlags);
-    }
     
-    if (localPaintFlags & PaintLayerPaintingCompositingForegroundPhase) {
+    if (isPaintingCompositedForeground) {
         if (shouldPaintContent)
             paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
                 localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, forceBlackText);
-        
-        if (shouldPaintOutline)
-            paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer);
+    }
+
+    if (shouldPaintOutline)
+        paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer);
 
+    if (isPaintingCompositedForeground) {
         // Paint any child layers that have overflow.
         paintList(m_normalFlowList.get(), context, localPaintingInfo, localPaintFlags);
     
index ccb658e..8dc8999 100644 (file)
@@ -613,9 +613,10 @@ public:
         PaintLayerPaintingCompositingBackgroundPhase = 1 << 5,
         PaintLayerPaintingCompositingForegroundPhase = 1 << 6,
         PaintLayerPaintingCompositingMaskPhase = 1 << 7,
-        PaintLayerPaintingOverflowContents = 1 << 8,
-        PaintLayerPaintingRootBackgroundOnly = 1 << 9,
-        PaintLayerPaintingSkipRootBackground = 1 << 10,
+        PaintLayerPaintingCompositingScrollingPhase = 1 << 8,
+        PaintLayerPaintingOverflowContents = 1 << 9,
+        PaintLayerPaintingRootBackgroundOnly = 1 << 10,
+        PaintLayerPaintingSkipRootBackground = 1 << 11,
         PaintLayerPaintingCompositingAllPhases = (PaintLayerPaintingCompositingBackgroundPhase | PaintLayerPaintingCompositingForegroundPhase | PaintLayerPaintingCompositingMaskPhase)
     };
     
index b364a06..c253a59 100644 (file)
@@ -813,6 +813,13 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
         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 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
             // 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 @@ GraphicsLayerPaintingPhase RenderLayerBacking::paintingPhaseForPrimaryLayer() co
     if (!m_maskLayer)
         phase |= GraphicsLayerPaintMask;
 
-    if (m_scrollingContentsLayer)
+    if (m_scrollingContentsLayer) {
         phase &= ~GraphicsLayerPaintForeground;
+        phase |= GraphicsLayerPaintCompositedScroll;
+    }
 
     return static_cast<GraphicsLayerPaintingPhase>(phase);
 }
@@ -1813,6 +1825,8 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
         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.
index 126149e..ca5ae11 100644 (file)
@@ -1281,6 +1281,8 @@ String RenderLayerCompositor::layerTreeAsText(LayerTreeFlags flags)
         layerTreeBehavior |= LayerTreeAsTextIncludeTileCaches;
     if (flags & LayerTreeFlagsIncludeRepaintRects)
         layerTreeBehavior |= LayerTreeAsTextIncludeRepaintRects;
+    if (flags & LayerTreeFlagsIncludePaintingPhases)
+        layerTreeBehavior |= LayerTreeAsTextIncludePaintingPhases;
 
     // We skip dumping the scroll and clip layers to keep layerTreeAsText output
     // similar between platforms.
index 2d97064..6cb1467 100644 (file)
@@ -1674,6 +1674,8 @@ String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionC
         layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
     if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
         layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
+    if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
+        layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
 
     return document->frame()->layerTreeAsText(layerTreeFlags);
 }
index c3df973..c1ac2bb 100644 (file)
@@ -222,8 +222,8 @@ public:
         // Values need to be kept in sync with Internals.idl.
         LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1,
         LAYER_TREE_INCLUDES_TILE_CACHES = 2,
-        LAYER_TREE_INCLUDES_REPAINT_RECTS = 4
-        
+        LAYER_TREE_INCLUDES_REPAINT_RECTS = 4,
+        LAYER_TREE_INCLUDES_PAINTING_PHASES = 8
     };
     String layerTreeAsText(Document*, unsigned flags, ExceptionCode&) const;
     String layerTreeAsText(Document*, ExceptionCode&) const;
index 5f4b1aa..93048d7 100644 (file)
     const unsigned short LAYER_TREE_INCLUDES_VISIBLE_RECTS = 1;
     const unsigned short LAYER_TREE_INCLUDES_TILE_CACHES = 2;
     const unsigned short LAYER_TREE_INCLUDES_REPAINT_RECTS = 4;
+    const unsigned short LAYER_TREE_INCLUDES_PAINTING_PHASES = 8;
     DOMString layerTreeAsText(in Document document, in [Optional] unsigned short flags) raises (DOMException);
 
     DOMString scrollingStateTreeAsText(in Document document) raises (DOMException);