Home | History | Annotate | Download | only in rendering
      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 (at) fas.harvard.edu>
      9  *   Christian Biesinger <cbiesinger (at) web.de>
     10  *   Randall Jesup <rjesup (at) wgate.com>
     11  *   Roland Mainz <roland.mainz (at) informatik.med.uni-giessen.de>
     12  *   Josh Soref <timeless (at) mac.com>
     13  *   Boris Zbarsky <bzbarsky (at) 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 (layer()->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 (layer()->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         || renderer()->style()->hasFlowFrom();
    431 
    432     return couldBeNormalFlow && !preventsElementFromBeingNormalFlow;
    433 }
    434 
    435 void RenderLayerStackingNode::updateIsNormalFlowOnly()
    436 {
    437     bool isNormalFlowOnly = shouldBeNormalFlowOnly();
    438     if (isNormalFlowOnly == this->isNormalFlowOnly())
    439         return;
    440 
    441     m_isNormalFlowOnly = isNormalFlowOnly;
    442     if (RenderLayer* p = layer()->parent())
    443         p->stackingNode()->dirtyNormalFlowList();
    444     dirtyStackingContainerZOrderLists();
    445 }
    446 
    447 bool RenderLayerStackingNode::needsToBeStackingContainer() const
    448 {
    449     return layer()->scrollableArea() && layer()->scrollableArea()->adjustForForceCompositedScrollingMode(m_needsToBeStackingContainer);
    450 }
    451 
    452 // Determine whether the current layer can be promoted to a stacking container.
    453 // We do this by computing what positive and negative z-order lists would look
    454 // like before and after promotion, and ensuring that proper stacking order is
    455 // preserved between the two sets of lists.
    456 void RenderLayerStackingNode::updateDescendantsAreContiguousInStackingOrder()
    457 {
    458     TRACE_EVENT0("blink_rendering,comp-scroll", "RenderLayerStackingNode::updateDescendantsAreContiguousInStackingOrder");
    459 
    460     const RenderLayer* currentLayer = layer();
    461     if (isStackingContext() || !m_descendantsAreContiguousInStackingOrderDirty || !currentLayer->acceleratedCompositingForOverflowScrollEnabled())
    462         return;
    463 
    464     if (!currentLayer->scrollsOverflow())
    465         return;
    466 
    467     RenderLayerStackingNode* stackingNode = ancestorStackingNode();
    468     if (!stackingNode)
    469         return;
    470 
    471     OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderListBeforePromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
    472     OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderListBeforePromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
    473     OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderListAfterPromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
    474     OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderListAfterPromote = adoptPtr(new Vector<RenderLayerStackingNode*>);
    475 
    476     collectBeforePromotionZOrderList(stackingNode, posZOrderListBeforePromote, negZOrderListBeforePromote);
    477     collectAfterPromotionZOrderList(stackingNode, posZOrderListAfterPromote, negZOrderListAfterPromote);
    478 
    479     size_t maxIndex = std::min(posZOrderListAfterPromote->size() + negZOrderListAfterPromote->size(), posZOrderListBeforePromote->size() + negZOrderListBeforePromote->size());
    480 
    481     m_descendantsAreContiguousInStackingOrderDirty = false;
    482     m_descendantsAreContiguousInStackingOrder = false;
    483 
    484     const RenderLayerStackingNode* nodeAfterPromote = 0;
    485     for (size_t i = 0; i < maxIndex && nodeAfterPromote != this; ++i) {
    486         const RenderLayerStackingNode* nodeBeforePromote = i < negZOrderListBeforePromote->size()
    487             ? negZOrderListBeforePromote->at(i)
    488             : posZOrderListBeforePromote->at(i - negZOrderListBeforePromote->size());
    489         nodeAfterPromote = i < negZOrderListAfterPromote->size()
    490             ? negZOrderListAfterPromote->at(i)
    491             : posZOrderListAfterPromote->at(i - negZOrderListAfterPromote->size());
    492 
    493         if (nodeBeforePromote != nodeAfterPromote && (nodeAfterPromote != this || renderer()->hasBackground()))
    494             return;
    495     }
    496 
    497     nodeAfterPromote = 0;
    498     for (size_t i = 0; i < maxIndex && nodeAfterPromote != this; ++i) {
    499         const RenderLayerStackingNode* nodeBeforePromote = i < posZOrderListBeforePromote->size()
    500             ? posZOrderListBeforePromote->at(posZOrderListBeforePromote->size() - i - 1)
    501             : negZOrderListBeforePromote->at(negZOrderListBeforePromote->size() + posZOrderListBeforePromote->size() - i - 1);
    502         nodeAfterPromote = i < posZOrderListAfterPromote->size()
    503             ? posZOrderListAfterPromote->at(posZOrderListAfterPromote->size() - i - 1)
    504             : negZOrderListAfterPromote->at(negZOrderListAfterPromote->size() + posZOrderListAfterPromote->size() - i - 1);
    505 
    506         if (nodeBeforePromote != nodeAfterPromote && nodeAfterPromote != this)
    507             return;
    508     }
    509 
    510     m_descendantsAreContiguousInStackingOrder = true;
    511 }
    512 
    513 void RenderLayerStackingNode::collectBeforePromotionZOrderList(RenderLayerStackingNode* ancestorStackingNode,
    514     OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList)
    515 {
    516     ancestorStackingNode->rebuildZOrderLists(posZOrderList, negZOrderList, this, OnlyStackingContextsCanBeStackingContainers);
    517 
    518     const RenderLayer* currentLayer = layer();
    519     const RenderLayer* positionedAncestor = currentLayer->parent();
    520     while (positionedAncestor && !positionedAncestor->isPositionedContainer() && !positionedAncestor->stackingNode()->isStackingContext())
    521         positionedAncestor = positionedAncestor->parent();
    522     if (positionedAncestor && (!positionedAncestor->isPositionedContainer() || positionedAncestor->stackingNode()->isStackingContext()))
    523         positionedAncestor = 0;
    524 
    525     if (!posZOrderList)
    526         posZOrderList = adoptPtr(new Vector<RenderLayerStackingNode*>());
    527     else if (posZOrderList->find(this) != kNotFound)
    528         return;
    529 
    530     // The current node will appear in the z-order lists after promotion, so
    531     // for a meaningful comparison, we must insert it in the z-order lists
    532     // before promotion if it does not appear there already.
    533     if (!positionedAncestor) {
    534         posZOrderList->prepend(this);
    535         return;
    536     }
    537 
    538     for (size_t index = 0; index < posZOrderList->size(); index++) {
    539         if (posZOrderList->at(index)->layer() == positionedAncestor) {
    540             posZOrderList->insert(index + 1, this);
    541             return;
    542         }
    543     }
    544 }
    545 
    546 void RenderLayerStackingNode::collectAfterPromotionZOrderList(RenderLayerStackingNode* ancestorStackingNode,
    547     OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList)
    548 {
    549     ancestorStackingNode->rebuildZOrderLists(posZOrderList, negZOrderList, this, ForceLayerToStackingContainer);
    550 }
    551 
    552 // Compute what positive and negative z-order lists would look like before and
    553 // after promotion, so we can later ensure that proper stacking order is
    554 // preserved between the two sets of lists.
    555 //
    556 // A few examples:
    557 // c = currentLayer
    558 // - = negative z-order child of currentLayer
    559 // + = positive z-order child of currentLayer
    560 // a = positioned ancestor of currentLayer
    561 // x = any other RenderLayer in the list
    562 //
    563 // (a) xxxxx-----++a+++x
    564 // (b) xxx-----c++++++xx
    565 //
    566 // Normally the current layer would be painted in the normal flow list if it
    567 // doesn't already appear in the positive z-order list. However, in the case
    568 // that the layer has a positioned ancestor, it will paint directly after the
    569 // positioned ancestor. In example (a), the current layer would be painted in
    570 // the middle of its own positive z-order children, so promoting would cause a
    571 // change in paint order (since a promoted layer will paint all of its positive
    572 // z-order children strictly after it paints itself).
    573 //
    574 // In example (b), it is ok to promote the current layer only if it does not
    575 // have a background. If it has a background, the background gets painted before
    576 // the layer's negative z-order children, so again, a promotion would cause a
    577 // change in paint order (causing the background to get painted after the
    578 // negative z-order children instead of before).
    579 //
    580 void RenderLayerStackingNode::computePaintOrderList(PaintOrderListType type, Vector<RefPtr<Node> >& list)
    581 {
    582     OwnPtr<Vector<RenderLayerStackingNode*> > posZOrderList;
    583     OwnPtr<Vector<RenderLayerStackingNode*> > negZOrderList;
    584 
    585     RenderLayerStackingNode* stackingNode = ancestorStackingNode();
    586     if (!stackingNode)
    587         return;
    588 
    589     switch (type) {
    590     case BeforePromote:
    591         collectBeforePromotionZOrderList(stackingNode, posZOrderList, negZOrderList);
    592         break;
    593     case AfterPromote:
    594         collectAfterPromotionZOrderList(stackingNode, posZOrderList, negZOrderList);
    595         break;
    596     }
    597 
    598     if (negZOrderList) {
    599         for (size_t index = 0; index < negZOrderList->size(); ++index)
    600             list.append(negZOrderList->at(index)->renderer()->node());
    601     }
    602 
    603     if (posZOrderList) {
    604         for (size_t index = 0; index < posZOrderList->size(); ++index)
    605             list.append(posZOrderList->at(index)->renderer()->node());
    606     }
    607 }
    608 
    609 bool RenderLayerStackingNode::descendantsAreContiguousInStackingOrder() const
    610 {
    611     if (isStackingContext() || !ancestorStackingContainerNode())
    612         return true;
    613 
    614     ASSERT(!m_descendantsAreContiguousInStackingOrderDirty);
    615     return m_descendantsAreContiguousInStackingOrder;
    616 }
    617 
    618 bool RenderLayerStackingNode::setNeedsToBeStackingContainer(bool needsToBeStackingContainer)
    619 {
    620     if (this->needsToBeStackingContainer() == needsToBeStackingContainer)
    621         return false;
    622 
    623     // Count the total number of RenderLayers which need to be stacking
    624     // containers some point. This should be recorded at most once per
    625     // RenderLayer, so we check m_needsToBeStackingContainerHasBeenRecorded.
    626     if (layer()->acceleratedCompositingForOverflowScrollEnabled() && !m_needsToBeStackingContainerHasBeenRecorded) {
    627         blink::Platform::current()->histogramEnumeration("Renderer.CompositedScrolling", RenderLayer::NeedsToBeStackingContainerBucket, RenderLayer::CompositedScrollingHistogramMax);
    628         m_needsToBeStackingContainerHasBeenRecorded = true;
    629     }
    630 
    631     m_needsToBeStackingContainer = needsToBeStackingContainer;
    632 
    633     return true;
    634 }
    635 
    636 RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingContainerNode() const
    637 {
    638     RenderLayer* ancestor = layer()->parent();
    639     while (ancestor && !ancestor->stackingNode()->isStackingContainer())
    640         ancestor = ancestor->parent();
    641     if (ancestor)
    642         return ancestor->stackingNode();
    643     return 0;
    644 }
    645 
    646 RenderLayerStackingNode* RenderLayerStackingNode::ancestorStackingNode() const
    647 {
    648     RenderLayer* ancestor = layer()->parent();
    649     while (ancestor && !ancestor->stackingNode()->isStackingContext())
    650         ancestor = ancestor->parent();
    651     if (ancestor)
    652         return ancestor->stackingNode();
    653     return 0;
    654 }
    655 
    656 RenderLayerModelObject* RenderLayerStackingNode::renderer() const
    657 {
    658     return m_layer->renderer();
    659 }
    660 
    661 } // namespace WebCore
    662