Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / compositing / GraphicsLayerUpdater.cpp
1 /*
2  * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3  * Copyright (C) 2014 Google Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
13  *
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.
25  */
26
27 #include "config.h"
28 #include "core/rendering/compositing/GraphicsLayerUpdater.h"
29
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"
38
39 namespace WebCore {
40
41 static bool shouldAppendLayer(const RenderLayer& layer)
42 {
43     if (!RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
44         return true;
45     Node* node = layer.renderer()->node();
46     if (node && isHTMLMediaElement(*node) && toHTMLMediaElement(node)->isFullscreen())
47         return false;
48     return true;
49 }
50
51 GraphicsLayerUpdater::UpdateContext::UpdateContext(const UpdateContext& other, const RenderLayer& layer)
52     : m_compositingStackingContainer(other.m_compositingStackingContainer)
53     , m_compositingAncestor(other.compositingContainer(layer))
54 {
55     CompositingState compositingState = layer.compositingState();
56     if (compositingState != NotComposited && compositingState != PaintsIntoGroupedBacking) {
57         m_compositingAncestor = &layer;
58         if (layer.stackingNode()->isStackingContainer())
59             m_compositingStackingContainer = &layer;
60     }
61 }
62
63 const RenderLayer* GraphicsLayerUpdater::UpdateContext::compositingContainer(const RenderLayer& layer) const
64 {
65     return layer.stackingNode()->isNormalFlowOnly() ? m_compositingAncestor : m_compositingStackingContainer;
66 }
67
68 GraphicsLayerUpdater::GraphicsLayerUpdater()
69     : m_needsRebuildTree(false)
70 {
71 }
72
73 GraphicsLayerUpdater::~GraphicsLayerUpdater()
74 {
75 }
76
77 void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, GraphicsLayerVector& childLayersOfEnclosingLayer)
78 {
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.
82
83     layer.stackingNode()->updateLayerListsIfNeeded();
84
85     const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
86     CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping();
87
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;
92
93 #if !ASSERT_DISABLED
94     LayerListMutationDetector mutationChecker(layer.stackingNode());
95 #endif
96
97     if (layer.stackingNode()->isStackingContainer()) {
98         RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
99         while (RenderLayerStackingNode* curNode = iterator.next())
100             rebuildTree(*curNode->layer(), childList);
101
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());
105     }
106
107     RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
108     while (RenderLayerStackingNode* curNode = iterator.next())
109         rebuildTree(*curNode->layer(), childList);
110
111     if (hasCompositedLayerMapping) {
112         bool parented = false;
113         if (layer.renderer()->isRenderPart())
114             parented = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(layer.renderer()));
115
116         if (!parented)
117             currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
118
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);
125             }
126
127             if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
128                 overflowControlLayer->removeFromParent();
129                 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
130             }
131
132             if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
133                 overflowControlLayer->removeFromParent();
134                 currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
135             }
136         }
137
138         if (shouldAppendLayer(layer))
139             childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
140     }
141 }
142
143 void GraphicsLayerUpdater::update(RenderLayer& layer, UpdateType updateType, const UpdateContext& context)
144 {
145     if (layer.hasCompositedLayerMapping()) {
146         CompositedLayerMappingPtr mapping = layer.compositedLayerMapping();
147
148         const RenderLayer* compositingContainer = context.compositingContainer(layer);
149         ASSERT(compositingContainer == layer.ancestorCompositingLayer());
150         if (mapping->updateRequiresOwnBackingStoreForAncestorReasons(compositingContainer))
151             updateType = ForceUpdate;
152
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);
156
157         if (RenderLayerReflectionInfo* reflection = layer.reflectionInfo()) {
158             if (reflection->reflectionLayer()->hasCompositedLayerMapping())
159                 reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds(ForceUpdate);
160         }
161
162         if (mapping->updateGraphicsLayerConfiguration(updateType))
163             m_needsRebuildTree = true;
164
165         mapping->updateGraphicsLayerGeometry(updateType, compositingContainer);
166
167         updateType = mapping->updateTypeForChildren(updateType);
168         mapping->clearNeedsGraphicsLayerUpdate();
169
170         if (!layer.parent())
171             layer.compositor()->updateRootLayerPosition();
172
173         if (mapping->hasUnpositionedOverflowControlsLayers())
174             layer.scrollableArea()->positionOverflowControls();
175     }
176
177     UpdateContext childContext(context, layer);
178     for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
179         update(*child, updateType, childContext);
180 }
181
182 #if !ASSERT_DISABLED
183
184 void GraphicsLayerUpdater::assertNeedsToUpdateGraphicsLayerBitsCleared(RenderLayer& layer)
185 {
186     if (layer.hasCompositedLayerMapping())
187         layer.compositedLayerMapping()->assertNeedsToUpdateGraphicsLayerBitsCleared();
188
189     for (RenderLayer* child = layer.firstChild(); child; child = child->nextSibling())
190         assertNeedsToUpdateGraphicsLayerBitsCleared(*child);
191 }
192
193 #endif
194
195 } // namespace WebCore