Title: [168119] trunk
Revision
168119
Author
simon.fra...@apple.com
Date
2014-05-01 13:56:21 -0700 (Thu, 01 May 2014)

Log Message

Don't always make backing store for -webkit-backface-visibility:hidden
https://bugs.webkit.org/show_bug.cgi?id=132420

Reviewed by Sam Weinig.

Source/WebCore:
Previously, -webkit-backface-visibility:hidden unconditionally created
compositing layers with backing store. This results in high memory use
on pages with this style applied to many elements (a cargo-cult "optimization").

Fix by only having -webkit-backface-visibility:hidden create compositing layers
if some ancestor has a 3D transform. That's the only scenario in which the
element can be flipped around to reveal the back side, so the only time we need
to do compositing for this property. In future, we could be smarter, and only
consider 3D transforms in the current preserve-3d context.

Tests: compositing/backing/backface-visibility-in-3dtransformed.html
       compositing/backing/backface-visibility-in-transformed.html
       compositing/backing/backface-visibility.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::RenderLayer::hitTestLayer):
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingLayer):
(WebCore::RenderLayerCompositor::requiresOwnBackingStore):
(WebCore::RenderLayerCompositor::requiresCompositingForBackfaceVisibility):
* rendering/RenderLayerCompositor.h:

LayoutTests:
Dump layers for elements with backface-visibility: hidden with various types
of ancestors.

* compositing/backing/backface-visibility-expected.txt: Added.
* compositing/backing/backface-visibility-in-3dtransformed-expected.txt: Added.
* compositing/backing/backface-visibility-in-3dtransformed.html: Added.
* compositing/backing/backface-visibility-in-transformed-expected.txt: Added.
* compositing/backing/backface-visibility-in-transformed.html: Added.
* compositing/backing/backface-visibility.html: Added.
* inspector-protocol/layers/layers-anonymous.html: Don't use backface-visibility
for force a layer.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (168118 => 168119)


--- trunk/LayoutTests/ChangeLog	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/LayoutTests/ChangeLog	2014-05-01 20:56:21 UTC (rev 168119)
@@ -1,3 +1,22 @@
+2014-05-01  Simon Fraser  <simon.fra...@apple.com>
+
+        Don't always make backing store for -webkit-backface-visibility:hidden
+        https://bugs.webkit.org/show_bug.cgi?id=132420
+
+        Reviewed by Sam Weinig.
+        
+        Dump layers for elements with backface-visibility: hidden with various types
+        of ancestors.
+
+        * compositing/backing/backface-visibility-expected.txt: Added.
+        * compositing/backing/backface-visibility-in-3dtransformed-expected.txt: Added.
+        * compositing/backing/backface-visibility-in-3dtransformed.html: Added.
+        * compositing/backing/backface-visibility-in-transformed-expected.txt: Added.
+        * compositing/backing/backface-visibility-in-transformed.html: Added.
+        * compositing/backing/backface-visibility.html: Added.
+        * inspector-protocol/layers/layers-anonymous.html: Don't use backface-visibility
+        for force a layer.
+
 2014-05-01  Brent Fulgham  <bfulg...@apple.com>
 
         Fix handling of attributes prior to compiling shader

Added: trunk/LayoutTests/compositing/backing/backface-visibility-expected.txt (0 => 168119)


--- trunk/LayoutTests/compositing/backing/backface-visibility-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/backing/backface-visibility-expected.txt	2014-05-01 20:56:21 UTC (rev 168119)
@@ -0,0 +1,3 @@
+Should be no layers here.
+
+

Added: trunk/LayoutTests/compositing/backing/backface-visibility-in-3dtransformed-expected.txt (0 => 168119)


