Diff
Modified: branches/safari-534.52-branch/LayoutTests/ChangeLog (98151 => 98152)
--- branches/safari-534.52-branch/LayoutTests/ChangeLog 2011-10-21 21:16:03 UTC (rev 98151)
+++ branches/safari-534.52-branch/LayoutTests/ChangeLog 2011-10-21 21:22:50 UTC (rev 98152)
@@ -1,5 +1,21 @@
2011-10-21 Lucas Forschler <lforsch...@apple.com>
+ Merge 98060
+
+ 2011-10-20 Simon Fraser <simon.fra...@apple.com>
+
+ Hidden composited iframes cause infinite loop
+ https://bugs.webkit.org/show_bug.cgi?id=52655
+
+ Reviewed by Darin Adler.
+
+ Test with a visibility:hidden iframe, whose subframe becomes composited.
+
+ * compositing/visibility/hidden-iframe-expected.txt: Added.
+ * compositing/visibility/hidden-iframe.html: Added.
+
+2011-10-21 Lucas Forschler <lforsch...@apple.com>
+
Merge 97821
2011-10-18 Anders Carlsson <ander...@apple.com>
Deleted: branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe-expected.txt (98060 => 98152)
--- trunk/LayoutTests/compositing/visibility/hidden-iframe-expected.txt 2011-10-21 03:02:05 UTC (rev 98060)
+++ branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe-expected.txt 2011-10-21 21:22:50 UTC (rev 98152)
@@ -1,3 +0,0 @@
-PASS: test did not hang.
-
-
Copied: branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe-expected.txt (from rev 98060, trunk/LayoutTests/compositing/visibility/hidden-iframe-expected.txt) (0 => 98152)
--- branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe-expected.txt (rev 0)
+++ branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe-expected.txt 2011-10-21 21:22:50 UTC (rev 98152)
@@ -0,0 +1,3 @@
+PASS: test did not hang.
+
+
Deleted: branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe.html (98060 => 98152)
--- trunk/LayoutTests/compositing/visibility/hidden-iframe.html 2011-10-21 03:02:05 UTC (rev 98060)
+++ branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe.html 2011-10-21 21:22:50 UTC (rev 98152)
@@ -1,31 +0,0 @@
-<html>
- <head>
- <style>
- iframe {
- visibility: hidden;
- position: absolute;
- }
- </style>
- <script>
- if (window.layoutTestController) {
- layoutTestController.dumpAsText();
- layoutTestController.waitUntilDone();
- }
-
- // Called from subframe.
- function testDone()
- {
- // This timeout is necessary to detect the hang.
- window.setTimeout(function() {
- document.getElementById('results').innerText = 'PASS: test did not hang.';
- if (window.layoutTestController)
- layoutTestController.notifyDone();
- }, 0);
- }
- </script>
- </head>
- <body>
- <p id="results">This test should not hang.</p>
- <iframe src=""
- </body>
-</html>
Copied: branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe.html (from rev 98060, trunk/LayoutTests/compositing/visibility/hidden-iframe.html) (0 => 98152)
--- branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe.html (rev 0)
+++ branches/safari-534.52-branch/LayoutTests/compositing/visibility/hidden-iframe.html 2011-10-21 21:22:50 UTC (rev 98152)
@@ -0,0 +1,31 @@
+<html>
+ <head>
+ <style>
+ iframe {
+ visibility: hidden;
+ position: absolute;
+ }
+ </style>
+ <script>
+ if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+ }
+
+ // Called from subframe.
+ function testDone()
+ {
+ // This timeout is necessary to detect the hang.
+ window.setTimeout(function() {
+ document.getElementById('results').innerText = 'PASS: test did not hang.';
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+ }, 0);
+ }
+ </script>
+ </head>
+ <body>
+ <p id="results">This test should not hang.</p>
+ <iframe src=""
+ </body>
+</html>
Modified: branches/safari-534.52-branch/Source/WebCore/ChangeLog (98151 => 98152)
--- branches/safari-534.52-branch/Source/WebCore/ChangeLog 2011-10-21 21:16:03 UTC (rev 98151)
+++ branches/safari-534.52-branch/Source/WebCore/ChangeLog 2011-10-21 21:22:50 UTC (rev 98152)
@@ -1,5 +1,50 @@
2011-10-21 Lucas Forschler <lforsch...@apple.com>
+ Merge 98060
+
+ 2011-10-20 Simon Fraser <simon.fra...@apple.com>
+
+ Hidden composited iframes cause infinite loop
+ https://bugs.webkit.org/show_bug.cgi?id=52655
+
+ Reviewed by Darin Adler.
+
+ visibility:hidden is problematic for compositing, because it causes
+ RenderLayers to be removed from the z-order layer tree. This confuses
+ RenderLayerCompositor in several ways; it never sees these layers
+ when traversing the tree as it computes compositing requirements, or
+ rebuilds the layer tree.
+
+ This is a particular problem with composited iframes. When an iframe
+ becomes composited, scheduleSetNeedsStyleRecalc() is called on that
+ iframe's ownerElement in the parent document. If this happens inside
+ Document::updateStyleForAllDocuments(), we get into an infinite loop
+ because notifyIFramesOfCompositingChange() queues up style update as we
+ bounce in and out of compositing mode, so documentsThatNeedStyleRecalc
+ never empties out.
+
+ This is an initial, conservative fix that doesn't attempt to fix all
+ the issues with visibility. It changes RenderLayerCompositor to count
+ the number of compositing RenderLayers, and to not leave compositing
+ mode if there are any (even if they are hidden, so not hit while
+ traversing the z-order tree). This avoids the infinite loop.
+
+ Test: compositing/visibility/hidden-iframe.html
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::ensureBacking):
+ (WebCore::RenderLayer::clearBacking):
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::RenderLayerCompositor):
+ (WebCore::RenderLayerCompositor::hasAnyAdditionalCompositedLayers):
+ (WebCore::RenderLayerCompositor::updateCompositingLayers):
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+ * rendering/RenderLayerCompositor.h:
+ (WebCore::RenderLayerCompositor::layerBecameComposited):
+ (WebCore::RenderLayerCompositor::layerBecameNonComposited):
+
+2011-10-21 Lucas Forschler <lforsch...@apple.com>
+
Merge 97821
2011-10-18 Anders Carlsson <ander...@apple.com>
Modified: branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayer.cpp (98151 => 98152)
--- branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayer.cpp 2011-10-21 21:16:03 UTC (rev 98151)
+++ branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayer.cpp 2011-10-21 21:22:50 UTC (rev 98152)
@@ -3657,13 +3657,17 @@
#if USE(ACCELERATED_COMPOSITING)
RenderLayerBacking* RenderLayer::ensureBacking()
{
- if (!m_backing)
+ if (!m_backing) {
m_backing = adoptPtr(new RenderLayerBacking(this));
+ compositor()->layerBecameComposited(this);
+ }
return m_backing.get();
}
void RenderLayer::clearBacking()
{
+ if (m_backing && !renderer()->documentBeingDestroyed())
+ compositor()->layerBecameNonComposited(this);
m_backing.clear();
}
Modified: branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayerCompositor.cpp (98151 => 98152)
--- branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayerCompositor.cpp 2011-10-21 21:16:03 UTC (rev 98151)
+++ branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayerCompositor.cpp 2011-10-21 21:22:50 UTC (rev 98152)
@@ -95,6 +95,7 @@
, m_updateCompositingLayersTimer(this, &RenderLayerCompositor::updateCompositingLayersTimerFired)
, m_hasAcceleratedCompositing(true)
, m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
+ , m_compositedLayerCount(0)
, m_showDebugBorders(false)
, m_showRepaintCounter(false)
, m_compositingConsultsOverlap(true)
@@ -237,6 +238,11 @@
updateCompositingLayers();
}
+bool RenderLayerCompositor::hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const
+{
+ return m_compositedLayerCount > rootLayer->isComposited();
+}
+
void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType updateType, RenderLayer* updateRoot)
{
m_updateCompositingLayersTimer.stop();
@@ -298,7 +304,9 @@
// Host the document layer in the RenderView's root layer.
if (updateRoot == rootRenderLayer()) {
- if (childList.isEmpty())
+ // Even when childList is empty, don't drop out of compositing mode if there are
+ // composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
+ if (childList.isEmpty() && !hasAnyAdditionalCompositedLayers(updateRoot))
destroyRootPlatformLayer();
else
m_rootPlatformLayer->setChildren(childList);
@@ -720,8 +728,9 @@
}
// If we're back at the root, and no other layers need to be composited, and the root layer itself doesn't need
- // to be composited, then we can drop out of compositing mode altogether.
- if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
+ // to be composited, then we can drop out of compositing mode altogether. However, don't drop out of compositing mode
+ // if there are composited layers that we didn't hit in our traversal (e.g. because of visibility:hidden).
+ if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode && !hasAnyAdditionalCompositedLayers(layer)) {
enableCompositingMode(false);
willBeComposited = false;
}
Modified: branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayerCompositor.h (98151 => 98152)
--- branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayerCompositor.h 2011-10-21 21:16:03 UTC (rev 98151)
+++ branches/safari-534.52-branch/Source/WebCore/rendering/RenderLayerCompositor.h 2011-10-21 21:22:50 UTC (rev 98152)
@@ -148,6 +148,13 @@
void didMoveOnscreen();
void willMoveOffscreen();
+ void layerBecameComposited(const RenderLayer*) { ++m_compositedLayerCount; }
+ void layerBecameNonComposited(const RenderLayer*)
+ {
+ ASSERT(m_compositedLayerCount > 0);
+ --m_compositedLayerCount;
+ }
+
void didStartAcceleratedAnimation(CSSPropertyID);
#if ENABLE(VIDEO)
@@ -232,6 +239,8 @@
void removeCompositedChildren(RenderLayer*);
bool layerHas3DContent(const RenderLayer*) const;
+
+ bool hasAnyAdditionalCompositedLayers(const RenderLayer* rootLayer) const;
void ensureRootPlatformLayer();
void destroyRootPlatformLayer();
@@ -269,6 +278,7 @@
bool m_hasAcceleratedCompositing;
ChromeClient::CompositingTriggerFlags m_compositingTriggers;
+ int m_compositedLayerCount;
bool m_showDebugBorders;
bool m_showRepaintCounter;
bool m_compositingConsultsOverlap;