Fix CALayer hiearchy when combining tiling with preserve-3d
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Oct 2012 20:36:02 +0000 (20:36 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Oct 2012 20:36:02 +0000 (20:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=100205

Reviewed by Dean Jackson.

Source/WebCore:

When an element has "transform-style: preserve-3d", its GraphicsLayerCA has a
m_structuralLayer which is a CATransformLayer. The primary CALayer which contains rendered
content becomes a sublayer of the CATransformLayer. If the element has backface-visibility:hidden,
it is the primary layer that is set to be single-sided.

In r131940 we started to use TileCaches in place of CATiledLayer. TileCaches work via
"customSublayers" returned from the PlatformCALayer, where the custom sublayer is
the tile cache container layer. However, the custom sublayers were being added as
children of the structural (CATransformLayer) layer, not of the primary (CALayer) layer,
thus they were not affected by the doubleSided property.

This change cleans up the confusing code in GraphicsLayerCA::updateSublayerList()
by maintaining two vectors of PlatformCALayers, one for sublayers of the structural
layer, and one for sublayers of the primary layer. It adds custom sublayers to
the latter list, so now the tile cache container layer becomes a sublayer of
the primary layer, so is affected by that layer's doubleSided property.

Test: compositing/tiling/backface-preserve-3d-tiled.html

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::updateSublayerList):

LayoutTests:

Pixel test that tests backface-visibility on a tile cache layer. Mark the test as
failing on Chromium.

* compositing/tiling/backface-preserve-3d-tiled-expected.png: Added.
* compositing/tiling/backface-preserve-3d-tiled-expected.txt: Added.
* compositing/tiling/backface-preserve-3d-tiled.html: Added.
* platform/chromium/TestExpectations:

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

LayoutTests/ChangeLog
LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.png [new file with mode: 0644]
LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.txt [new file with mode: 0644]
LayoutTests/compositing/tiling/backface-preserve-3d-tiled.html [new file with mode: 0644]
LayoutTests/platform/chromium/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

index 20208b6..4cf4759 100644 (file)
@@ -1,3 +1,18 @@
+2012-10-24  Simon Fraser  <simon.fraser@apple.com>
+
+        Fix CALayer hiearchy when combining tiling with preserve-3d
+        https://bugs.webkit.org/show_bug.cgi?id=100205
+
+        Reviewed by Dean Jackson.
+
+        Pixel test that tests backface-visibility on a tile cache layer. Mark the test as
+        failing on Chromium.
+
+        * compositing/tiling/backface-preserve-3d-tiled-expected.png: Added.
+        * compositing/tiling/backface-preserve-3d-tiled-expected.txt: Added.
+        * compositing/tiling/backface-preserve-3d-tiled.html: Added.
+        * platform/chromium/TestExpectations:
+
 2012-10-24  Rick Byers  <rbyers@chromium.org>
 
         image-set doesn't round-trip properly with cssText
diff --git a/LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.png b/LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.png
new file mode 100644 (file)
index 0000000..34fa390
Binary files /dev/null and b/LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.png differ
diff --git a/LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.txt b/LayoutTests/compositing/tiling/backface-preserve-3d-tiled-expected.txt
new file mode 100644 (file)
index 0000000..298fc20
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (children 2
+        (GraphicsLayer
+          (position 18.00 10.00)
+          (bounds 204.00 204.00)
+          (children 1
+            (GraphicsLayer
+              (position 2.00 2.00)
+              (bounds 200.00 200.00)
+              (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 -0.00] [0.00 0.00 0.00 1.00])
+              (children 1
+                (GraphicsLayer
+                  (bounds 202.00 202.00)
+                  (preserves3D 1)
+                  (drawsContent 1)
+                  (backfaceVisibility hidden)
+                  (transform [-1.00 0.00 -0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 -1.00 0.00] [0.00 0.00 0.00 1.00])
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 18.00 224.00)
+          (bounds 204.00 204.00)
+          (children 1
+            (GraphicsLayer
+              (position 2.00 2.00)
+              (bounds 200.00 200.00)
+              (childrenTransform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 -0.00] [0.00 0.00 0.00 1.00])
+              (children 1
+                (GraphicsLayer
+                  (bounds 202.00 2502.00)
+                  (usingTiledLayer 1)
+                  (preserves3D 1)
+                  (drawsContent 1)
+                  (backfaceVisibility hidden)
+                  (transform [-1.00 0.00 -0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 -1.00 0.00] [0.00 0.00 0.00 1.00])
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/tiling/backface-preserve-3d-tiled.html b/LayoutTests/compositing/tiling/backface-preserve-3d-tiled.html
new file mode 100644 (file)
index 0000000..0b06c31
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        body {
+            overflow: hidden;
+        }
+        
+        .container {
+            position: relative;
+            height: 200px;
+            width: 200px;
+            border: 2px solid black;
+            margin: 10px;
+            overflow: hidden;
+            -webkit-perspective: 600px;
+        }
+        .box {
+            position: absolute;
+            height: 200px;
+            width: 200px;
+            background-color: red;
+            border: 1px solid black;
+            -webkit-backface-visibility: hidden;
+            -webkit-transform-style: preserve-3d;
+            -webkit-transform: rotateY(180deg);
+        }
+        
+        .tiled {
+            height: 2500px;
+        }
+        
+        #layers {
+            opacity: 0; /* Hide from pixel result */
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText(true);
+        
+        function dumpLayers()
+        {
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+        }
+        window.addEventListener('load', dumpLayers, false);
+    </script>
+</head>
+<body>
+    <!-- You should see two empty white squares. -->
+    <div class="container">
+        <div class="box"></div>
+    </div>
+    <div class="container">
+        <div class="tiled box">
+        </div>
+    </div>
+
+<pre id="layers">Layers go here</pre>
+</body>
+</html>
index 84ab6b4..a8498f7 100644 (file)
@@ -2818,6 +2818,7 @@ crbug.com/84032 [ Win ] fast/dom/object-plugin-hides-properties.html [ Pass Time
 #new test added. Still fails on chrome
 webkit.org/b/98315 css3/compositing/blend-mode-property.html [ Failure ]
 webkit.org/b/98315 css3/compositing/should-have-compositing-layer.html [ Failure ]
+webkit.org/b/100205 compositing/tiling/backface-preserve-3d-tiled.html [ Failure ]
 
 # two regions reftests failing on Chromium
 webkit.org/b/74219 fast/regions/positioned-objects-block-static-spanning-regions-rtl.html [ ImageOnlyFailure Pass ]
index 75f7fd2..3011dd4 100644 (file)
@@ -1,3 +1,32 @@
+2012-10-24  Simon Fraser  <simon.fraser@apple.com>
+
+        Fix CALayer hiearchy when combining tiling with preserve-3d
+        https://bugs.webkit.org/show_bug.cgi?id=100205
+
+        Reviewed by Dean Jackson.
+
+        When an element has "transform-style: preserve-3d", its GraphicsLayerCA has a
+        m_structuralLayer which is a CATransformLayer. The primary CALayer which contains rendered
+        content becomes a sublayer of the CATransformLayer. If the element has backface-visibility:hidden,
+        it is the primary layer that is set to be single-sided.
+        
+        In r131940 we started to use TileCaches in place of CATiledLayer. TileCaches work via
+        "customSublayers" returned from the PlatformCALayer, where the custom sublayer is 
+        the tile cache container layer. However, the custom sublayers were being added as
+        children of the structural (CATransformLayer) layer, not of the primary (CALayer) layer,
+        thus they were not affected by the doubleSided property.
+        
+        This change cleans up the confusing code in GraphicsLayerCA::updateSublayerList()
+        by maintaining two vectors of PlatformCALayers, one for sublayers of the structural
+        layer, and one for sublayers of the primary layer. It adds custom sublayers to
+        the latter list, so now the tile cache container layer becomes a sublayer of
+        the primary layer, so is affected by that layer's doubleSided property.
+
+        Test: compositing/tiling/backface-preserve-3d-tiled.html
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::updateSublayerList):
+
 2012-10-23  Zhenyao Mo  <zmo@google.com>
 
         Update mozilla's CheckedInt.h to the latest version
index 6ee9c02..5e872b8 100644 (file)
@@ -1184,54 +1184,47 @@ void GraphicsLayerCA::updateLayerNames()
 
 void GraphicsLayerCA::updateSublayerList()
 {
-    PlatformCALayerList newSublayers;
-    const Vector<GraphicsLayer*>& childLayers = children();
+    const PlatformCALayerList* customSublayers = m_layer->customSublayers();
+
+    PlatformCALayerList structuralLayerChildren;
+    PlatformCALayerList primaryLayerChildren;
+
+    PlatformCALayerList& childListForSublayers = m_structuralLayer ? structuralLayerChildren : primaryLayerChildren;
+
+    if (customSublayers)
+        primaryLayerChildren.append(*customSublayers);
 
-    if (const PlatformCALayerList* customSublayers = m_layer->customSublayers())
-        newSublayers.appendRange(customSublayers->begin(), customSublayers->end());
+    if (m_structuralLayer) {
+        if (m_replicaLayer)
+            structuralLayerChildren.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
     
-    if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) {
-        if (m_structuralLayer) {
-            // Add the replica layer first.
-            if (m_replicaLayer)
-                newSublayers.append(static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer());
-            // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind.
-            newSublayers.append(m_layer);
-        } else if (m_contentsLayer && m_contentsVisible) {
-            // FIXME: add the contents layer in the correct order with negative z-order children.
-            // This does not cause visible rendering issues because currently contents layers are only used
-            // for replaced elements that don't have children.
-            newSublayers.append(m_contentsLayer);
-        }
-        
-        size_t numChildren = childLayers.size();
-        for (size_t i = 0; i < numChildren; ++i) {
-            GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
-            PlatformCALayer* childLayer = curChild->layerForSuperlayer();
-            newSublayers.append(childLayer);
-        }
+        structuralLayerChildren.append(m_layer);
+    }
 
-        for (size_t i = 0; i < newSublayers.size(); --i)
-            newSublayers[i]->removeFromSuperlayer();
+    if (m_contentsLayer && m_contentsVisible) {
+        // FIXME: add the contents layer in the correct order with negative z-order children.
+        // This does not cause visible rendering issues because currently contents layers are only used
+        // for replaced elements that don't have children.
+        primaryLayerChildren.append(m_contentsLayer);
     }
     
+    const Vector<GraphicsLayer*>& childLayers = children();
+    size_t numChildren = childLayers.size();
+    for (size_t i = 0; i < numChildren; ++i) {
+        GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]);
+        PlatformCALayer* childLayer = curChild->layerForSuperlayer();
+        childListForSublayers.append(childLayer);
+    }
+
 #ifdef VISIBLE_TILE_WASH
     if (m_visibleTileWashLayer)
-        newSublayers.append(m_visibleTileWashLayer);
+        childListForSublayers.append(m_visibleTileWashLayer);
 #endif
 
-    if (m_structuralLayer) {
-        m_structuralLayer->setSublayers(newSublayers);
-
-        if (m_contentsLayer) {
-            // If we have a transform layer, then the contents layer is parented in the 
-            // primary layer (which is itself a child of the transform layer).
-            m_layer->removeAllSublayers();
-            if (m_contentsVisible)
-                m_layer->appendSublayer(m_contentsLayer.get());
-        }
-    } else
-        m_layer->setSublayers(newSublayers);
+    if (m_structuralLayer)
+        m_structuralLayer->setSublayers(structuralLayerChildren);
+    
+    m_layer->setSublayers(primaryLayerChildren);
 }
 
 void GraphicsLayerCA::updateGeometry(float pageScaleFactor, const FloatPoint& positionRelativeToBase)