--- trunk/LayoutTests/compositing/backing/backface-visibility-in-3dtransformed-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/backing/backface-visibility-in-3dtransformed-expected.txt	2014-05-01 20:56:21 UTC (rev 168119)
@@ -0,0 +1,28 @@
+Should be several layers here.
+
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 50.00)
+          (bounds 122.00 122.00)
+          (drawsContent 1)
+          (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 10.00 1.00])
+          (children 1
+            (GraphicsLayer
+              (position 11.00 11.00)
+              (bounds 100.00 100.00)
+              (contentsOpaque 1)
+              (backfaceVisibility hidden)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+

Added: trunk/LayoutTests/compositing/backing/backface-visibility-in-3dtransformed.html (0 => 168119)


--- trunk/LayoutTests/compositing/backing/backface-visibility-in-3dtransformed.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/backing/backface-visibility-in-3dtransformed.html	2014-05-01 20:56:21 UTC (rev 168119)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .container {
+            height: 100px;
+            width: 100px;
+            padding: 10px;
+            border: 1px solid gray;
+        }
+        .box {
+          width: 100px;
+          height: 100px;
+          background-color: silver;
+        }
+        
+        .transformed {
+            -webkit-transform: translateZ(10px);
+        }
+        .backface-hidden {
+            -webkit-backface-visibility: hidden;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function dumpLayers()
+        {
+            var layersResult = document.getElementById('layers');
+            if (window.testRunner)
+                layersResult.innerText = window.internals.layerTreeAsText(document);
+
+        }
+        window.addEventListener('load', dumpLayers, false)
+    </script>
+</head>
+<body>
+    <p>Should be several layers here.</p>
+    <div class="transformed container">
+        <div class="backface-hidden box"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>

Added: trunk/LayoutTests/compositing/backing/backface-visibility-in-transformed-expected.txt (0 => 168119)


--- trunk/LayoutTests/compositing/backing/backface-visibility-in-transformed-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/backing/backface-visibility-in-transformed-expected.txt	2014-05-01 20:56:21 UTC (rev 168119)
@@ -0,0 +1,3 @@
+Should be no layers here.
+
+

Added: trunk/LayoutTests/compositing/backing/backface-visibility-in-transformed.html (0 => 168119)


--- trunk/LayoutTests/compositing/backing/backface-visibility-in-transformed.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/backing/backface-visibility-in-transformed.html	2014-05-01 20:56:21 UTC (rev 168119)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .container {
+            height: 100px;
+            width: 100px;
+            padding: 10px;
+            border: 1px solid gray;
+        }
+        .box {
+          width: 100px;
+          height: 100px;
+          background-color: silver;
+        }
+        
+        .transformed {
+            -webkit-transform: translate(10px, 10px);
+        }
+        .backface-hidden {
+            -webkit-backface-visibility: hidden;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function dumpLayers()
+        {
+            var layersResult = document.getElementById('layers');
+            if (window.testRunner)
+                layersResult.innerText = window.internals.layerTreeAsText(document);
+
+        }
+        window.addEventListener('load', dumpLayers, false)
+    </script>
+</head>
+<body>
+    <p>Should be no layers here.</p>
+    <div class="transformed container">
+        <div class="backface-hidden box"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>

Added: trunk/LayoutTests/compositing/backing/backface-visibility.html (0 => 168119)


--- trunk/LayoutTests/compositing/backing/backface-visibility.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/backing/backface-visibility.html	2014-05-01 20:56:21 UTC (rev 168119)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 100px;
+          height: 100px;
+          background-color: silver;
+        }
+        
+        .backface-hidden {
+            -webkit-backface-visibility: hidden;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        function dumpLayers()
+        {
+            var layersResult = document.getElementById('layers');
+            if (window.testRunner)
+                layersResult.innerText = window.internals.layerTreeAsText(document);
+
+        }
+        window.addEventListener('load', dumpLayers, false)
+    </script>
+</head>
+<body>
+    <p>Should be no layers here.</p>
+    <div class="backface-hidden box"></div>
+<pre id="layers"></pre>
+</body>
+</html>

Modified: trunk/LayoutTests/inspector-protocol/layers/layers-anonymous.html (168118 => 168119)


--- trunk/LayoutTests/inspector-protocol/layers/layers-anonymous.html	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/LayoutTests/inspector-protocol/layers/layers-anonymous.html	2014-05-01 20:56:21 UTC (rev 168119)
@@ -127,7 +127,7 @@
 
     #first-letter::first-letter {
         float: left;
-        -webkit-backface-visibility: hidden;
+        -webkit-transform: translateZ(0);
     }
 
 </style>

Modified: trunk/Source/WebCore/ChangeLog (168118 => 168119)


--- trunk/Source/WebCore/ChangeLog	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/Source/WebCore/ChangeLog	2014-05-01 20:56:21 UTC (rev 168119)
@@ -1,3 +1,35 @@
+2014-05-01  Simon Fraser  <simon.fra...@apple.com>
+
+        Don't always make backing store for -webkit-backface-visibility:hidden
+        https://bugs.webkit.org/show_bug.cgi?id=132420
+
+        Reviewed by Sam Weinig.
+        
+        Previously, -webkit-backface-visibility:hidden unconditionally created
+        compositing layers with backing store. This results in high memory use
+        on pages with this style applied to many elements (a cargo-cult "optimization").
+        
+        Fix by only having -webkit-backface-visibility:hidden create compositing layers
+        if some ancestor has a 3D transform. That's the only scenario in which the
+        element can be flipped around to reveal the back side, so the only time we need
+        to do compositing for this property. In future, we could be smarter, and only
+        consider 3D transforms in the current preserve-3d context.
+
+        Tests: compositing/backing/backface-visibility-in-3dtransformed.html
+               compositing/backing/backface-visibility-in-transformed.html
+               compositing/backing/backface-visibility.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::RenderLayer):
+        (WebCore::RenderLayer::updateLayerPositions):
+        (WebCore::RenderLayer::hitTestLayer):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+        (WebCore::RenderLayerCompositor::requiresOwnBackingStore):
+        (WebCore::RenderLayerCompositor::requiresCompositingForBackfaceVisibility):
+        * rendering/RenderLayerCompositor.h:
+
 2014-05-01  Alex Christensen  <achristen...@webkit.org>
 
         Finish updating ANGLE.

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (168118 => 168119)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2014-05-01 20:56:21 UTC (rev 168119)
@@ -169,6 +169,8 @@
     , m_3DTransformedDescendantStatusDirty(true)
     , m_has3DTransformedDescendant(false)
     , m_hasCompositingDescendant(false)
+    , m_hasTransformedAncestor(false)
+    , m_has3DTransformedAncestor(false)
     , m_indirectCompositingReason(NoIndirectCompositingReason)
     , m_viewportConstrainedNotCompositedReason(NoNotCompositedReason)
 #if PLATFORM(IOS)
@@ -449,6 +451,8 @@
         clearRepaintRects();
 
     m_repaintStatus = NeedsNormalRepaint;
+    m_hasTransformedAncestor = flags & SeenTransformedLayer;
+    m_has3DTransformedAncestor = flags & Seen3DTransformedLayer;
 
     // Go ahead and update the reflection's position and size.
     if (m_reflection)
@@ -467,6 +471,12 @@
     if (renderer().hasColumns())
         flags |= UpdatePagination;
 
+    if (transform()) {
+        flags |= SeenTransformedLayer;
+        if (!transform()->isAffine())
+            flags |= Seen3DTransformedLayer;
+    }
+
     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
         child->updateLayerPositions(geometryMap, flags);
 
@@ -4931,7 +4941,7 @@
         // We computed the correct state in the caller (above code), so just reference it.
         ASSERT(transformState);
         localTransformState = const_cast<HitTestingTransformState*>(transformState);
-    } else if (transformState || m_has3DTransformedDescendant || preserves3D()) {
+    } else if (transformState || has3DTransformedDescendant() || preserves3D()) {
         // We need transform state for the first time, or to offset the container state, so create it here.
         localTransformState = createLocalTransformState(rootLayer, containerLayer, hitTestRect, hitTestLocation, transformState);
     }

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (168118 => 168119)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2014-05-01 20:56:21 UTC (rev 168119)
@@ -499,7 +499,9 @@
         NeedsFullRepaintInBacking = 1 << 1,
         IsCompositingUpdateRoot = 1 << 2,
         UpdateCompositingLayers = 1 << 3,
-        UpdatePagination = 1 << 4
+        UpdatePagination = 1 << 4,
+        SeenTransformedLayer = 1 << 5,
+        Seen3DTransformedLayer = 1 << 6
     };
     typedef unsigned UpdateLayerPositionsFlags;
     static const UpdateLayerPositionsFlags defaultFlags = CheckForRepaint | IsCompositingUpdateRoot | UpdateCompositingLayers;
