#ifndef RenderLayerStackingNode_h
#define RenderLayerStackingNode_h
#include "core/rendering/RenderLayerModelObject.h"
#include "wtf/Noncopyable.h"
#include "wtf/OwnPtr.h"
#include "wtf/Vector.h"
namespace WebCore {
class RenderLayer;
class RenderLayerCompositor;
class RenderStyle;
class RenderLayerStackingNode {
WTF_MAKE_NONCOPYABLE(RenderLayerStackingNode);
public:
explicit RenderLayerStackingNode(RenderLayer*);
~RenderLayerStackingNode();
int zIndex() const { return renderer()->style()->zIndex(); }
bool isStackingContext() const { return !renderer()->style()->hasAutoZIndex(); }
bool isStackingContainer() const { return isStackingContext() || needsToBeStackingContainer(); }
bool setNeedsToBeStackingContainer(bool);
bool descendantsAreContiguousInStackingOrder() const;
void setDescendantsAreContiguousInStackingOrderDirty(bool flag) { m_descendantsAreContiguousInStackingOrderDirty = flag; }
void updateDescendantsAreContiguousInStackingOrder();
void updateLayerListsIfNeeded();
bool zOrderListsDirty() const { return m_zOrderListsDirty; }
void dirtyZOrderLists();
void updateZOrderLists();
void clearZOrderLists();
void dirtyStackingContainerZOrderLists();
bool hasPositiveZOrderList() const { return posZOrderList() && posZOrderList()->size(); }
bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); }
bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
void updateIsNormalFlowOnly();
bool normalFlowListDirty() const { return m_normalFlowListDirty; }
void dirtyNormalFlowList();
enum PaintOrderListType {BeforePromote, AfterPromote};
void computePaintOrderList(PaintOrderListType, Vector<RefPtr<Node> >&);
void updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle);
RenderLayerStackingNode* ancestorStackingContainerNode() const;
RenderLayerStackingNode* ancestorStackingNode() const;
RenderLayerStackingNode* enclosingStackingContainerNode() { return isStackingContainer() ? this : ancestorStackingContainerNode(); }
RenderLayer* layer() const { return m_layer; }
#if !ASSERT_DISABLED
bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
#endif
private:
friend class RenderLayerStackingNodeIterator;
friend class RenderLayerStackingNodeReverseIterator;
friend class RenderTreeAsText;
Vector<RenderLayerStackingNode*>* posZOrderList() const
{
ASSERT(!m_zOrderListsDirty);
ASSERT(isStackingContainer() || !m_posZOrderList);
return m_posZOrderList.get();
}
Vector<RenderLayerStackingNode*>* normalFlowList() const
{
ASSERT(!m_normalFlowListDirty);
return m_normalFlowList.get();
}
Vector<RenderLayerStackingNode*>* negZOrderList() const
{
ASSERT(!m_zOrderListsDirty);
ASSERT(isStackingContainer() || !m_negZOrderList);
return m_negZOrderList.get();
}
enum CollectLayersBehavior {
ForceLayerToStackingContainer,
OverflowScrollCanBeStackingContainers,
OnlyStackingContextsCanBeStackingContainers
};
void rebuildZOrderLists();
void rebuildZOrderLists(OwnPtr<Vector<RenderLayerStackingNode*> >&, OwnPtr<Vector<RenderLayerStackingNode*> >&,
const RenderLayerStackingNode* nodeToForceAsStackingContainer = 0,
CollectLayersBehavior = OverflowScrollCanBeStackingContainers);
void collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >&,
OwnPtr<Vector<RenderLayerStackingNode*> >&, const RenderLayerStackingNode* nodeToForceAsStackingContainer = 0,
CollectLayersBehavior = OverflowScrollCanBeStackingContainers);
#if !ASSERT_DISABLED
bool isInStackingParentZOrderLists() const;
bool isInStackingParentNormalFlowList() const;
void updateStackingParentForZOrderLists(RenderLayerStackingNode* stackingParent);
void updateStackingParentForNormalFlowList(RenderLayerStackingNode* stackingParent);
void setStackingParent(RenderLayerStackingNode* stackingParent) { m_stackingParent = stackingParent; }
#endif
bool shouldBeNormalFlowOnly() const;
bool shouldBeNormalFlowOnlyIgnoringCompositedScrolling() const;
void updateNormalFlowList();
void dirtyNormalFlowListCanBePromotedToStackingContainer();
void dirtySiblingStackingNodeCanBePromotedToStackingContainer();
void collectBeforePromotionZOrderList(RenderLayerStackingNode*,
OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList);
void collectAfterPromotionZOrderList(RenderLayerStackingNode*,
OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList);
bool isDirtyStackingContainer() const { return m_zOrderListsDirty && isStackingContainer(); }
bool needsToBeStackingContainer() const;
RenderLayerCompositor* compositor() const;
RenderLayerModelObject* renderer() const;
RenderLayer* m_layer;
OwnPtr<Vector<RenderLayerStackingNode*> > m_posZOrderList;
OwnPtr<Vector<RenderLayerStackingNode*> > m_negZOrderList;
OwnPtr<Vector<RenderLayerStackingNode*> > m_normalFlowList;
unsigned m_descendantsAreContiguousInStackingOrder : 1;
unsigned m_descendantsAreContiguousInStackingOrderDirty : 1;
unsigned m_zOrderListsDirty : 1;
unsigned m_normalFlowListDirty: 1;
unsigned m_isNormalFlowOnly : 1;
unsigned m_needsToBeStackingContainer : 1;
unsigned m_needsToBeStackingContainerHasBeenRecorded : 1;
#if !ASSERT_DISABLED
unsigned m_layerListMutationAllowed : 1;
RenderLayerStackingNode* m_stackingParent;
#endif
};
inline void RenderLayerStackingNode::clearZOrderLists()
{
ASSERT(!isStackingContainer());
#if !ASSERT_DISABLED
updateStackingParentForZOrderLists(0);
#endif
m_posZOrderList.clear();
m_negZOrderList.clear();
}
inline void RenderLayerStackingNode::updateZOrderLists()
{
if (!m_zOrderListsDirty)
return;
if (!isStackingContainer()) {
clearZOrderLists();
m_zOrderListsDirty = false;
return;
}
rebuildZOrderLists();
}
#if !ASSERT_DISABLED
class LayerListMutationDetector {
public:
explicit LayerListMutationDetector(RenderLayerStackingNode* stackingNode)
: m_stackingNode(stackingNode)
, m_previousMutationAllowedState(stackingNode->layerListMutationAllowed())
{
m_stackingNode->setLayerListMutationAllowed(false);
}
~LayerListMutationDetector()
{
m_stackingNode->setLayerListMutationAllowed(m_previousMutationAllowedState);
}
private:
RenderLayerStackingNode* m_stackingNode;
bool m_previousMutationAllowedState;
};
#endif
}
#endif