- Revision
- 137409
- Author
- [email protected]
- Date
- 2012-12-11 21:14:18 -0800 (Tue, 11 Dec 2012)
Log Message
ScrollingCoordinator::hasVisibleSlowRepaintFixedObject() should exclude out-of-view fixed position elements
https://bugs.webkit.org/show_bug.cgi?id=102543
Source/WebCore:
Let RenderLayerCompositor manage the reasons that fixed position elements are not composited.
Check the reason in ScrollingCoordinator::hasVisibleSlowRepaintFixedObjects(), don't let fixed position layer not composited with explicit reasons cause slow scrolling.
Reviewed by James Robinson.
Test: compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html
* page/scrolling/ScrollingCoordinator.cpp:
(WebCore::ScrollingCoordinator::hasVisibleSlowRepaintFixedObjects): Exclude fixed position elements that are not composited for explicit reasons.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements): Manages m_fixedPositionLayerNotCompositedReasonMap.
(WebCore::RenderLayerCompositor::needsToBeComposited):
(WebCore::RenderLayerCompositor::requiresCompositingLayer):
(WebCore::RenderLayerCompositor::requiresCompositingForPosition):
* rendering/RenderLayerCompositor.h:
(WebCore::RenderLayerCompositor::fixedPositionLayerNotCompositedReason): Now outputs fixedPositionLayerNotCompositedreason.
(RenderLayerCompositor):
LayoutTests:
Reviewed by James Robinson.
* compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html: Ensure slow-scrolling is not triggered.
* compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (137408 => 137409)
--- trunk/LayoutTests/ChangeLog 2012-12-12 04:52:49 UTC (rev 137408)
+++ trunk/LayoutTests/ChangeLog 2012-12-12 05:14:18 UTC (rev 137409)
@@ -1,3 +1,13 @@
+2012-12-11 Xianzhu Wang <[email protected]>
+
+ ScrollingCoordinator::hasVisibleSlowRepaintFixedObject() should exclude out-of-view fixed position elements
+ https://bugs.webkit.org/show_bug.cgi?id=102543
+
+ Reviewed by James Robinson.
+
+ * compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html: Ensure slow-scrolling is not triggered.
+ * compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html: Added.
+
2012-12-11 Hayato Ito <[email protected]>
[Shadow DOM] Kill ShadowRoot constructor
Added: trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scroll-reason-expected.txt (0 => 137409)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scroll-reason-expected.txt (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scroll-reason-expected.txt 2012-12-12 05:14:18 UTC (rev 137409)
@@ -0,0 +1,2 @@
+Main thread scrolling reasons should be blank:
+
Added: trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html (0 => 137409)
--- trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html (rev 0)
+++ trunk/LayoutTests/compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html 2012-12-12 05:14:18 UTC (rev 137409)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+<style>
+ .fixed {
+ position: fixed;
+ width: 10px;
+ height: 10px;
+ z-index: -1;
+ }
+</style>
+
+<script type="text/_javascript_">
+ if (window.internals)
+ window.internals.settings.setEnableCompositingForFixedPosition(true);
+
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+
+ window.addEventListener("load", function() {
+ document.getElementById("mainThreadScrollingReasons").innerText = window.internals.mainThreadScrollingReasons(document);
+ }, false);
+ }
+</script>
+</head>
+
+<body>
+<div style="height: 1000px">
+ Main thread scrolling reasons should be blank:
+ <pre id="mainThreadScrollingReasons"></pre>
+</div>
+
+<!-- out of view fixed position elements should not trigger main thread scrolling. -->
+<div class="fixed"></div>
+<div class="fixed" style="top: -100px"></div>
+<div class="fixed" style="top: 0px; left: 1000px"></div>
+
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (137408 => 137409)
--- trunk/Source/WebCore/ChangeLog 2012-12-12 04:52:49 UTC (rev 137408)
+++ trunk/Source/WebCore/ChangeLog 2012-12-12 05:14:18 UTC (rev 137409)
@@ -1,3 +1,26 @@
+2012-12-11 Xinazhu Wang <[email protected]>
+
+ ScrollingCoordinator::hasVisibleSlowRepaintFixedObject() should exclude out-of-view fixed position elements
+ https://bugs.webkit.org/show_bug.cgi?id=102543
+
+ Let RenderLayerCompositor manage the reasons that fixed position elements are not composited.
+ Check the reason in ScrollingCoordinator::hasVisibleSlowRepaintFixedObjects(), don't let fixed position layer not composited with explicit reasons cause slow scrolling.
+
+ Reviewed by James Robinson.
+
+ Test: compositing/layer-creation/fixed-position-out-of-view-scroll-reason.html
+
+ * page/scrolling/ScrollingCoordinator.cpp:
+ (WebCore::ScrollingCoordinator::hasVisibleSlowRepaintFixedObjects): Exclude fixed position elements that are not composited for explicit reasons.
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::computeCompositingRequirements): Manages m_fixedPositionLayerNotCompositedReasonMap.
+ (WebCore::RenderLayerCompositor::needsToBeComposited):
+ (WebCore::RenderLayerCompositor::requiresCompositingLayer):
+ (WebCore::RenderLayerCompositor::requiresCompositingForPosition):
+ * rendering/RenderLayerCompositor.h:
+ (WebCore::RenderLayerCompositor::fixedPositionLayerNotCompositedReason): Now outputs fixedPositionLayerNotCompositedreason.
+ (RenderLayerCompositor):
+
2012-12-11 Hayato Ito <[email protected]>
[Shadow DOM] Kill ShadowRoot constructor
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (137408 => 137409)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2012-12-12 04:52:49 UTC (rev 137408)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2012-12-12 05:14:18 UTC (rev 137409)
@@ -338,8 +338,9 @@
RenderObject* viewportConstrainedObject = *it;
if (!viewportConstrainedObject->isBoxModelObject() || !viewportConstrainedObject->hasLayer())
return true;
- RenderBoxModelObject* viewportConstrainedBoxModelObject = toRenderBoxModelObject(viewportConstrainedObject);
- if (!viewportConstrainedBoxModelObject->layer()->backing())
+ RenderLayer* layer = toRenderBoxModelObject(viewportConstrainedObject)->layer();
+ // Any explicit reason that a fixed position element is not composited shouldn't cause slow scrolling.
+ if (!layer->isComposited() && layer->compositor()->fixedPositionLayerNotCompositedReason(layer) == RenderLayerCompositor::NoReason)
return true;
}
return false;
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (137408 => 137409)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2012-12-12 04:52:49 UTC (rev 137408)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2012-12-12 05:14:18 UTC (rev 137409)
@@ -453,6 +453,7 @@
CompositingState compState(updateRoot, m_compositingConsultsOverlap);
bool layersChanged = false;
bool saw3DTransform = false;
+ m_fixedPositionLayerNotCompositedReasonMap.clear();
if (m_compositingConsultsOverlap) {
OverlapMap overlapTestRequestMap;
computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, compState, layersChanged, saw3DTransform);
@@ -843,7 +844,8 @@
CompositingState childState(compositingState);
childState.m_subtreeIsCompositing = false;
- bool willBeComposited = needsToBeComposited(layer);
+ FixedPositionLayerNotCompositedReason fixedPositionLayerNotCompositedReason = NoReason;
+ bool willBeComposited = needsToBeComposited(layer, &fixedPositionLayerNotCompositedReason);
if (willBeComposited) {
// Tell the parent it has compositing descendants.
compositingState.m_subtreeIsCompositing = true;
@@ -852,7 +854,8 @@
if (overlapMap)
overlapMap->pushCompositingContainer();
- }
+ } else if (fixedPositionLayerNotCompositedReason != NoReason)
+ m_fixedPositionLayerNotCompositedReasonMap.set(layer, fixedPositionLayerNotCompositedReason);
#if !ASSERT_DISABLED
LayerListMutationDetector mutationChecker(layer);
@@ -1555,18 +1558,18 @@
return false;
}
-bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer) const
+bool RenderLayerCompositor::needsToBeComposited(const RenderLayer* layer, FixedPositionLayerNotCompositedReason* fixedPositionLayerNotCompositedReason) const
{
if (!canBeComposited(layer))
return false;
- return requiresCompositingLayer(layer) || layer->mustCompositeForIndirectReasons() || (inCompositingMode() && layer->isRootLayer());
+ return requiresCompositingLayer(layer, fixedPositionLayerNotCompositedReason) || layer->mustCompositeForIndirectReasons() || (inCompositingMode() && layer->isRootLayer());
}
// Note: this specifies whether the RL needs a compositing layer for intrinsic reasons.
// Use needsToBeComposited() to determine if a RL actually needs a compositing layer.
// static
-bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer) const
+bool RenderLayerCompositor::requiresCompositingLayer(const RenderLayer* layer, FixedPositionLayerNotCompositedReason* fixedPositionLayerNotCompositedReason) const
{
RenderObject* renderer = layer->renderer();
// The compositing state of a reflection should match that of its reflected layer.
@@ -1584,7 +1587,7 @@
|| clipsCompositingDescendants(layer)
|| requiresCompositingForAnimation(renderer)
|| requiresCompositingForFilters(renderer)
- || requiresCompositingForPosition(renderer, layer)
+ || requiresCompositingForPosition(renderer, layer, fixedPositionLayerNotCompositedReason)
|| requiresCompositingForOverflowScrolling(layer)
|| requiresCompositingForBlending(renderer);
}
@@ -1962,7 +1965,7 @@
#endif
}
-bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer) const
+bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, FixedPositionLayerNotCompositedReason* fixedPositionLayerNotCompositedReason) const
{
// position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
// opacity, transform) can get their own composited layer. A stacking context is required otherwise
@@ -1983,16 +1986,22 @@
// Don't promote fixed position elements that are descendants of transformed elements.
// They will stay fixed wrt the transformed element rather than the enclosing frame.
- if (container != m_renderView)
+ if (container != m_renderView) {
+ if (fixedPositionLayerNotCompositedReason)
+ *fixedPositionLayerNotCompositedReason = DescendantOfTransformedElement;
return false;
+ }
// Fixed position elements that are invisible in the current view don't get their own layer.
if (FrameView* frameView = m_renderView->frameView()) {
IntRect viewBounds = frameView->visibleContentRect();
LayoutRect layerBounds = calculateCompositedBounds(layer, rootRenderLayer());
layerBounds.scale(pageScaleFactor());
- if (!viewBounds.intersects(enclosingIntRect(layerBounds)))
+ if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
+ if (fixedPositionLayerNotCompositedReason)
+ *fixedPositionLayerNotCompositedReason = LayerBoundsOutOfView;
return false;
+ }
}
return true;
Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.h (137408 => 137409)
--- trunk/Source/WebCore/rendering/RenderLayerCompositor.h 2012-12-12 04:52:49 UTC (rev 137408)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.h 2012-12-12 05:14:18 UTC (rev 137409)
@@ -31,6 +31,7 @@
#include "GraphicsLayerUpdater.h"
#include "RenderLayer.h"
#include "RenderLayerBacking.h"
+#include <wtf/HashMap.h>
namespace WebCore {
@@ -229,6 +230,14 @@
void reportMemoryUsage(MemoryObjectInfo*) const;
+ enum FixedPositionLayerNotCompositedReason {
+ NoReason,
+ LayerBoundsOutOfView,
+ DescendantOfTransformedElement,
+ };
+
+ FixedPositionLayerNotCompositedReason fixedPositionLayerNotCompositedReason(const RenderLayer* layer) const { return m_fixedPositionLayerNotCompositedReasonMap.get(layer); }
+
private:
class OverlapMap;
@@ -243,9 +252,9 @@
virtual void flushLayers(GraphicsLayerUpdater*) OVERRIDE;
// Whether the given RL needs a compositing layer.
- bool needsToBeComposited(const RenderLayer*) const;
+ bool needsToBeComposited(const RenderLayer*, FixedPositionLayerNotCompositedReason* = 0) const;
// Whether the layer has an intrinsic need for compositing layer.
- bool requiresCompositingLayer(const RenderLayer*) const;
+ bool requiresCompositingLayer(const RenderLayer*, FixedPositionLayerNotCompositedReason* = 0) const;
// Whether the layer could ever be composited.
bool canBeComposited(const RenderLayer*) const;
@@ -310,7 +319,7 @@
bool requiresCompositingForFilters(RenderObject*) const;
bool requiresCompositingForBlending(RenderObject* renderer) const;
bool requiresCompositingForScrollableFrame() const;
- bool requiresCompositingForPosition(RenderObject*, const RenderLayer*) const;
+ bool requiresCompositingForPosition(RenderObject*, const RenderLayer*, FixedPositionLayerNotCompositedReason* = 0) const;
bool requiresCompositingForOverflowScrolling(const RenderLayer*) const;
bool requiresCompositingForIndirectReason(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
@@ -391,6 +400,9 @@
double m_obligatoryBackingStoreBytes;
double m_secondaryBackingStoreBytes;
#endif
+
+ typedef HashMap<const RenderLayer*, FixedPositionLayerNotCompositedReason> FixedPositionLayerNotCompositedReasonMap;
+ FixedPositionLayerNotCompositedReasonMap m_fixedPositionLayerNotCompositedReasonMap;
};