1/*
2 * Copyright (C) 2003, 2009, 2012 Apple Inc. All rights reserved.
3 * Copyright (C) 2013 Intel Corporation. All rights reserved.
4 *
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
6 *
7 * Other contributors:
8 *   Robert O'Callahan <roc+@cs.cmu.edu>
9 *   David Baron <dbaron@fas.harvard.edu>
10 *   Christian Biesinger <cbiesinger@web.de>
11 *   Randall Jesup <rjesup@wgate.com>
12 *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
13 *   Josh Soref <timeless@mac.com>
14 *   Boris Zbarsky <bzbarsky@mit.edu>
15 *
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
20 *
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
29 *
30 * Alternatively, the contents of this file may be used under the terms
31 * of either the Mozilla Public License Version 1.1, found at
32 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
33 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
34 * (the "GPL"), in which case the provisions of the MPL or the GPL are
35 * applicable instead of those above.  If you wish to allow use of your
36 * version of this file only under the terms of one of those two
37 * licenses (the MPL or the GPL) and not to allow others to use your
38 * version of this file under the LGPL, indicate your decision by
39 * deletingthe provisions above and replace them with the notice and
40 * other provisions required by the MPL or the GPL, as the case may be.
41 * If you do not delete the provisions above, a recipient may use your
42 * version of this file under any of the LGPL, the MPL or the GPL.
43 */
44
45#ifndef RenderLayerStackingNode_h
46#define RenderLayerStackingNode_h
47
48#include "core/rendering/RenderLayerModelObject.h"
49#include "wtf/Noncopyable.h"
50#include "wtf/OwnPtr.h"
51#include "wtf/Vector.h"
52
53namespace blink {
54
55class RenderLayer;
56class RenderLayerCompositor;
57class RenderStyle;
58
59class RenderLayerStackingNode {
60    WTF_MAKE_NONCOPYABLE(RenderLayerStackingNode);
61public:
62    explicit RenderLayerStackingNode(RenderLayer*);
63    ~RenderLayerStackingNode();
64
65    int zIndex() const { return renderer()->style()->zIndex(); }
66
67    // A stacking context is a layer that has a non-auto z-index.
68    bool isStackingContext() const { return !renderer()->style()->hasAutoZIndex(); }
69
70    // Update our normal and z-index lists.
71    void updateLayerListsIfNeeded();
72
73    bool zOrderListsDirty() const { return m_zOrderListsDirty; }
74    void dirtyZOrderLists();
75    void updateZOrderLists();
76    void clearZOrderLists();
77    void dirtyStackingContextZOrderLists();
78
79    bool hasPositiveZOrderList() const { return posZOrderList() && posZOrderList()->size(); }
80    bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); }
81
82    // FIXME: should check for dirtiness here?
83    bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
84    void updateIsNormalFlowOnly();
85    bool normalFlowListDirty() const { return m_normalFlowListDirty; }
86    void dirtyNormalFlowList();
87
88    void updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle);
89
90    RenderLayerStackingNode* ancestorStackingContextNode() const;
91
92    // Gets the enclosing stacking context for this node, possibly the node
93    // itself, if it is a stacking context.
94    RenderLayerStackingNode* enclosingStackingContextNode() { return isStackingContext() ? this : ancestorStackingContextNode(); }
95
96    RenderLayer* layer() const { return m_layer; }
97
98#if ENABLE(ASSERT)
99    bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
100    void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
101#endif
102
103private:
104    friend class RenderLayerStackingNodeIterator;
105    friend class RenderLayerStackingNodeReverseIterator;
106    friend class RenderTreeAsText;
107
108    Vector<RenderLayerStackingNode*>* posZOrderList() const
109    {
110        ASSERT(!m_zOrderListsDirty);
111        ASSERT(isStackingContext() || !m_posZOrderList);
112        return m_posZOrderList.get();
113    }
114
115    Vector<RenderLayerStackingNode*>* normalFlowList() const
116    {
117        ASSERT(!m_normalFlowListDirty);
118        return m_normalFlowList.get();
119    }
120
121    Vector<RenderLayerStackingNode*>* negZOrderList() const
122    {
123        ASSERT(!m_zOrderListsDirty);
124        ASSERT(isStackingContext() || !m_negZOrderList);
125        return m_negZOrderList.get();
126    }
127
128    void rebuildZOrderLists();
129    void collectLayers(OwnPtr<Vector<RenderLayerStackingNode*> >& posZOrderList, OwnPtr<Vector<RenderLayerStackingNode*> >& negZOrderList);
130
131#if ENABLE(ASSERT)
132    bool isInStackingParentZOrderLists() const;
133    bool isInStackingParentNormalFlowList() const;
134    void updateStackingParentForZOrderLists(RenderLayerStackingNode* stackingParent);
135    void updateStackingParentForNormalFlowList(RenderLayerStackingNode* stackingParent);
136    void setStackingParent(RenderLayerStackingNode* stackingParent) { m_stackingParent = stackingParent; }
137#endif
138
139    bool shouldBeNormalFlowOnly() const;
140
141    void updateNormalFlowList();
142
143    bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
144
145    RenderLayerCompositor* compositor() const;
146    // FIXME: Investigate changing this to Renderbox.
147    RenderLayerModelObject* renderer() const;
148
149    RenderLayer* m_layer;
150
151    // m_posZOrderList holds a sorted list of all the descendant nodes within
152    // that have z-indices of 0 or greater (auto will count as 0).
153    // m_negZOrderList holds descendants within our stacking context with
154    // negative z-indices.
155    OwnPtr<Vector<RenderLayerStackingNode*> > m_posZOrderList;
156    OwnPtr<Vector<RenderLayerStackingNode*> > m_negZOrderList;
157
158    // This list contains child nodes that cannot create stacking contexts.
159    OwnPtr<Vector<RenderLayerStackingNode*> > m_normalFlowList;
160
161    unsigned m_zOrderListsDirty : 1;
162    unsigned m_normalFlowListDirty: 1;
163    unsigned m_isNormalFlowOnly : 1;
164
165#if ENABLE(ASSERT)
166    unsigned m_layerListMutationAllowed : 1;
167    RenderLayerStackingNode* m_stackingParent;
168#endif
169};
170
171inline void RenderLayerStackingNode::clearZOrderLists()
172{
173    ASSERT(!isStackingContext());
174
175#if ENABLE(ASSERT)
176    updateStackingParentForZOrderLists(0);
177#endif
178
179    m_posZOrderList.clear();
180    m_negZOrderList.clear();
181}
182
183inline void RenderLayerStackingNode::updateZOrderLists()
184{
185    if (!m_zOrderListsDirty)
186        return;
187
188    if (!isStackingContext()) {
189        clearZOrderLists();
190        m_zOrderListsDirty = false;
191        return;
192    }
193
194    rebuildZOrderLists();
195}
196
197#if ENABLE(ASSERT)
198class LayerListMutationDetector {
199public:
200    explicit LayerListMutationDetector(RenderLayerStackingNode* stackingNode)
201        : m_stackingNode(stackingNode)
202        , m_previousMutationAllowedState(stackingNode->layerListMutationAllowed())
203    {
204        m_stackingNode->setLayerListMutationAllowed(false);
205    }
206
207    ~LayerListMutationDetector()
208    {
209        m_stackingNode->setLayerListMutationAllowed(m_previousMutationAllowedState);
210    }
211
212private:
213    RenderLayerStackingNode* m_stackingNode;
214    bool m_previousMutationAllowedState;
215};
216#endif
217
218} // namespace blink
219
220#endif // RenderLayerStackingNode_h
221