Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / RenderLayerStackingNode.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
3  *
4  * Portions are Copyright (C) 1998 Netscape Communications Corporation.
5  *
6  * Other contributors:
7  *   Robert O'Callahan <roc+@cs.cmu.edu>
8  *   David Baron <dbaron@fas.harvard.edu>
9  *   Christian Biesinger <cbiesinger@web.de>
10  *   Randall Jesup <rjesup@wgate.com>
11  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
12  *   Josh Soref <timeless@mac.com>
13  *   Boris Zbarsky <bzbarsky@mit.edu>
14  *
15  * This library is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU Lesser General Public
17  * License as published by the Free Software Foundation; either
18  * version 2.1 of the License, or (at your option) any later version.
19  *
20  * This library is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public
26  * License along with this library; if not, write to the Free Software
27  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28  *
29  * Alternatively, the contents of this file may be used under the terms
30  * of either the Mozilla Public License Version 1.1, found at
31  * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
32  * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
33  * (the "GPL"), in which case the provisions of the MPL or the GPL are
34  * applicable instead of those above.  If you wish to allow use of your
35  * version of this file only under the terms of one of those two
36  * licenses (the MPL or the GPL) and not to allow others to use your
37  * version of this file under the LGPL, indicate your decision by
38  * deletingthe provisions above and replace them with the notice and
39  * other provisions required by the MPL or the GPL, as the case may be.
40  * If you do not delete the provisions above, a recipient may use your
41  * version of this file under any of the LGPL, the MPL or the GPL.
42  */
43
44 #include "config.h"
45 #include "core/rendering/RenderLayerStackingNode.h"
46
47 #include "core/rendering/RenderLayer.h"
48 #include "core/rendering/RenderLayerCompositor.h"
49 #include "core/rendering/RenderView.h"
50 #include "public/platform/Platform.h"
51
52 namespace WebCore {
53
54 // FIXME: This should not require RenderLayer. There is currently a cycle where
55 // in order to determine if we shoulBeNormalFlowOnly() and isStackingContainer()
56 // we have to ask the render layer about some of its state.
57 RenderLayerStackingNode::RenderLayerStackingNode(RenderLayer* layer)
58     : m_layer(layer)
59     , m_descendantsAreContiguousInStackingOrder(false)
60     , m_descendantsAreContiguousInStackingOrderDirty(true)
61     , m_normalFlowListDirty(true)
62     , m_needsToBeStackingContainer(false)
63     , m_needsToBeStackingContainerHasBeenRecorded(false)
64 #if !ASSERT_DISABLED
65     , m_layerListMutationAllowed(true)
66     , m_stackingParent(0)
67 #endif
68 {
69     m_isNormalFlowOnly = shouldBeNormalFlowOnly();
70
71     // Non-stacking containers should have empty z-order lists. As this is already the case,
72     // there is no need to dirty / recompute these lists.
73     m_zOrderListsDirty = isStackingContainer();
74 }
75
76 RenderLayerStackingNode::~RenderLayerStackingNode()
77 {
78 #if !ASSERT_DISABLED
79     if (!renderer()->documentBeingDestroyed()) {
80         ASSERT(!isInStackingParentZOrderLists());
81         ASSERT(!isInStackingParentNormalFlowList());
82
83         updateStackingParentForZOrderLists(0);
84         updateStackingParentForNormalFlowList(0);
85     }
86 #endif
87 }
88
89 bool RenderLayerStackingNode::isStackingContext(const RenderStyle* style) const
90 {
91     return !style->hasAutoZIndex() || layer()->isRootLayer();
92 }
93
94 // Helper for the sorting of layers by z-index.
95 static inline bool compareZIndex(RenderLayerStackingNode* first, RenderLayerStackingNode* second)
96 {
97     return first->zIndex() < second->zIndex();
98 }
99
100 RenderLayerCompositor* RenderLayerStackingNode::compositor() const
101 {
102     if (!renderer()->view())
103         return 0;
104     return renderer()->view()->compositor();
105 }
106
107 void RenderLayerStackingNode::dirtyNormalFlowListCanBePromotedToStackingContainer()
108 {
109     m_descendantsAreContiguousInStackingOrderDirty = true;
110
111     if (m_normalFlowListDirty || !normalFlowList())
112         return;
113
114     for (size_t index = 0; index < normalFlowList()->size(); ++index)
115         normalFlowList()->at(index)->dirtyNormalFlowListCanBePromotedToStackingContainer();
116 }
117
118 void RenderLayerStackingNode::dirtySiblingStackingNodeCanBePromotedToStackingContainer()
119 {
120     RenderLayerStackingNode* stackingNode = ancestorStackingNode();
121     if (!stackingNode)
122         return;
123
124     if (!stackingNode->zOrderListsDirty() && stackingNode->posZOrderList()) {
125         for (size_t index = 0; index < stackingNode->posZOrderList()->size(); ++index)
126             stackingNode->posZOrderList()->at(index)->setDescendantsAreContiguousInStackingOrderDirty(true);
127     }
128
129     stackingNode->dirtyNormalFlowListCanBePromotedToStackingContainer();
130
131     if (!stackingNode->zOrderListsDirty() && stackingNode->negZOrderList()) {
132         for (size_t index = 0; index < stackingNode->negZOrderList()->size(); ++index)
133             stackingNode->negZOrderList()->at(index)->setDescendantsAreContiguousInStackingOrderDirty(true);
134     }
135 }
136
137 void RenderLayerStackingNode::dirtyZOrderLists()
138 {
139     ASSERT(m_layerListMutationAllowed);
140     ASSERT(isStackingContainer());
141
142 #if !ASSERT_DISABLED
143     updateStackingParentForZOrderLists(0);
144 #endif
145
146     if (m_posZOrderList)
147         m_posZOrderList->clear();
148     if (m_negZOrderList)
149         m_negZOrderList->clear();
150     m_zOrderListsDirty = true;
151
152     m_descendantsAreContiguousInStackingOrderDirty = true;
153
154     if (!renderer()->documentBeingDestroyed()) {
155         compositor()->setNeedsUpdateCompositingRequirementsState();
156         compositor()->setCompositingLayersNeedRebuild();
157         if (renderer()->acceleratedCompositingForOverflowScrollEnabled())
158             compositor()->setNeedsToRecomputeCompositingRequirements();
159     }
160 }
161
162 void RenderLayerStackingNode::dirtyStackingContainerZOrderLists()
163 {
164     // Any siblings in the ancestor stacking context could also be affected.
165     // Changing z-index, for example, could cause us to stack in between a
166     // sibling's descendants, meaning that we have to recompute
167     // m_descendantsAreContiguousInStackingOrder for that sibling.
168     dirtySiblingStackingNodeCanBePromotedToStackingContainer();
169
170     RenderLayerStackingNode* stackingContainerNode = ancestorStackingContainerNode();
171     if (stackingContainerNode)
172         stackingContainerNode->dirtyZOrderLists();
173
174     // Any change that could affect our stacking container's z-order list could
175     // cause other RenderLayers in our stacking context to either opt in or out
176     // of composited scrolling. It is important that we make our stacking
177     // context aware of these z-order changes so the appropriate updating can
178     // happen.
179     RenderLayerStackingNode* stackingNode = ancestorStackingNode();
180     if (stackingNode && stackingNode != stackingContainerNode)
181         stackingNode->dirtyZOrderLists();
182 }
183
184 void RenderLayerStackingNode::dirtyNormalFlowList()
185 {
186     ASSERT(m_layerListMutationAllowed);
187
188 #if !ASSERT_DISABLED
189     updateStackingParentForNormalFlowList(0);
190 #endif
191
192     if (m_normalFlowList)
193         m_normalFlowList->clear();
194     m_normalFlowListDirty = true;
195
196     if (!renderer()->documentBeingDestroyed()) {
197         compositor()->setCompositingLayersNeedRebuild();
198         if (renderer()->acceleratedCompositingForOverflowScrollEnabled())
199             compositor()->setNeedsToRecomputeCompositingRequirements();
200     }
201 }
202
203 void RenderLayerStackingNode::rebuildZOrderLists()
204 {
205     ASSERT(m_layerListMutationAllowed);
206     ASSERT(isDirtyStackingContainer());
207     rebuildZOrderLists(m_posZOrderList, m_negZOrderList);
208
209 #if !ASSERT_DISABLED
210     updateStackingParentForZOrderLists(this);
211 #endif
212
213     m_zOrderListsDirty = false;
214 }
215
216 void RenderLayerStackingNode::rebuildZOrderLists(OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList,
217     OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList, const RenderLayerStackingNode* nodeToForceAsStackingContainer,
218     CollectLayersBehavior collectLayersBehavior)
219 {
220     for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
221         if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
222             child->stackingNode()->collectLayers(posZOrderList, negZOrderList, nodeToForceAsStackingContainer, collectLayersBehavior);
223     }
224
225     // Sort the two lists.
226     if (posZOrderList)
227         std::stable_sort(posZOrderList->begin(), posZOrderList->end(), compareZIndex);
228
229     if (negZOrderList)
230         std::stable_sort(negZOrderList->begin(), negZOrderList->end(), compareZIndex);
231
232     // Append layers for top layer elements after normal layer collection, to ensure they are on top regardless of z-indexes.
233     // The renderers of top layer elements are children of the view, sorted in top layer stacking order.
234     if (layer()->isRootLayer()) {
235         RenderObject* view = renderer()->view();
236         for (RenderObject* child = view->firstChild(); child; child = child->nextSibling()) {
237             Element* childElement = (child->node() && child->node()->isElementNode()) ? toElement(child->node()) : 0;
238             if (childElement && childElement->isInTopLayer()) {
239                 RenderLayer* layer = toRenderLayerModelObject(child)->layer();
240                 // Create the buffer if it doesn't exist yet.
241                 if (!posZOrderList)
242                     posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>);
243                 posZOrderList->append(layer->stackingNode());
244             }
245         }
246     }
247 }
248
249 void RenderLayerStackingNode::updateNormalFlowList()
250 {
251     if (!m_normalFlowListDirty)
252         return;
253
254     ASSERT(m_layerListMutationAllowed);
255
256     for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
257         // Ignore non-overflow layers and reflections.
258         if (child->stackingNode()->isNormalFlowOnly() && (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)) {
259             if (!m_normalFlowList)
260                 m_normalFlowList = adoptPtr(new Vector<RenderLayerStackingNode*>);
261             m_normalFlowList->append(child->stackingNode());
262         }
263     }
264
265 #if !ASSERT_DISABLED
266     updateStackingParentForNormalFlowList(this);
267 #endif
268
269     m_normalFlowListDirty = false;
270 }
271
272 void RenderLayerStackingNode::collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posBuffer, OwnPtr<Vector<RenderLayerStackingNode*> >& negBuffer,
273     const RenderLayerStackingNode* nodeToForceAsStackingContainer, CollectLayersBehavior collectLayersBehavior)
274 {
275     if (layer()->isInTopLayer())
276         return;
277
278     layer()->updateDescendantDependentFlags();
279
280     bool isStacking = false;
281     bool isNormalFlow = false;
282
283     switch (collectLayersBehavior) {
284     case ForceLayerToStackingContainer:
285         ASSERT(nodeToForceAsStackingContainer);
286         if (this == nodeToForceAsStackingContainer) {
287             isStacking = true;
288             isNormalFlow = false;
289         } else {
290             isStacking = isStackingContext();
291             isNormalFlow = shouldBeNormalFlowOnlyIgnoringCompositedScrolling();
292         }
293         break;
294     case OverflowScrollCanBeStackingContainers:
295         ASSERT(!nodeToForceAsStackingContainer);
296         isStacking = isStackingContainer();
297         isNormalFlow = isNormalFlowOnly();
298         break;
299     case OnlyStackingContextsCanBeStackingContainers:
300         isStacking = isStackingContext();
301         isNormalFlow = shouldBeNormalFlowOnlyIgnoringCompositedScrolling();
302         break;
303     }
304
305     // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
306     if (!isNormalFlow && !layer()->isOutOfFlowRenderFlowThread()) {
307         // Determine which buffer the child should be in.
308         OwnPtr<Vector<RenderLayerStackingNode*> >& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
309
310         // Create the buffer if it doesn't exist yet.
311         if (!buffer)
312             buffer = adoptPtr(new Vector<RenderLayerStackingNode*>);
313
314         // Append ourselves at the end of the appropriate buffer.
315         buffer->append(this);
316     }
317
318     // Recur into our children to collect more layers, but only if we don't establish
319     // a stacking context/container.
320     if (!isStacking) {
321         for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
322             // Ignore reflections.
323             if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
324                 child->stackingNode()->collectLayers(posBuffer, negBuffer, nodeToForceAsStackingContainer, collectLayersBehavior);
325         }
326     }
327 }
328
329 #if !ASSERT_DISABLED
330 bool RenderLayerStackingNode::isInStackingParentZOrderLists() const
331 {
332     if (!m_stackingParent || m_stackingParent->zOrderListsDirty())
333         return false;
334
335     if (m_stackingParent->posZOrderList() && m_stackingParent->posZOrderList()->find(this) != kNotFound)
336         return true;
337
338     if (m_stackingParent->negZOrderList() && m_stackingParent->negZOrderList()->find(this) != kNotFound)
339         return true;
340
341     return false;
342 }
343
344 bool RenderLayerStackingNode::isInStackingParentNormalFlowList() const
345 {
346     if (!m_stackingParent || m_stackingParent->normalFlowListDirty())
347         return false;
348
349     return (m_stackingParent->normalFlowList() && m_stackingParent->normalFlowList()->find(this) != kNotFound);
350 }
351
352 void RenderLayerStackingNode::updateStackingParentForZOrderLists(RenderLayerStackingNode* stackingParent)
353 {
354     if (m_posZOrderList) {
355         for (size_t i = 0; i < m_posZOrderList->size(); ++i)
356             m_posZOrderList->at(i)->setStackingParent(stackingParent);
357     }
358
359     if (m_negZOrderList) {
360         for (size_t i = 0; i < m_negZOrderList->size(); ++i)
361             m_negZOrderList->at(i)->setStackingParent(stackingParent);
362     }
363 }
364
365 void RenderLayerStackingNode::updateStackingParentForNormalFlowList(RenderLayerStackingNode* stackingParent)
366 {
367     if (m_normalFlowList) {
368         for (size_t i = 0; i < m_normalFlowList->size(); ++i)
369             m_normalFlowList->at(i)->setStackingParent(stackingParent);
370     }
371 }
372 #endif
373
374 void RenderLayerStackingNode::updateLayerListsIfNeeded()
375 {
376     updateZOrderLists();
377     updateNormalFlowList();
378
379     if (!layer()->reflectionInfo())
380         return;
381
382     RenderLayer* reflectionLayer = layer()->reflectionInfo()->reflectionLayer();
383     reflectionLayer->stackingNode()->updateZOrderLists();
384     reflectionLayer->stackingNode()->updateNormalFlowList();
385 }
386
387 void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle)
388 {
389     bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
390     EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
391     int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;
392
393     // FIXME: RenderLayer already handles visibility changes through our visiblity dirty bits. This logic could
394     // likely be folded along with the rest.
395     bool isStackingContext = this->isStackingContext();
396     if (isStackingContext == wasStackingContext && oldVisibility == renderer()->style()->visibility() && oldZIndex == zIndex())
397         return;
398
399     dirtyStackingContainerZOrderLists();
400
401     if (isStackingContainer())
402         dirtyZOrderLists();
403     else
404         clearZOrderLists();
405
406     compositor()->setNeedsUpdateCompositingRequirementsState();
407 }
408
409 bool RenderLayerStackingNode::shouldBeNormalFlowOnly() const
410 {
411     return shouldBeNormalFlowOnlyIgnoringCompositedScrolling() && !layer()->needsCompositedScrolling();
412 }
413
414 bool RenderLayerStackingNode::shouldBeNormalFlowOnlyIgnoringCompositedScrolling() const
415 {
416     const bool couldBeNormalFlow = renderer()->hasOverflowClip()
417         || renderer()->hasReflection()
418         || renderer()->hasMask()
419         || renderer()->isCanvas()
420         || renderer()->isVideo()
421         || renderer()->isEmbeddedObject()
422         || renderer()->isRenderIFrame()
423         || (renderer()->style()->specifiesColumns() && !layer()->isRootLayer());
424     const bool preventsElementFromBeingNormalFlow = renderer()->isPositioned()
425         || renderer()->hasTransform()
426         || renderer()->hasClipPath()
427         || renderer()->hasFilter()
428         || renderer()->hasBlendMode()
429         || layer()->isTransparent();
430
431     return couldBeNormalFlow && !preventsElementFromBeingNormalFlow;
432 }
433
434 void RenderLayerStackingNode::updateIsNormalFlowOnly()
435 {
436     bool isNormalFlowOnly = shouldBeNormalFlowOnly();
437     if (isNormalFlowOnly == this->isNormalFlowOnly())
438         return;
439
440     m_isNormalFlowOnly = isNormalFlowOnly;
441     if (RenderLayer* p = layer()->parent())
442         p->stackingNode()->dirtyNormalFlowList();
443     dirtyStackingContainerZOrderLists();
444 }
445
446 bool RenderLayerStackingNode::needsToBeStackingContainer() const
447 {
448     return layer()->scrollableArea() && layer()->scrollableArea()->adjustForForceCompositedScrollingMode(m_needsToBeStackingContainer);
449 }
450
451 // Determine whether the current layer can be promoted to a stacking container.
452 // We do this by computing what positive and negative z-order lists would look
453 // like before and after promotion, and ensuring that proper stacking order is
454 // preserved between the two sets of lists.
455 void RenderLayerStackingNode::updateDescendantsAreContiguousInStackingOrder()
456 {
457     TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerStackingNode::updateDescendantsAreContiguousInStackingOrder");
458
459     if (isStackingContext() || !m_descendantsAreContiguousInStackingOrderDirty || !renderer()->acceleratedCompositingForOverflowScrollEnabled())
460         return;
461
462     if (!layer()->scrollsOverflow())
463         return;
464
465     RenderLayerStackingNode* stackingNode = ancestorStackingNode();
466     if (!stackingNode)
467         return;
468
469     OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderListBeforePromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
470     OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderListBeforePromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
471     OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderListAfterPromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
472     OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderListAfterPromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
473
474     collectBeforePromotionZOrderList(stackingNode, posZOrderListBeforePromote, negZOrderListBeforePromote);
475     collectAfterPromotionZOrderList(stackingNode, posZOrderListAfterPromote, negZOrderListAfterPromote);
476
477     size_t maxIndex = std::min(posZOrderListAfterPromote->size() + negZOrderListAfterPromote->size(), posZOrderListBeforePromote->size() + negZOrderListBeforePromote->size());
478
479     m_descendantsAreContiguousInStackingOrderDirty = false;
480     m_descendantsAreContiguousInStackingOrder = false;
481
482     const RenderLayerStackingNode* nodeAfterPromote = 0;
483     for (size_t i = 0; i < maxIndex && nodeAfterPromote != this; ++i) {
484         const RenderLayerStackingNode* nodeBeforePromote = i < negZOrderListBeforePromote->size()
485             ? negZOrderListBeforePromote->at(i)
486             : posZOrderListBeforePromote->at(i - negZOrderListBeforePromote->size());
487         nodeAfterPromote = i < negZOrderListAfterPromote->size()
488             ? negZOrderListAfterPromote->at(i)
489             : posZOrderListAfterPromote->at(i - negZOrderListAfterPromote->size());
490
491         if (nodeBeforePromote != nodeAfterPromote && (nodeAfterPromote != this || renderer()->hasBackground()))
492             return;
493     }
494
495     nodeAfterPromote = 0;
496     for (size_t i = 0; i < maxIndex && nodeAfterPromote != this; ++i) {
497         const RenderLayerStackingNode* nodeBeforePromote = i < posZOrderListBeforePromote->size()
498             ? posZOrderListBeforePromote->at(posZOrderListBeforePromote->size() - i - 1)
499             : negZOrderListBeforePromote->at(negZOrderListBeforePromote->size() + posZOrderListBeforePromote->size() - i - 1);
500         nodeAfterPromote = i < posZOrderListAfterPromote->size()
501             ? posZOrderListAfterPromote->at(posZOrderListAfterPromote->size() - i - 1)
502             : negZOrderListAfterPromote->at(negZOrderListAfterPromote->size() + posZOrderListAfterPromote->size() - i - 1);
503
504         if (nodeBeforePromote != nodeAfterPromote && nodeAfterPromote != this)
505             return;
506     }
507
508     m_descendantsAreContiguousInStackingOrder = true;
509 }
510
511 void RenderLayerStackingNode::collectBeforePromotionZOrderList(RenderLayerStackingNode* ancestorStackingNode,
512     OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList)
513 {
514     ancestorStackingNode->rebuildZOrderLists(posZOrderList, negZOrderList, this, OnlyStackingContextsCanBeStackingContainers);
515
516     const RenderLayer* currentLayer = layer();
517     const RenderLayer* positionedAncestor = currentLayer->parent();
518     while (positionedAncestor && !positionedAncestor->isPositionedContainer() && !positionedAncestor->stackingNode()->isStackingContext())
519         positionedAncestor = positionedAncestor->parent();
520     if (positionedAncestor && (!positionedAncestor->isPositionedContainer() || positionedAncestor->stackingNode()->isStackingContext()))
521         positionedAncestor = 0;
522
523     if (!posZOrderList)
524         posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>());
525     else if (posZOrderList->find(this) != kNotFound)
526         return;
527
528     // The current node will appear in the z-order lists after promotion, so
529     // for a meaningful comparison, we must insert it in the z-order lists
530     // before promotion if it does not appear there already.
531     if (!positionedAncestor) {
532         posZOrderList->prepend(this);
533         return;
534     }
535
536     for (size_t index = 0; index < posZOrderList->size(); index++) {
537         if (posZOrderList->at(index)->layer() == positionedAncestor) {
538             posZOrderList->insert(index + 1, this);
539             return;
540         }
541     }
542 }
543
544 void RenderLayerStackingNode::collectAfterPromotionZOrderList(RenderLayerStackingNode* ancestorStackingNode,
545     OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList)
546 {
547     ancestorStackingNode->rebuildZOrderLists(posZOrderList, negZOrderList, this, ForceLayerToStackingContainer);
548 }
549
550 // Compute what positive and negative z-order lists would look like before and
551 // after promotion, so we can later ensure that proper stacking order is
552 // preserved between the two sets of lists.
553 //
554 // A few examples:
555 // c = currentLayer
556 // - = negative z-order child of currentLayer
557 // + = positive z-order child of currentLayer
558 // a = positioned ancestor of currentLayer
559 // x = any other RenderLayer in the list
560 //
561 // (a) xxxxx-----++a+++x
562 // (b) xxx-----c++++++xx
563 //
564 // Normally the current layer would be painted in the normal flow list if it
565 // doesn't already appear in the positive z-order list. However, in the case
566 // that the layer has a positioned ancestor, it will paint directly after the
567 // positioned ancestor. In example (a), the current layer would be painted in
568 // the middle of its own positive z-order children, so promoting would cause a
569 // change in paint order (since a promoted layer will paint all of its positive
570 // z-order children strictly after it paints itself).
571 //
572 // In example (b), it is ok to promote the current layer only if it does not
573 // have a background. If it has a background, the background gets painted before
574 // the layer's negative z-order children, so again, a promotion would cause a
575 // change in paint order (causing the background to get painted after the
576 // negative z-order children instead of before).
577 //
578 void RenderLayerStackingNode::computePaintOrderList(PaintOrderListType type, Vector<RefPtr<Node> >& list)
579 {
580     OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderList;
581     OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderList;
582
583     RenderLayerStackingNode* stackingNode = ancestorStackingNode();
584     if (!stackingNode)
585         return;
586
587     switch (type) {
588     case BeforePromote:
589         collectBeforePromotionZOrderList(stackingNode, posZOrderList, negZOrderList);
590         break;
591     case AfterPromote:
592         collectAfterPromotionZOrderList(stackingNode, posZOrderList, negZOrderList);
593         break;
594     }
595
596     if (negZOrderList) {
597         for (size_t index = 0; index < negZOrderList->size(); ++index)
598             list.append(negZOrderList->at(index)->renderer()->node());
599     }
600
601     if (posZOrderList) {
602         for (size_t index = 0; index < posZOrderList->size(); ++index)
603             list.append(posZOrderList->at(index)->renderer()->node());
604     }
605 }
606
607 bool RenderLayerStackingNode::descendantsAreContiguousInStackingOrder() const
608 {
609     if (isStackingContext() || !ancestorStackingContainerNode())
610         return true;
611
612     ASSERT(!m_descendantsAreContiguousInStackingOrderDirty);
613     return m_descendantsAreContiguousInStackingOrder;
614 }
615
616 bool RenderLayerStackingNode::setNeedsToBeStackingContainer(bool needsToBeStackingContainer)
617 {
618     if (this->needsToBeStackingContainer() == needsToBeStackingContainer)
619         return false;
620
621     // Count the total number of RenderLayers which need to be stacking
622     // containers some point. This should be recorded at most once per
623     // RenderLayer, so we check m_needsToBeStackingContainerHasBeenRecorded.
624     if (renderer()->acceleratedCompositingForOverflowScrollEnabled() && !m_needsToBeStackingContainerHasBeenRecorded) {
625         blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", NeedsToBeStackingContainerBucket, CompositedScrollingHistogramMax);
626         m_needsToBeStackingContainerHasBeenRecorded = true;
627     }
628
629     m_needsToBeStackingContainer = needsToBeStackingContainer;
630
631     return true;
632 }
633
634 RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingContainerNode() const
635 {
636     RenderLayer* ancestor = layer()->parent();
637     while (ancestor && !ancestor->stackingNode()->isStackingContainer())
638         ancestor = ancestor->parent();
639     if (ancestor)
640         return ancestor->stackingNode();
641     return 0;
642 }
643
644 RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingNode() const
645 {
646     RenderLayer* ancestor = layer()->parent();
647     while (ancestor && !ancestor->stackingNode()->isStackingContext())
648         ancestor = ancestor->parent();
649     if (ancestor)
650         return ancestor->stackingNode();
651     return 0;
652 }
653
654 RenderLayerModelObject* RenderLayerStackingNode::renderer() const
655 {
656     return m_layer->renderer();
657 }
658
659 } // namespace WebCore