Diff
Modified: trunk/LayoutTests/ChangeLog (141038 => 141039)
--- trunk/LayoutTests/ChangeLog 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/ChangeLog 2013-01-29 04:16:56 UTC (rev 141039)
@@ -1,3 +1,22 @@
+2013-01-28 Simon Fraser <simon.fra...@apple.com>
+
+ position:fixed that doesn't render any content should not force compositing
+ https://bugs.webkit.org/show_bug.cgi?id=108112
+
+ Reviewed by Beth Dakin.
+
+ Change tests to put a background color on position:fixed elements that need to be composited.
+ New test with an empty fixed position element.
+
+ * compositing/layer-creation/fixed-position-change-out-of-view-in-view.html:
+ * compositing/layer-creation/fixed-position-no-content-expected.txt: Added.
+ * compositing/layer-creation/fixed-position-no-content.html: Copied from LayoutTests/compositing/layer-creation/fixed-position-out-of-view.html.
+ * compositing/layer-creation/fixed-position-out-of-view-scaled-scroll.html:
+ * compositing/layer-creation/fixed-position-out-of-view-scaled.html:
+ * compositing/layer-creation/fixed-position-out-of-view.html:
+ * platform/mac/tiled-drawing/fixed/fixed-position-out-of-view-negative-zindex.html:
+ * platform/mac/tiled-drawing/fixed/fixed-position-out-of-view.html:
+
2013-01-28 Keishi Hattori <kei...@webkit.org>
[Chromium] Skipping mathml tests because MATHML was disasbled.
Modified: trunk/LayoutTests/compositing/layer-creation/fixed-position-change-out-of-view-in-view.html (141038 => 141039)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-change-out-of-view-in-view.html 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-change-out-of-view-in-view.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -2,6 +2,11 @@
<html>
<head>
+ <style>
+ #fixed1, #fixed2 {
+ background-color: silver;
+ }
+ </style>
<script type="text/_javascript_">
if (window.testRunner && window.internals) {
testRunner.dumpAsText();
Added: trunk/LayoutTests/compositing/layer-creation/fixed-position-no-content-expected.txt (0 => 141039)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-no-content-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-no-content-expected.txt 2013-01-29 04:16:56 UTC (rev 141039)
@@ -0,0 +1,3 @@
+There should be no layers.
+
+
Copied: trunk/LayoutTests/compositing/layer-creation/fixed-position-no-content.html (from rev 141038, trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view.html) (0 => 141039)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-no-content.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-no-content.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <style>
+ .fixed {
+ position: fixed;
+ width: 50px;
+ height: 50px;
+ }
+
+ .absolute {
+ position: absolute;
+ top: 40px;
+ left: 40px;
+ height: 100px;
+ width: 100px;
+ background-color: gray;
+ }
+ </style>
+
+ <script type="text/_javascript_">
+ if (window.internals)
+ window.internals.settings.setAcceleratedCompositingForFixedPositionEnabled(true);
+
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+
+ window.addEventListener("load", function() {
+ document.getElementById("layertree").innerText = window.internals.layerTreeAsText(document);
+ }, false);
+ }
+ </script>
+</head>
+
+<body>
+ <div style="height: 1000px">
+ <p>There should be no layers.</p>
+ <pre id="layertree"></pre>
+ </div>
+
+ <!-- This should not be composited -->
+ <div class="fixed" style="top: 10px; left: 10px"></div>
+ <!-- And this should not be promoted into a layer -->
+ <div class="absolute"></div>
+</body>
+</html>
+
Modified: trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scaled-scroll.html (141038 => 141039)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scaled-scroll.html 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scaled-scroll.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -6,6 +6,7 @@
position: fixed;
width: 10px;
height: 10px;
+ background-color: silver;
}
</style>
<script>
Modified: trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scaled.html (141038 => 141039)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scaled.html 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scaled.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -6,6 +6,7 @@
position: fixed;
width: 10px;
height: 10px;
+ background-color: silver;
}
</style>
<script>
Modified: trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view.html (141038 => 141039)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view.html 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -7,6 +7,7 @@
position: fixed;
width: 10px;
height: 10px;
+ background-color: silver;
}
</style>
Modified: trunk/LayoutTests/platform/mac/tiled-drawing/fixed/fixed-position-out-of-view-negative-zindex.html (141038 => 141039)
--- trunk/LayoutTests/platform/mac/tiled-drawing/fixed/fixed-position-out-of-view-negative-zindex.html 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/platform/mac/tiled-drawing/fixed/fixed-position-out-of-view-negative-zindex.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -7,6 +7,7 @@
position: fixed;
width: 10px;
height: 10px;
+ background-color: silver;
}
</style>
Modified: trunk/LayoutTests/platform/mac/tiled-drawing/fixed/fixed-position-out-of-view.html (141038 => 141039)
--- trunk/LayoutTests/platform/mac/tiled-drawing/fixed/fixed-position-out-of-view.html 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/LayoutTests/platform/mac/tiled-drawing/fixed/fixed-position-out-of-view.html 2013-01-29 04:16:56 UTC (rev 141039)
@@ -7,6 +7,7 @@
position: fixed;
width: 10px;
height: 10px;
+ background-color: silver;
}
</style>
Modified: trunk/Source/WebCore/ChangeLog (141038 => 141039)
--- trunk/Source/WebCore/ChangeLog 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/Source/WebCore/ChangeLog 2013-01-29 04:16:56 UTC (rev 141039)
@@ -1,5 +1,45 @@
2013-01-28 Simon Fraser <simon.fra...@apple.com>
+ position:fixed that doesn't render any content should not force compositing
+ https://bugs.webkit.org/show_bug.cgi?id=108112
+
+ Reviewed by Beth Dakin.
+
+ It's not uncommon for pages to have position:fixed elements with no content.
+ When these are behind other elements, they can cause those other elements
+ to become composited, using lots of backing store memory.
+
+ Optimize for the case where the position:fixed element has no rendered
+ content and no children by not making it composited in that case.
+
+ Test: compositing/layer-creation/fixed-position-no-content.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::hasNonEmptyChildRenderers): Moved from RenderLayerBacking.cpp.
+ (WebCore::hasBoxDecorations): Ditto.
+ (WebCore::RenderLayer::hasBoxDecorationsOrBackground): Ditto.
+ (WebCore::RenderLayer::hasVisibleBoxDecorations): Check for visibility:visible, box decorations and
+ overflow controls.
+ (WebCore::RenderLayer::isVisuallyNonEmpty): Returns true if this layer has some visible
+ representation.
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerBacking.cpp:
+ (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Need to call updateDescendantDependentFlags()
+ to ensure that the visibility flags are up to date.
+ (WebCore::RenderLayerBacking::updateDrawsContent): Call RenderLayer::hasBoxDecorationsOrBackground() now.
+ (WebCore::RenderLayerBacking::paintsBoxDecorations): Call RenderLayer::hasVisibleBoxDecorations() now.
+ (WebCore::RenderLayerBacking::paintsChildren): Call RenderLayer::hasNonEmptyChildRenderers().
+ (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer): Whitespace.
+ (WebCore::RenderLayerBacking::containsPaintedContent): Call RenderLayer::hasBoxDecorationsOrBackground().
+ (WebCore::RenderLayerBacking::isDirectlyCompositedImage): Ditto.
+ * rendering/RenderLayerBacking.h:
+ (RenderLayerBacking):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::requiresCompositingForPosition): If the layer has no content to paint,
+ or visible descendant layers, then don't make it composited.
+
+2013-01-28 Simon Fraser <simon.fra...@apple.com>
+
Avoid doing work at 60fps for tiled layers when not necessary
https://bugs.webkit.org/show_bug.cgi?id=108135
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (141038 => 141039)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2013-01-29 04:16:56 UTC (rev 141039)
@@ -5404,6 +5404,59 @@
parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
}
+bool RenderLayer::hasNonEmptyChildRenderers() const
+{
+ // 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;
+
+ if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool hasBoxDecorations(const RenderStyle* style)
+{
+ return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
+}
+
+bool RenderLayer::hasBoxDecorationsOrBackground() const
+{
+ return hasBoxDecorations(renderer()->style()) || renderer()->hasBackground();
+}
+
+bool RenderLayer::hasVisibleBoxDecorations() const
+{
+ if (!hasVisibleContent())
+ return false;
+
+ return hasBoxDecorationsOrBackground() || hasOverflowControls();
+}
+
+bool RenderLayer::isVisuallyNonEmpty() const
+{
+ ASSERT(!m_visibleDescendantStatusDirty);
+
+ if (hasVisibleContent() && hasNonEmptyChildRenderers())
+ return true;
+
+ if (renderer()->isReplaced() || renderer()->hasMask())
+ return true;
+
+ if (hasVisibleBoxDecorations())
+ return true;
+
+ return false;
+}
+
void RenderLayer::updateStackingContextsAfterStyleChange(const RenderStyle* oldStyle)
{
if (!oldStyle)
Modified: trunk/Source/WebCore/rendering/RenderLayer.h (141038 => 141039)
--- trunk/Source/WebCore/rendering/RenderLayer.h 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/Source/WebCore/rendering/RenderLayer.h 2013-01-29 04:16:56 UTC (rev 141039)
@@ -473,6 +473,13 @@
void setHasVisibleContent();
void dirtyVisibleContentStatus();
+ bool hasBoxDecorationsOrBackground() const;
+ bool hasVisibleBoxDecorations() const;
+ // Returns true if this layer has visible content (ignoring any child layers).
+ bool isVisuallyNonEmpty() const;
+ // True if this layer container renderers that paint.
+ bool hasNonEmptyChildRenderers() const;
+
// FIXME: We should ASSERT(!m_hasSelfPaintingLayerDescendantDirty); here but we hit the same bugs as visible content above.
// Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates.
bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; }
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (141038 => 141039)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp 2013-01-29 04:16:56 UTC (rev 141039)
@@ -76,8 +76,6 @@
using namespace HTMLNames;
-static bool hasBoxDecorations(const RenderStyle*);
-static bool hasBoxDecorationsOrBackground(const RenderObject*);
static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
static IntRect clipBox(RenderBox* renderer);
@@ -474,6 +472,7 @@
RenderLayerCompositor* compositor = this->compositor();
RenderObject* renderer = this->renderer();
+ m_owningLayer->updateDescendantDependentFlags();
m_owningLayer->updateZOrderLists();
bool layerConfigChanged = false;
@@ -912,7 +911,7 @@
// m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
// m_scrollingLayer never has backing store.
// m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
- bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && hasBoxDecorationsOrBackground(renderer());
+ bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && m_owningLayer->hasBoxDecorationsOrBackground();
m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
@@ -1284,11 +1283,6 @@
return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
}
-static bool hasBoxDecorationsOrBackground(const RenderObject* renderer)
-{
- return hasBoxDecorations(renderer->style()) || renderer->hasBackground();
-}
-
static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
{
return hasBoxDecorations(style) || style->hasBackgroundImage();
@@ -1365,24 +1359,18 @@
bool RenderLayerBacking::paintsBoxDecorations() const
{
- if (!m_owningLayer->hasVisibleContent())
+ if (!m_owningLayer->hasVisibleBoxDecorations())
return false;
- if (!hasBoxDecorationsOrBackground(renderer()))
- return false;
-
if (!supportsDirectBoxDecorationsComposition(renderer()))
return true;
- if (m_owningLayer->hasOverflowControls())
- return true;
-
return false;
}
bool RenderLayerBacking::paintsChildren() const
{
- if (m_owningLayer->hasVisibleContent() && containsNonEmptyRenderers())
+ if (m_owningLayer->hasVisibleContent() && m_owningLayer->hasNonEmptyChildRenderers())
return true;
if (hasVisibleNonCompositingDescendantLayers())
@@ -1406,7 +1394,7 @@
return false;
if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
- return false;
+ return false;
if (paintsBoxDecorations() || paintsChildren())
return false;
@@ -1439,25 +1427,6 @@
return true;
}
-bool RenderLayerBacking::containsNonEmptyRenderers() const
-{
- // 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;
-
- if (toRenderBox(child)->width() > 0 || toRenderBox(child)->height() > 0)
- return true;
- }
- }
- return false;
-}
-
// Conservative test for having no rendered children.
bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
{
@@ -1516,12 +1485,12 @@
// and set background color on the layer in that case, instead of allocating backing store and painting.
#if ENABLE(VIDEO)
if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
- return hasBoxDecorationsOrBackground(renderer());
+ return m_owningLayer->hasBoxDecorationsOrBackground();
#endif
#if PLATFORM(MAC) && USE(CA) && (PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
#elif ENABLE(WEBGL) || ENABLE(ACCELERATED_2D_CANVAS)
if (isAcceleratedCanvas(renderer()))
- return hasBoxDecorationsOrBackground(renderer());
+ return m_owningLayer->hasBoxDecorationsOrBackground();
#endif
return true;
@@ -1533,7 +1502,7 @@
{
RenderObject* renderObject = renderer();
- if (!renderObject->isImage() || hasBoxDecorationsOrBackground(renderObject) || renderObject->hasClip())
+ if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip())
return false;
RenderImage* imageRenderer = toRenderImage(renderObject);
Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (141038 => 141039)
--- trunk/Source/WebCore/rendering/RenderLayerBacking.h 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h 2013-01-29 04:16:56 UTC (rev 141039)
@@ -152,7 +152,7 @@
void adjustTileCacheCoverage();
void updateDebugIndicators(bool showBorder, bool showRepaintCounter);
-
+
// GraphicsLayerClient interface
virtual bool shouldUseTileCache(const GraphicsLayer*) const OVERRIDE;
virtual void notifyAnimationStarted(const GraphicsLayer*, double startTime) OVERRIDE;
@@ -256,7 +256,6 @@
void updateBackgroundColor(bool isSimpleContainer);
void updateContentsRect(bool isSimpleContainer);
- bool containsNonEmptyRenderers() const;
bool hasVisibleNonCompositingDescendantLayers() const;
bool shouldClipCompositedBounds() const;
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (141038 => 141039)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2013-01-29 03:51:54 UTC (rev 141038)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2013-01-29 04:16:56 UTC (rev 141039)
@@ -2077,6 +2077,13 @@
return false;
}
}
+
+ bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant();
+ if (!paintsContent) {
+ // isVisuallyNonEmpty() depends on layout.
+ m_reevaluateCompositingAfterLayout = true;
+ return false;
+ }
return true;
}