Chromium Code Reviews| Index: Source/core/rendering/compositing/GraphicsLayerUpdater.cpp |
| diff --git a/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp b/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e5dbcf8aabce42f69ef1e0ec71670574bc8e7df1 |
| --- /dev/null |
| +++ b/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp |
| @@ -0,0 +1,195 @@ |
| +/* |
| + * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. |
|
esprehn
2014/03/01 09:37:07
ditto, shorter copyright
|
| + * Copyright (C) 2014 Google Inc. All rights reserved. |
| + * |
| + * Redistribution and use in source and binary forms, with or without |
| + * modification, are permitted provided that the following conditions |
| + * are met: |
| + * 1. Redistributions of source code must retain the above copyright |
| + * notice, this list of conditions and the following disclaimer. |
| + * 2. Redistributions in binary form must reproduce the above copyright |
| + * notice, this list of conditions and the following disclaimer in the |
| + * documentation and/or other materials provided with the distribution. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| + */ |
| + |
| +#include "config.h" |
| +#include "core/rendering/compositing/GraphicsLayerUpdater.h" |
| + |
| +#include "core/rendering/RenderLayer.h" |
| +#include "core/rendering/RenderLayerReflectionInfo.h" |
| +#include "core/rendering/RenderPart.h" |
| +#include "core/rendering/RenderView.h" |
| +#include "core/rendering/compositing/CompositedLayerMapping.h" |
| +#include "core/rendering/compositing/RenderLayerCompositor.h" |
| +#include "public/platform/Platform.h" |
| + |
| +namespace WebCore { |
| + |
| +GraphicsLayerUpdater::GraphicsLayerUpdater(RenderView& renderView) |
| + : m_renderView(renderView) |
| + , m_pixelsWithoutPromotingAllTransitions(0.0) |
| + , m_pixelsAddedByPromotingAllTransitions(0.0) |
| +{ |
| +} |
| + |
| +GraphicsLayerUpdater::~GraphicsLayerUpdater() |
| +{ |
| +} |
| + |
| +void GraphicsLayerUpdater::rebuildTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth) |
|
esprehn
2014/03/01 09:37:07
Can we pass a RenderLayer& ?
abarth-chromium
2014/03/01 09:40:39
Sure.
|
| +{ |
| + // Make the layer compositing if necessary, and set up clipping and content layers. |
| + // Note that we can only do work here that is independent of whether the descendant layers |
| + // have been processed. computeCompositingRequirements() will already have done the repaint if necessary. |
| + |
| + layer->stackingNode()->updateLayerListsIfNeeded(); |
| + layer->update3dRenderingContext(); |
| + |
| + const bool hasCompositedLayerMapping = layer->hasCompositedLayerMapping(); |
| + CompositedLayerMappingPtr currentCompositedLayerMapping = layer->compositedLayerMapping(); |
| + |
| + update(layer); |
| + |
| + // Grab some stats for histograms. |
| + if (hasCompositedLayerMapping) { |
| + m_pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width(); |
| + } else { |
| + if ((layer->renderer()->style()->transitionForProperty(CSSPropertyOpacity) || |
| + layer->renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) && |
| + m_renderView.viewRect().intersects(layer->absoluteBoundingBox())) |
| + m_pixelsAddedByPromotingAllTransitions += layer->size().height() * layer->size().width(); |
| + } |
| + |
| + // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers. |
| + // Otherwise children continue to append to the child list of the enclosing layer. |
| + Vector<GraphicsLayer*> layerChildren; |
| + Vector<GraphicsLayer*>& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer; |
| + |
| +#if !ASSERT_DISABLED |
| + LayerListMutationDetector mutationChecker(layer->stackingNode()); |
| +#endif |
| + |
| + if (layer->stackingNode()->isStackingContainer()) { |
| + RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren); |
| + while (RenderLayerStackingNode* curNode = iterator.next()) |
| + rebuildTree(curNode->layer(), childList, depth + 1); |
| + |
| + // If a negative z-order child is compositing, we get a foreground layer which needs to get parented. |
| + if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer()) |
| + childList.append(currentCompositedLayerMapping->foregroundLayer()); |
| + } |
| + |
| + RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren); |
| + while (RenderLayerStackingNode* curNode = iterator.next()) |
| + rebuildTree(curNode->layer(), childList, depth + 1); |
| + |
| + if (hasCompositedLayerMapping) { |
| + bool parented = false; |
| + if (layer->renderer()->isRenderPart()) |
| + parented = parentFrameContentLayers(toRenderPart(layer->renderer())); |
| + |
| + if (!parented) |
| + currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren); |
| + |
| + // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer. |
| + // Otherwise, the overflow control layers are normal children. |
| + if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) { |
| + if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) { |
| + overflowControlLayer->removeFromParent(); |
| + currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer); |
| + } |
| + |
| + if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) { |
| + overflowControlLayer->removeFromParent(); |
| + currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer); |
| + } |
| + |
| + if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) { |
| + overflowControlLayer->removeFromParent(); |
| + currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer); |
| + } |
| + } |
| + |
| + childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers()); |
| + } |
| + |
| + if (!depth) { |
| + int percentageIncreaseInPixels = static_cast<int>(m_pixelsAddedByPromotingAllTransitions / m_pixelsWithoutPromotingAllTransitions * 100); |
| + blink::Platform::current()->histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50); |
| + } |
| +} |
| + |
| +// This just updates layer geometry without changing the hierarchy. |
| +void GraphicsLayerUpdater::updateRecursive(RenderLayer* layer) |
|
esprehn
2014/03/01 09:37:07
same
|
| +{ |
| + update(layer); |
| + |
| +#if !ASSERT_DISABLED |
| + LayerListMutationDetector mutationChecker(layer->stackingNode()); |
| +#endif |
| + |
| + RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren); |
| + while (RenderLayerStackingNode* curNode = iterator.next()) |
| + updateRecursive(curNode->layer()); |
| +} |
| + |
| +void GraphicsLayerUpdater::update(RenderLayer* layer) |
| +{ |
| + if (!layer->hasCompositedLayerMapping()) |
| + return; |
| + |
| + CompositedLayerMappingPtr mapping = layer->compositedLayerMapping(); |
| + |
| + // Note carefully: here we assume that the compositing state of all descendants have been updated already, |
| + // so it is legitimate to compute and cache the composited bounds for this layer. |
| + mapping->updateCompositedBounds(); |
| + |
| + if (RenderLayerReflectionInfo* reflection = layer->reflectionInfo()) { |
| + if (reflection->reflectionLayer()->hasCompositedLayerMapping()) |
| + reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds(); |
| + } |
| + |
| + mapping->updateGraphicsLayerConfiguration(); |
| + mapping->updateGraphicsLayerGeometry(); |
| + |
| + if (!layer->parent()) |
| + layer->compositor()->updateRootLayerPosition(); |
| + |
| + if (mapping->hasUnpositionedOverflowControlsLayers()) |
| + layer->scrollableArea()->positionOverflowControls(); |
| +} |
| + |
| +bool GraphicsLayerUpdater::parentFrameContentLayers(RenderPart* renderer) |
|
esprehn
2014/03/01 09:37:07
This should have a verb name. parentFrameContentLa
abarth-chromium
2014/03/01 09:40:39
I haven't figured that out yet.
|
| +{ |
| + RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(renderer); |
| + if (!innerCompositor || !innerCompositor->inCompositingMode() || innerCompositor->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingFrame) |
| + return false; |
| + |
| + RenderLayer* layer = renderer->layer(); |
| + if (!layer->hasCompositedLayerMapping()) |
| + return false; |
| + |
| + CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping(); |
| + GraphicsLayer* hostingLayer = compositedLayerMapping->parentForSublayers(); |
| + GraphicsLayer* rootLayer = innerCompositor->rootGraphicsLayer(); |
| + if (hostingLayer->children().size() != 1 || hostingLayer->children()[0] != rootLayer) { |
| + hostingLayer->removeAllChildren(); |
| + hostingLayer->addChild(rootLayer); |
| + } |
| + return true; |
| +} |
| + |
| + |
| +} // namespace WebCore |