summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Roard <nicolasroard@google.com>2011-07-29 11:30:01 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-07-29 11:30:01 -0700
commit40e3b187f192eb3de4f6540cecd522cb767ce97c (patch)
tree5697bd4814f07e67e931532a53a394368ac410e7
parent910c92cb6b526721c89abf1b7f8c58117a2fd2a2 (diff)
parente0aa068729e4558f198f02f9217b11a05fe3d1d3 (diff)
downloadexternal_webkit-40e3b187f192eb3de4f6540cecd522cb767ce97c.zip
external_webkit-40e3b187f192eb3de4f6540cecd522cb767ce97c.tar.gz
external_webkit-40e3b187f192eb3de4f6540cecd522cb767ce97c.tar.bz2
Merge "Reduce the number of layers - overflow elements triggered all layers before them to be composited; this is not needed at all... - fixed elements will trigger layers after them to be composited, but we don't need to composite all of them -- the one fully contained into previous composited layers don't need to..."
-rw-r--r--Source/WebCore/rendering/RenderLayer.cpp3
-rw-r--r--Source/WebCore/rendering/RenderLayer.h9
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.cpp135
-rw-r--r--Source/WebCore/rendering/RenderLayerCompositor.h4
4 files changed, 112 insertions, 39 deletions
diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp
index 4e1c875..ce5bf27 100644
--- a/Source/WebCore/rendering/RenderLayer.cpp
+++ b/Source/WebCore/rendering/RenderLayer.cpp
@@ -177,6 +177,9 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
#if USE(ACCELERATED_COMPOSITING)
, m_hasCompositingDescendant(false)
, m_mustOverlapCompositedLayers(false)
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ , m_shouldComposite(false)
+#endif
#endif
, m_containsDirtyOverlayScrollbars(false)
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
diff --git a/Source/WebCore/rendering/RenderLayer.h b/Source/WebCore/rendering/RenderLayer.h
index 2174920..f257593 100644
--- a/Source/WebCore/rendering/RenderLayer.h
+++ b/Source/WebCore/rendering/RenderLayer.h
@@ -354,7 +354,7 @@ public:
if (hasOverflowScroll())
return true;
#endif
- return !hasAutoZIndex() || renderer()->isRenderView() || (isComposited() && isFixed());
+ return !hasAutoZIndex() || renderer()->isRenderView() || (isComposited() && isFixed()) || m_shouldComposite;
}
#else
#if ENABLE(ANDROID_OVERFLOW_SCROLL)
@@ -641,6 +641,10 @@ private:
bool mustOverlapCompositedLayers() const { return m_mustOverlapCompositedLayers; }
void setMustOverlapCompositedLayers(bool b) { m_mustOverlapCompositedLayers = b; }
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ bool shouldComposite() { return m_shouldComposite; }
+ void setShouldComposite(bool b) { m_shouldComposite = b; }
+#endif
#endif
void updateContentsScale(float);
@@ -743,6 +747,9 @@ protected:
#if USE(ACCELERATED_COMPOSITING)
bool m_hasCompositingDescendant : 1; // In the z-order tree.
bool m_mustOverlapCompositedLayers : 1;
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ bool m_shouldComposite : 1;
+#endif
#endif
bool m_containsDirtyOverlayScrollbars : 1;
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index 786f806..8d066e9 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -80,6 +80,9 @@ struct CompositingState {
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
, m_fixedSibling(false)
#endif
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ , m_hasScrollableElement(false)
+#endif
#ifndef NDEBUG
, m_depth(0)
#endif
@@ -91,6 +94,9 @@ struct CompositingState {
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
bool m_fixedSibling;
#endif
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ bool m_hasScrollableElement;
+#endif
#ifndef NDEBUG
int m_depth;
#endif
@@ -288,6 +294,10 @@ void RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
// FIXME: we could maybe do this and the hierarchy udpate in one pass, but the parenting logic would be more complex.
CompositingState compState(updateRoot);
bool layersChanged = false;
+
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ compState.m_hasScrollableElement = false;
+#endif
if (m_compositingConsultsOverlap) {
OverlapMap overlapTestRequestMap;
computeCompositingRequirements(updateRoot, &overlapTestRequestMap, compState, layersChanged);
@@ -589,14 +599,6 @@ bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, con
for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
const IntRect& bounds = it->second;
if (layerBounds.intersects(bounds)) {
-#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- RenderLayer* intersectedLayer = it->first;
- if (intersectedLayer && intersectedLayer->isFixed()) {
- if (bounds.contains(layerBounds)) {
- continue;
- }
- }
-#endif
return true;
}
}
@@ -604,6 +606,53 @@ bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, con
return false;
}
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+
+// to properly support z-index with composited fixed elements, we need to turn
+// layers following a fixed layer into compositing mode; but if a layer is fully
+// contained into a previous layer already composited (that is not the fixed
+// layer), we don't need to composite it. This saves up quite a bit on the
+// number of layers we have to composite.
+//
+bool RenderLayerCompositor::checkForFixedLayers(Vector<RenderLayer*>* list, bool stopAtFixedLayer)
+{
+ size_t listSize = list->size();
+ int haveFixedLayer = -1;
+ bool fixedSibling = false;
+ for (size_t j = 0; j < listSize; ++j) {
+ RenderLayer* currentLayer = list->at(j);
+ if (currentLayer->isFixed() && needsToBeComposited(currentLayer)) {
+ haveFixedLayer = j;
+ fixedSibling = true;
+ }
+ if (haveFixedLayer != -1 && haveFixedLayer != j) {
+ IntRect currentLayerBounds = currentLayer->renderer()->localToAbsoluteQuad(
+ FloatRect(currentLayer->localBoundingBox())).enclosingBoundingBox();
+ bool needComposite = true;
+ int stop = 0;
+ if (stopAtFixedLayer)
+ stop = haveFixedLayer + 1;
+
+ for (size_t k = j - 1; k >= stop; --k) {
+ RenderLayer* aLayer = list->at(k);
+ if (aLayer && aLayer->renderer()) {
+ IntRect bounds = aLayer->renderer()->localToAbsoluteQuad(
+ FloatRect(aLayer->localBoundingBox())).enclosingBoundingBox();
+ if (bounds.contains(currentLayerBounds)
+ && needsToBeComposited(aLayer)) {
+ needComposite = false;
+ break;
+ }
+ }
+ }
+ currentLayer->setShouldComposite(needComposite);
+ }
+ }
+ return fixedSibling;
+}
+
+#endif
+
// Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
// For the z-order children of a compositing layer:
// If a child layers has a compositing layer, then all subsequent layers must
@@ -636,7 +685,14 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
mustOverlapCompositedLayers = overlapsCompositedLayers(*overlapMap, absBounds);
}
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ if (compositingState.m_fixedSibling)
+ layer->setMustOverlapCompositedLayers(layer->shouldComposite());
+ else
+ layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
+#else
layer->setMustOverlapCompositedLayers(mustOverlapCompositedLayers);
+#endif
// The children of this layer don't need to composite, unless there is
// a compositing layer among them, so start by inheriting the compositing
@@ -648,17 +704,20 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
bool willBeComposited = needsToBeComposited(layer);
-#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- // If we are a fixed layer, signal it to our siblings
- if (willBeComposited && layer->isFixed())
- compositingState.m_fixedSibling = true;
-
- if (!willBeComposited && compositingState.m_fixedSibling) {
- layer->setMustOverlapCompositedLayers(true);
- willBeComposited = true;
- }
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // tell the parent it has scrollable descendants.
+ if (layer->hasOverflowScroll())
+ compositingState.m_hasScrollableElement = true;
#endif
+
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // we don't want to signal that the subtree is compositing if the reason
+ // is because the layer is an overflow layer -- doing so would trigger
+ // all the above layers to be composited unnecessarily
+ if (willBeComposited && !layer->hasOverflowScroll()) {
+#else
if (willBeComposited) {
+#endif
// Tell the parent it has compositing descendants.
compositingState.m_subtreeIsCompositing = true;
// This layer now acts as the ancestor for kids.
@@ -680,25 +739,10 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (Vector<RenderLayer*>* negZOrderList = layer->negZOrderList()) {
size_t listSize = negZOrderList->size();
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- childState.m_fixedSibling = false;
-
- // For the negative z-order, if we have a fixed layer
- // we need to make all the siblings composited layers.
- // Otherwise a negative layer (below the fixed layer) could
- // still be drawn onto a higher z-order layer (e.g. the body)
- // if not immediately intersecting with our fixed layer.
- // So it's not enough here to only set m_fixedSibling for
- // subsequent siblings as we do for the normal flow
- // and positive z-order.
- for (size_t j = 0; j < listSize; ++j) {
- if ((negZOrderList->at(j))->isFixed() &&
- needsToBeComposited(negZOrderList->at(j))) {
- childState.m_fixedSibling = true;
- break;
- }
- }
+ childState.m_fixedSibling = compositingState.m_fixedSibling;
+ if (checkForFixedLayers(negZOrderList, false))
+ childState.m_fixedSibling = true;
#endif
-
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = negZOrderList->at(i);
computeCompositingRequirements(curLayer, overlapMap, childState, layersChanged);
@@ -716,12 +760,14 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
}
}
}
-
+
ASSERT(!layer->m_normalFlowListDirty);
if (Vector<RenderLayer*>* normalFlowList = layer->normalFlowList()) {
size_t listSize = normalFlowList->size();
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- childState.m_fixedSibling = false;
+ childState.m_fixedSibling = compositingState.m_fixedSibling;
+ if (checkForFixedLayers(normalFlowList, true))
+ childState.m_fixedSibling = true;
#endif
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = normalFlowList->at(i);
@@ -733,7 +779,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (Vector<RenderLayer*>* posZOrderList = layer->posZOrderList()) {
size_t listSize = posZOrderList->size();
#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
- childState.m_fixedSibling = false;
+ childState.m_fixedSibling = compositingState.m_fixedSibling;
+ if (checkForFixedLayers(posZOrderList, true))
+ childState.m_fixedSibling = true;
#endif
for (size_t i = 0; i < listSize; ++i) {
RenderLayer* curLayer = posZOrderList->at(i);
@@ -768,6 +816,11 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
if (childState.m_subtreeIsCompositing)
compositingState.m_subtreeIsCompositing = true;
+#if ENABLE(ANDROID_OVERFLOW_SCROLL)
+ if (childState.m_hasScrollableElement)
+ compositingState.m_hasScrollableElement = true;
+#endif
+
// Set the flag to say that this SC has compositing children.
layer->setHasCompositingDescendant(childState.m_subtreeIsCompositing);
@@ -781,7 +834,13 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O
// 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 ENABLE(ANDROID_OVERFLOW_SCROLL)
+ // We also need to check that we don't have a scrollable layer, as this
+ // would not have set the m_subtreeIsCompositing flag
+ if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !childState.m_hasScrollableElement && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
+#else
if (layer->isRootLayer() && !childState.m_subtreeIsCompositing && !requiresCompositingLayer(layer) && !m_forceCompositingMode) {
+#endif
enableCompositingMode(false);
willBeComposited = false;
}
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h
index 0315050..813e265 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.h
+++ b/Source/WebCore/rendering/RenderLayerCompositor.h
@@ -218,6 +218,10 @@ private:
void updateCompositingLayersTimerFired(Timer<RenderLayerCompositor>*);
+#if ENABLE(COMPOSITED_FIXED_ELEMENTS)
+ bool checkForFixedLayers(Vector<RenderLayer*>* list, bool stopAtFixedLayer);
+#endif
+
// Returns true if any layer's compositing changed
void computeCompositingRequirements(RenderLayer*, OverlapMap*, struct CompositingState&, bool& layersChanged);