void RenderLayerStackingNode::collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posBuffer, OwnPtr<Vector<RenderLayerStackingNode*> >& negBuffer,
    const RenderLayerStackingNode* nodeToForceAsStackingContainer, CollectLayersBehavior collectLayersBehavior)
{
    if (layer()->isInTopLayer())
        return;

    layer()->updateDescendantDependentFlags();

    bool isStacking = false;
    bool isNormalFlow = false;

    switch (collectLayersBehavior) {
    case ForceLayerToStackingContainer:
        ASSERT(nodeToForceAsStackingContainer);
        if (this == nodeToForceAsStackingContainer) {
            isStacking = true;
            isNormalFlow = false;
        } else {
            isStacking = isStackingContext();
            isNormalFlow = shouldBeNormalFlowOnlyIgnoringCompositedScrolling();
        }
        break;
    case OverflowScrollCanBeStackingContainers:
        ASSERT(!nodeToForceAsStackingContainer);
        isStacking = isStackingContainer();
        isNormalFlow = isNormalFlowOnly();
        break;
    case OnlyStackingContextsCanBeStackingContainers:
        isStacking = isStackingContext();
        isNormalFlow = shouldBeNormalFlowOnlyIgnoringCompositedScrolling();
        break;
    }

    // Overflow layers are just painted by their enclosing layers, so they don't get put in zorder lists.
    if (!isNormalFlow && !layer()->isOutOfFlowRenderFlowThread()) {
        // Determine which buffer the child should be in.
        OwnPtr<Vector<RenderLayerStackingNode*> >& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;

        // Create the buffer if it doesn't exist yet.
        if (!buffer)
            buffer = adoptPtr(new Vector<RenderLayerStackingNode*>);

        // Append ourselves at the end of the appropriate buffer.
        buffer->append(this);
    }

    // Recur into our children to collect more layers, but only if we don't establish
    // a stacking context/container.
    if (!isStacking) {
        for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
            // Ignore reflections.
            if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
                child->stackingNode()->collectLayers(posBuffer, negBuffer, nodeToForceAsStackingContainer, collectLayersBehavior);
        }
    }
}
void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle)
{
    bool wasStackingContext = oldStyle ? !oldStyle->hasAutoZIndex() : false;
    int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;

    bool isStackingContext = this->isStackingContext();
    if (isStackingContext == wasStackingContext && oldZIndex == zIndex())
        return;

    dirtyStackingContextZOrderLists();

    if (isStackingContext)
        dirtyZOrderLists();
    else
        clearZOrderLists();
}
void PaintLayerStackingNode::collectLayers(
    std::unique_ptr<Vector<PaintLayerStackingNode*>>& posBuffer,
    std::unique_ptr<Vector<PaintLayerStackingNode*>>& negBuffer) {
  if (layer()->isInTopLayer())
    return;

  if (isStacked()) {
    std::unique_ptr<Vector<PaintLayerStackingNode*>>& buffer =
        (zIndex() >= 0) ? posBuffer : negBuffer;
    if (!buffer)
      buffer = wrapUnique(new Vector<PaintLayerStackingNode*>);
    buffer->append(this);
  }

  if (!isStackingContext()) {
    for (PaintLayer* child = layer()->firstChild(); child;
         child = child->nextSibling())
      child->stackingNode()->collectLayers(posBuffer, negBuffer);
  }
}
void RenderLayerStackingNode::collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posBuffer, OwnPtr<Vector<RenderLayerStackingNode*> >& negBuffer)
{
    if (layer()->isInTopLayer())
        return;

    layer()->updateDescendantDependentFlags();

    if (!isNormalFlowOnly()) {
        OwnPtr<Vector<RenderLayerStackingNode*> >& buffer = (zIndex() >= 0) ? posBuffer : negBuffer;
        if (!buffer)
            buffer = adoptPtr(new Vector<RenderLayerStackingNode*>);
        buffer->append(this);
    }

    if (!isStackingContext()) {
        for (RenderLayer* child = layer()->firstChild(); child; child = child->nextSibling()) {
            if (!layer()->reflectionInfo() || layer()->reflectionInfo()->reflectionLayer() != child)
                child->stackingNode()->collectLayers(posBuffer, negBuffer);
        }
    }
}
void PaintLayerStackingNode::styleDidChange(const ComputedStyle* oldStyle) {
  bool wasStackingContext = oldStyle ? oldStyle->isStackingContext() : false;
  int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;

  bool isStackingContext = this->isStackingContext();
  bool shouldBeStacked = layoutObject()->styleRef().isStacked();
  if (isStackingContext == wasStackingContext &&
      m_isStacked == shouldBeStacked && oldZIndex == zIndex())
    return;

  dirtyStackingContextZOrderLists();

  if (isStackingContext)
    dirtyZOrderLists();
  else
    clearZOrderLists();

  if (m_isStacked != shouldBeStacked) {
    m_isStacked = shouldBeStacked;
    if (!layoutObject()->documentBeingDestroyed() && !layer()->isRootLayer())
      compositor()->setNeedsCompositingUpdate(CompositingUpdateRebuildTree);
  }
}
void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle)
{
    bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
    EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
    int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;

    // FIXME: RenderLayer already handles visibility changes through our visiblity dirty bits. This logic could
    // likely be folded along with the rest.
    bool isStackingContext = this->isStackingContext();
    if (isStackingContext == wasStackingContext && oldVisibility == renderer()->style()->visibility() && oldZIndex == zIndex())
        return;

    dirtyStackingContainerZOrderLists();

    if (isStackingContainer())
        dirtyZOrderLists();
    else
        clearZOrderLists();

    compositor()->setNeedsUpdateCompositingRequirementsState();
}