Diff
Modified: branches/safari-600.3-branch/LayoutTests/ChangeLog (176241 => 176242)
--- branches/safari-600.3-branch/LayoutTests/ChangeLog 2014-11-18 02:21:39 UTC (rev 176241)
+++ branches/safari-600.3-branch/LayoutTests/ChangeLog 2014-11-18 02:25:46 UTC (rev 176242)
@@ -1,3 +1,22 @@
+2014-11-17 Dana Burkart <[email protected]>
+
+ Merge r173293. <rdar://problem/18978414>
+
+ 2014-09-04 Simon Fraser <[email protected]>
+
+ Improve the logic for compositing backing store avoidance
+ https://bugs.webkit.org/show_bug.cgi?id=136556
+
+ Reviewed by Dean Jackson.
+
+ Tests that dump the layer tree (showing backing store) for various combinations
+ of child renderers and whitespace.
+
+ * compositing/backing/inline-block-no-backing-expected.txt: Added.
+ * compositing/backing/inline-block-no-backing.html: Added.
+ * compositing/backing/whitespace-nodes-no-backing-expected.txt: Added.
+ * compositing/backing/whitespace-nodes-no-backing.html: Added.
+
2014-11-05 Dana Burkart <[email protected]>
Merge r174740. <rdar://problem/18883801>
Copied: branches/safari-600.3-branch/LayoutTests/compositing/backing/inline-block-no-backing-expected.txt (from rev 173293, trunk/LayoutTests/compositing/backing/inline-block-no-backing-expected.txt) (0 => 176242)
--- branches/safari-600.3-branch/LayoutTests/compositing/backing/inline-block-no-backing-expected.txt (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/compositing/backing/inline-block-no-backing-expected.txt 2014-11-18 02:25:46 UTC (rev 176242)
@@ -0,0 +1,58 @@
+
+
+ (GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 3
+ (GraphicsLayer
+ (position 18.00 18.00)
+ (bounds 160.00 320.00)
+ (drawsContent 1)
+ (children 2
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 120.00 120.00)
+ )
+ (GraphicsLayer
+ (position 10.00 154.00)
+ (bounds 120.00 120.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 202.00 18.00)
+ (bounds 160.00 320.00)
+ (children 2
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 120.00 120.00)
+ )
+ (GraphicsLayer
+ (position 10.00 154.00)
+ (bounds 120.00 120.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 386.00 18.00)
+ (bounds 160.00 320.00)
+ (children 2
+ (GraphicsLayer
+ (position 10.00 10.00)
+ (bounds 120.00 120.00)
+ )
+ (GraphicsLayer
+ (position 10.00 154.00)
+ (bounds 120.00 120.00)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Copied: branches/safari-600.3-branch/LayoutTests/compositing/backing/inline-block-no-backing.html (from rev 173293, trunk/LayoutTests/compositing/backing/inline-block-no-backing.html) (0 => 176242)
--- branches/safari-600.3-branch/LayoutTests/compositing/backing/inline-block-no-backing.html (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/compositing/backing/inline-block-no-backing.html 2014-11-18 02:25:46 UTC (rev 176242)
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .container {
+ display: inline-block;
+ height: 320px;
+ width: 160px;
+ margin: 10px;
+ }
+
+ .composited {
+ -webkit-transform: translateZ(0);
+ }
+
+ .child {
+ position: relative;
+ height: 120px;
+ width: 120px;
+ margin: 10px;
+ }
+
+ .box {
+ height: 100px;
+ width: 100px;
+ background-color: blue;
+ }
+ </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>
+ <div class="composited container">
+ <img class="composited child" src=""
+ <img class="composited child" src=""
+ </div>
+
+ <div class="composited container" style="-webkit-user-select: none;">
+ <img class="composited child" src=""
+ <img class="composited child" src=""
+ </div>
+
+ <div class="composited container" style="-webkit-user-select: none;">
+ <img class="composited child" src=""
+ <div style="inline-block">
+ <img class="composited child" src=""
+ </div>
+ </div>
+
+<pre id="layers">Layer tree goes here in DRT</pre>
+</body>
+</html>
Copied: branches/safari-600.3-branch/LayoutTests/compositing/backing/whitespace-nodes-no-backing-expected.txt (from rev 173293, trunk/LayoutTests/compositing/backing/whitespace-nodes-no-backing-expected.txt) (0 => 176242)
--- branches/safari-600.3-branch/LayoutTests/compositing/backing/whitespace-nodes-no-backing-expected.txt (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/compositing/backing/whitespace-nodes-no-backing-expected.txt 2014-11-18 02:25:46 UTC (rev 176242)
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+span
+inner span
+
+ (GraphicsLayer
+ (anchor 0.00 0.00)
+ (bounds 800.00 600.00)
+ (children 1
+ (GraphicsLayer
+ (bounds 800.00 600.00)
+ (contentsOpaque 1)
+ (children 9
+ (GraphicsLayer
+ (position 10.00 8.00)
+ (bounds 780.00 58.00)
+ (drawsContent 1)
+ (children 2
+ (GraphicsLayer
+ (position 2.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ (GraphicsLayer
+ (position 60.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 68.00)
+ (bounds 780.00 58.00)
+ (children 2
+ (GraphicsLayer
+ (position 2.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ (GraphicsLayer
+ (position 60.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 128.00)
+ (bounds 780.00 58.00)
+ (children 1
+ (GraphicsLayer
+ (position 2.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 188.00)
+ (bounds 780.00 58.00)
+ (children 1
+ (GraphicsLayer
+ (position 2.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 248.00)
+ (bounds 780.00 78.00)
+ (drawsContent 1)
+ (children 1
+ (GraphicsLayer
+ (position 2.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ )
+ )
+ (GraphicsLayer
+ (position 10.00 328.00)
+ (bounds 780.00 54.00)
+ (drawsContent 1)
+ )
+ (GraphicsLayer
+ (position 10.00 384.00)
+ (bounds 780.00 18.00)
+ (drawsContent 1)
+ )
+ (GraphicsLayer
+ (position 10.00 404.00)
+ (bounds 780.00 18.00)
+ (drawsContent 1)
+ )
+ (GraphicsLayer
+ (position 10.00 424.00)
+ (bounds 780.00 78.00)
+ (children 2
+ (GraphicsLayer
+ (position 2.00 2.00)
+ (bounds 50.00 50.00)
+ )
+ (GraphicsLayer
+ (position 0.00 58.00)
+ (bounds 20.00 20.00)
+ (contentsOpaque 1)
+ )
+ )
+ )
+ )
+ )
+ )
+)
+
Copied: branches/safari-600.3-branch/LayoutTests/compositing/backing/whitespace-nodes-no-backing.html (from rev 173293, trunk/LayoutTests/compositing/backing/whitespace-nodes-no-backing.html) (0 => 176242)
--- branches/safari-600.3-branch/LayoutTests/compositing/backing/whitespace-nodes-no-backing.html (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/compositing/backing/whitespace-nodes-no-backing.html 2014-11-18 02:25:46 UTC (rev 176242)
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .container {
+ margin: 2px;
+ }
+
+ .composited {
+ -webkit-transform: translateZ(0);
+ }
+
+ .child {
+ position: relative;
+ margin: 2px;
+ }
+
+ img {
+ height: 50px;
+ width: 50px;
+ }
+ .box {
+ height: 20px;
+ width: 20px;
+ background-color: blue;
+ }
+ </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>
+ <div class="composited container">
+ <img class="composited child" src=""
+ <img class="composited child" src=""
+ </div>
+
+ <div class="composited container" style="-webkit-user-select: none;">
+ <img class="composited child" src=""
+ <img class="composited child" src=""
+ </div>
+
+ <div class="composited container"><img class="composited child" src=""
+
+ <div class="composited container" style="-webkit-user-select: none;">
+ <img class="composited child" src=""
+ </div>
+
+ <div class="composited container">
+ <img class="composited child" src="" class="box"></div>
+ </div>
+
+ <div class="composited container">
+ <img src=""
+ </div>
+
+ <div class="composited container">
+ <span>span<span>
+ </div>
+
+ <div class="composited container">
+ <span><span>inner span<span></span>
+ </div>
+
+ <div class="composited container" style="-webkit-user-select: none;">
+ <span><img class="composited child" src="" class="composited box"></div><span>
+ </div>
+
+<pre id="layers">Layer tree goes here in DRT</pre>
+</body>
+</html>
Modified: branches/safari-600.3-branch/Source/WebCore/ChangeLog (176241 => 176242)
--- branches/safari-600.3-branch/Source/WebCore/ChangeLog 2014-11-18 02:21:39 UTC (rev 176241)
+++ branches/safari-600.3-branch/Source/WebCore/ChangeLog 2014-11-18 02:25:46 UTC (rev 176242)
@@ -1,5 +1,41 @@
2014-11-17 Dana Burkart <[email protected]>
+ Merge r173293. <rdar://problem/18978414>
+
+ 2014-09-04 Simon Fraser <[email protected]>
+
+ Improve the logic for compositing backing store avoidance
+ https://bugs.webkit.org/show_bug.cgi?id=136556
+
+ Reviewed by Dean Jackson.
+
+ Avoid backing store allocation in more cases by improving the logic that detects
+ whether a RenderLayer has any painted, non-layer descendent renderers.
+
+ Rename RenderLayer::hasNonEmptyChildRenderers() to hasPaintingNonLayerDescendants(),
+ and make it recur 3 levels deep, walking child lists of up to 20 siblings looking
+ for renderers that paint anything. Any renderer with box decorations paints;
+ replaced elements paint, and non-whitespace text nodes paint. We can avoid
+ making backing store when whitespace nodes are present only when user-select is none,
+ since we have to ensure that there's backing store to paint the selection into.
+
+ Tests: compositing/backing/inline-block-no-backing.html
+ compositing/backing/whitespace-nodes-no-backing.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hasNonEmptyChildRenderers): Call the recursive hasPaintingNonLayerDescendants().
+ (WebCore::RenderLayer::hasBoxDecorationsOrBackground):
+ (WebCore::RenderLayer::isVisuallyNonEmpty): Do the cheap tests first. Use isRenderReplaced()
+ rather than isReplaced(), since the latter includes inline-blocks.
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateConfiguration): Don't run the isSimpleContainerCompositingLayer()
+ logic in the root layer, since it always wants backing store.
+ (WebCore::RenderLayerBacking::updateAfterDescendents): Ditto.
+ (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer): isReplaced() includes
+ inline-block, so use isRenderReplaced() instead.
+
+2014-11-17 Dana Burkart <[email protected]>
+
Merge r176156. <rdar://problem/18877535>
2014-11-15 David Kilzer <[email protected]>
Modified: branches/safari-600.3-branch/Source/WebCore/rendering/RenderLayer.cpp (176241 => 176242)
--- branches/safari-600.3-branch/Source/WebCore/rendering/RenderLayer.cpp 2014-11-18 02:21:39 UTC (rev 176241)
+++ branches/safari-600.3-branch/Source/WebCore/rendering/RenderLayer.cpp 2014-11-18 02:25:46 UTC (rev 176242)
@@ -94,6 +94,7 @@
#include "RenderScrollbarPart.h"
#include "RenderTableCell.h"
#include "RenderTableRow.h"
+#include "RenderText.h"
#include "RenderTheme.h"
#include "RenderTreeAsText.h"
#include "RenderView.h"
@@ -6201,33 +6202,66 @@
parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
}
-bool RenderLayer::hasNonEmptyChildRenderers() const
+// FIXME: use RenderObject::hasBoxDecorations(). And why hasBorderRadius() and filter?
+static bool hasBoxDecorations(const RenderStyle& style)
{
- // Some HTML can cause whitespace text nodes to have renderers, like:
- // <div>
- // <img src=""
- // </div>
- // so test for 0x0 RenderTexts here
- for (RenderObject* child = renderer().firstChild(); child; child = child->nextSibling()) {
- if (!child->hasLayer()) {
- if (child->isRenderInline() || !child->isBox())
- return true;
+ return style.hasBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
+}
+
+static bool hasBoxDecorationsOrBackground(const RenderElement& renderer)
+{
+ return hasBoxDecorations(renderer.style()) || renderer.hasBackground();
+}
+
+// Constrain the depth and breadth of the search for performance.
+static const int maxDescendentDepth = 3;
+static const int maxSiblingCount = 20;
+
+static bool hasPaintingNonLayerDescendants(const RenderElement& renderer, int depth)
+{
+ if (depth > maxDescendentDepth)
+ return true;
+
+ int siblingCount = 0;
+ for (const auto& child : childrenOfType<RenderObject>(renderer)) {
+ if (++siblingCount > maxSiblingCount)
+ return true;
- if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
+ if (child.isText()) {
+ bool isSelectable = renderer.style().userSelect() != SELECT_NONE;
+ if (isSelectable || !toRenderText(child).isAllCollapsibleWhitespace())
return true;
}
+
+ if (!child.isRenderElement())
+ continue;
+
+ const RenderElement& renderElementChild = toRenderElement(child);
+
+ if (renderElementChild.isRenderLayerModelObject() && toRenderLayerModelObject(renderElementChild).hasSelfPaintingLayer())
+ continue;
+
+ if (hasBoxDecorationsOrBackground(renderElementChild))
+ return true;
+
+ if (renderElementChild.isRenderReplaced())
+ return true;
+
+ if (hasPaintingNonLayerDescendants(renderElementChild, depth + 1))
+ return true;
}
+
return false;
}
-static bool hasBoxDecorations(const RenderStyle& style)
+bool RenderLayer::hasNonEmptyChildRenderers() const
{
- return style.hasBorder() || style.hasBorderRadius() || style.hasOutline() || style.hasAppearance() || style.boxShadow() || style.hasFilter();
+ return hasPaintingNonLayerDescendants(renderer(), 0);
}
bool RenderLayer::hasBoxDecorationsOrBackground() const
{
- return hasBoxDecorations(renderer().style()) || renderer().hasBackground();
+ return WebCore::hasBoxDecorationsOrBackground(renderer());
}
bool RenderLayer::hasVisibleBoxDecorations() const
@@ -6245,13 +6279,13 @@
if (!hasVisibleContent())
return false;
- if (hasNonEmptyChildRenderers())
+ if (renderer().isRenderReplaced() || hasOverflowControls())
return true;
- if (renderer().isReplaced())
+ if (hasBoxDecorationsOrBackground())
return true;
-
- if (hasVisibleBoxDecorations())
+
+ if (hasNonEmptyChildRenderers())
return true;
return false;
Modified: branches/safari-600.3-branch/Source/WebCore/rendering/RenderLayerBacking.cpp (176241 => 176242)
--- branches/safari-600.3-branch/Source/WebCore/rendering/RenderLayerBacking.cpp 2014-11-18 02:21:39 UTC (rev 176241)
+++ branches/safari-600.3-branch/Source/WebCore/rendering/RenderLayerBacking.cpp 2014-11-18 02:25:46 UTC (rev 176242)
@@ -571,11 +571,12 @@
} else
m_graphicsLayer->setReplicatedByLayer(0);
- bool isSimpleContainer = isSimpleContainerCompositingLayer();
- bool didUpdateContentsRect = false;
- updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
-
- updateRootLayerConfiguration();
+ if (!m_owningLayer.isRootLayer()) {
+ bool isSimpleContainer = isSimpleContainerCompositingLayer();
+ bool didUpdateContentsRect = false;
+ updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
+ } else
+ updateRootLayerConfiguration();
if (isDirectlyCompositedImage())
updateImageContents();
@@ -966,11 +967,15 @@
void RenderLayerBacking::updateAfterDescendents()
{
- bool didUpdateContentsRect = false;
- bool isSimpleContainer = isSimpleContainerCompositingLayer();
- updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
- if (!didUpdateContentsRect && m_graphicsLayer->usesContentsLayer())
- resetContentsRect();
+ bool isSimpleContainer = false;
+ if (!m_owningLayer.isRootLayer()) {
+ bool didUpdateContentsRect = false;
+ // FIXME: this duplicates work we did in updateConfiguration().
+ isSimpleContainer = isSimpleContainerCompositingLayer();
+ updateDirectlyCompositedContents(isSimpleContainer, didUpdateContentsRect);
+ if (!didUpdateContentsRect && m_graphicsLayer->usesContentsLayer())
+ resetContentsRect();
+ }
updateDrawsContent(isSimpleContainer);
@@ -1703,7 +1708,7 @@
// This is a useful optimization, because it allows us to avoid allocating backing store.
bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
{
- if (renderer().isReplaced() && (!isCompositedPlugin(&renderer()) || isRestartedPlugin(&renderer())))
+ if (renderer().isRenderReplaced() && (!isCompositedPlugin(&renderer()) || isRestartedPlugin(&renderer())))
return false;
if (paintsBoxDecorations() || paintsChildren())