@@ -1113,10 +1115,11 @@
     void updateDescendantDependentFlags(HashSet<const RenderObject*>* outOfFlowDescendantContainingBlocks = 0);
     bool checkIfDescendantClippingContextNeedsUpdate(bool isClipping);
 
-    // This flag is computed by RenderLayerCompositor, which knows more about 3d hierarchies than we do.
-    void setHas3DTransformedDescendant(bool b) { m_has3DTransformedDescendant = b; }
     bool has3DTransformedDescendant() const { return m_has3DTransformedDescendant; }
-    
+
+    bool hasTransformedAncestor() const { return m_hasTransformedAncestor; }
+    bool has3DTransformedAncestor() const { return m_has3DTransformedAncestor; }
+
     void dirty3DTransformedDescendantStatus();
     // Both updates the status, and returns true if descendants of this have 3d.
     bool update3DTransformedDescendantStatus();
@@ -1253,6 +1256,10 @@
     bool m_has3DTransformedDescendant : 1;  // Set on a stacking context layer that has 3D descendants anywhere
                                             // in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
     bool m_hasCompositingDescendant : 1; // In the z-order tree.
+
+    bool m_hasTransformedAncestor : 1;
+    bool m_has3DTransformedAncestor : 1;
+
     unsigned m_indirectCompositingReason : 3;
     unsigned m_viewportConstrainedNotCompositedReason : 2;
 

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (168118 => 168119)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp	2014-05-01 20:56:21 UTC (rev 168119)
@@ -2032,7 +2032,7 @@
         || requiresCompositingForCanvas(*renderer)
         || requiresCompositingForPlugin(*renderer)
         || requiresCompositingForFrame(*renderer)
