2 * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2014 Google Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
30 #include "core/html/HTMLMediaElement.h"
31 #include "core/rendering/RenderLayer.h"
32 #include "core/rendering/RenderLayerReflectionInfo.h"
33 #include "core/rendering/RenderPart.h"
34 #include "core/rendering/RenderView.h"
35 #include "core/rendering/compositing/CompositedLayerMapping.h"
36 #include "core/rendering/compositing/RenderLayerCompositor.h"
37 #include "public/platform/Platform.h"
41 static bool shouldAppendLayer(const RenderLayer& layer)
43 if (!RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
45 Node* node = layer.renderer()->node();
46 if (node && isHTMLMediaElement(*node) && toHTMLMediaElement(node)->isFullscreen())
51 GraphicsLayerUpdater::UpdateContext::UpdateContext(const UpdateContext& other, const RenderLayer& layer)
52 : m_compositingStackingContainer(other.m_compositingStackingContainer)
53 , m_compositingAncestor(other.compositingContainer(layer))
55 CompositingState compositingState = layer.compositingState();
56 if (compositingState != NotComposited && compositingState != PaintsIntoGroupedBacking) {
57 m_compositingAncestor = &layer;
58 if (layer.stackingNode()->isStackingContainer())
59 m_compositingStackingContainer = &layer;
63 const RenderLayer* GraphicsLayerUpdater::UpdateContext::compositingContainer(const RenderLayer& layer) const
65 return layer.stackingNode()->isNormalFlowOnly() ? m_compositingAncestor : m_compositingStackingContainer;
68 GraphicsLayerUpdater::GraphicsLayerUpdater()
69 : m_needsRebuildTree(false)
73 GraphicsLayerUpdater::~GraphicsLayerUpdater()
77 void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, GraphicsLayerVector& childLayersOfEnclosingLayer)
79 // Make the layer compositing if necessary, and set up clipping and content layers.
80 // Note that we can only do work here that is independent of whether the descendant layers
81 // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
83 layer.stackingNode()->updateLayerListsIfNeeded();
85 const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
86 CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping();
88 // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
89 // Otherwise children continue to append to the child list of the enclosing layer.
90 GraphicsLayerVector layerChildren;
91 GraphicsLayerVector& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer;
94 LayerListMutationDetector mutationChecker(layer.stackingNode());
97 if (layer.stackingNode()->isStackingContainer()) {
98 RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
99 while (RenderLayerStackingNode* curNode = iterator.next())
100 rebuildTree(*curNode->layer(), childList);
102 // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
103 if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
104 childList.append(currentCompositedLayerMapping->foregroundLayer());
107 RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
108 while (RenderLayerStackingNode* curNode = iterator.next())
109 rebuildTree(*curNode->layer(), childList);
111 if (hasCompositedLayerMapping) {
112 bool parented = false;
113 if (layer.renderer()->isRenderPart())
114 parented = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(layer.renderer()));
117 currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
119 // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
120 // Otherwise, the overflow control layers are normal children.
121 if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) {
122 if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) {
123 overflowControlLayer->removeFromParent();
124 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
127 if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
128 overflowControlLayer->removeFromParent();
129 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
132 if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
133 overflowControlLayer->removeFromParent();
134 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
138 if (shouldAppendLayer(layer))
139 childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
143 void GraphicsLayerUpdater::update(RenderLayer& layer, UpdateType updateType, const UpdateContext& context)
145 if (layer.hasCompositedLayerMapping()) {
146 CompositedLayerMappingPtr mapping = layer.compositedLayerMapping();
148 const RenderLayer* compositingContainer = context.compositingContainer(layer);
149 ASSERT(compositingContainer == layer.ancestorCompositingLayer());
150 if (mapping->updateRequiresOwnBackingStoreForAncestorReasons(compositingContainer))
151 updateType = ForceUpdate;
153 // Note carefully: here we assume that the compositing state of all descendants have been updated already,
154 // so it is legitimate to compute and cache the composited bounds for this layer.
155 mapping->updateCompositedBounds(updateType);
157 if (RenderLayerReflectionInfo* reflection = layer.reflectionInfo()) {
158 if (reflection->reflectionLayer()->hasCompositedLayerMapping())
159 reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds(ForceUpdate);
162 if (mapping->updateGraphicsLayerConfiguration(updateType))
163 m_needsRebuildTree = true;
165 mapping->updateGraphicsLayerGeometry(updateType, compositingContainer);
167 updateType = mapping->updateTypeForChildren(updateType);
168 mapping->clearNeedsGraphicsLayerUpdate();
171 layer.compositor()->updateRootLayerPosition();
173 if (mapping->hasUnpositionedOverflowControlsLayers())
174 layer.scrollableArea()->positionOverflowControls();
177 UpdateContext childContext(context, layer);
178 for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
179 update(*child, updateType, childContext);
184 void GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(RenderLayer& layer)
186 if (layer.hasCompositedLayerMapping())
187 layer.compositedLayerMapping()->assertNeedsToUpdateGraphicsLayerBitsCleared();
189 for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
190 assertNeedsToUpdateGraphicsLayerBitsCleared(*child);
195 } // namespace WebCore