-        || (canRender3DTransforms() && renderer->style().backfaceVisibility() == BackfaceVisibilityHidden)
+        || requiresCompositingForBackfaceVisibility(*renderer)
         || clipsCompositingDescendants(*renderer->layer())
         || requiresCompositingForAnimation(*renderer)
         || requiresCompositingForFilters(*renderer)
@@ -2075,7 +2075,7 @@
         || requiresCompositingForCanvas(renderer)
         || requiresCompositingForPlugin(renderer)
         || requiresCompositingForFrame(renderer)
-        || (canRender3DTransforms() && renderer.style().backfaceVisibility() == BackfaceVisibilityHidden)
+        || requiresCompositingForBackfaceVisibility(renderer)
         || requiresCompositingForAnimation(renderer)
         || requiresCompositingForFilters(renderer)
         || requiresCompositingForPosition(renderer, layer)
@@ -2342,6 +2342,14 @@
     return renderer.hasTransform() && renderer.style().transform().has3DOperation();
 }
 
+bool RenderLayerCompositor::requiresCompositingForBackfaceVisibility(RenderLayerModelObject& renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
+        return false;
+
+    return renderer.style().backfaceVisibility() == BackfaceVisibilityHidden && renderer.layer()->has3DTransformedAncestor();
+}
+
 bool RenderLayerCompositor::requiresCompositingForVideo(RenderLayerModelObject& renderer) const
 {
     if (!(m_compositingTriggers & ChromeClient::VideoTrigger))

Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (168118 => 168119)


--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h	2014-05-01 20:56:21 UTC (rev 168119)
@@ -392,6 +392,7 @@
     // Whether a running transition or animation enforces the need for a compositing layer.
     bool requiresCompositingForAnimation(RenderLayerModelObject&) const;
     bool requiresCompositingForTransform(RenderLayerModelObject&) const;
+    bool requiresCompositingForBackfaceVisibility(RenderLayerModelObject&) const;
     bool requiresCompositingForVideo(RenderLayerModelObject&) const;
     bool requiresCompositingForCanvas(RenderLayerModelObject&) const;
     bool requiresCompositingForPlugin(RenderLayerModelObject&) const;

Modified: trunk/WebKit.xcworkspace/xcshareddata/xcschemes/All Source (target WebProcess).xcscheme (168118 => 168119)


--- trunk/WebKit.xcworkspace/xcshareddata/xcschemes/All Source (target WebProcess).xcscheme	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/WebKit.xcworkspace/xcshareddata/xcschemes/All Source (target WebProcess).xcscheme	2014-05-01 20:56:21 UTC (rev 168119)
@@ -115,9 +115,9 @@
             buildForAnalyzing = "YES">
             <BuildableReference
                BuildableIdentifier = "primary"
-               BlueprintIdentifier = "1AD7451818D0D26C006F3A1E"
-               BuildableName = "WebKit.framework"
-               BlueprintName = "WebKit"
+               BlueprintIdentifier = "9398100A0824BF01008DF038"
+               BuildableName = "WebKitLegacy.framework"
+               BlueprintName = "WebKitLegacy"
                ReferencedContainer = "container:Source/WebKit/WebKit.xcodeproj">
             </BuildableReference>
          </BuildActionEntry>

Modified: trunk/WebKit.xcworkspace/xcshareddata/xcschemes/All Source.xcscheme (168118 => 168119)


--- trunk/WebKit.xcworkspace/xcshareddata/xcschemes/All Source.xcscheme	2014-05-01 20:39:55 UTC (rev 168118)
+++ trunk/WebKit.xcworkspace/xcshareddata/xcschemes/All Source.xcscheme	2014-05-01 20:56:21 UTC (rev 168119)
@@ -115,9 +115,9 @@
             buildForAnalyzing = "YES">
             <BuildableReference
                BuildableIdentifier = "primary"
-               BlueprintIdentifier = "1AD7451818D0D26C006F3A1E"
-               BuildableName = "WebKit.framework"
-               BlueprintName = "WebKit"
+               BlueprintIdentifier = "9398100A0824BF01008DF038"
+               BuildableName = "WebKitLegacy.framework"
+               BlueprintName = "WebKitLegacy"
                ReferencedContainer = "container:Source/WebKit/WebKit.xcodeproj">
             </BuildableReference>
          </BuildActionEntry>
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to