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
53 namespace WebCore {
54
55 class RenderLayer;
56 class RenderLayerCompositor;
57 class RenderStyle;
58
59 class RenderLayerStackingNode {
60 WTF_MAKE_NONCOPYABLE(RenderLayerStackingNode);
61 public:
62 explicit RenderLayerStackingNode(RenderLayer*);
63 ~RenderLayerStackingNode();
64
zIndex()65 int zIndex() const { return renderer()->style()->zIndex(); }
66
67 // A stacking context is a layer that has a non-auto z-index.
isStackingContext()68 bool isStackingContext() const { return !renderer()->style()->hasAutoZIndex(); }
69
70 // Update our normal and z-index lists.
71 void updateLayerListsIfNeeded();
72
zOrderListsDirty()73 bool zOrderListsDirty() const { return m_zOrderListsDirty; }
74 void dirtyZOrderLists();
75 void updateZOrderLists();
76 void clearZOrderLists();
77 void dirtyStackingContextZOrderLists();
78
hasPositiveZOrderList()79 bool hasPositiveZOrderList() const { return posZOrderList() && posZOrderList()->size(); }
hasNegativeZOrderList()80 bool hasNegativeZOrderList() const { return negZOrderList() && negZOrderList()->size(); }
81
82 // FIXME: should check for dirtiness here?
isNormalFlowOnly()83 bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
84 void updateIsNormalFlowOnly();
normalFlowListDirty()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.
enclosingStackingContextNode()94 RenderLayerStackingNode* enclosingStackingContextNode() { return isStackingContext() ? this : ancestorStackingContextNode(); }
95
layer()96 RenderLayer* layer() const { return m_layer; }
97
98 #if ASSERT_ENABLED
layerListMutationAllowed()99 bool layerListMutationAllowed() const { return m_layerListMutationAllowed; }
setLayerListMutationAllowed(bool flag)100 void setLayerListMutationAllowed(bool flag) { m_layerListMutationAllowed = flag; }
101 #endif
102
103 private:
104 friend class RenderLayerStackingNodeIterator;
105 friend class RenderLayerStackingNodeReverseIterator;
106 friend class RenderTreeAsText;
107
posZOrderList()108 Vector<RenderLayerStackingNode*>* posZOrderList() const
109 {
110 ASSERT(!m_zOrderListsDirty);
111 ASSERT(isStackingContext() || !m_posZOrderList);
112 return m_posZOrderList.get();
113 }
114
normalFlowList()115 Vector<RenderLayerStackingNode*>* normalFlowList() const
116 {
117 ASSERT(!m_normalFlowListDirty);
118 return m_normalFlowList.get();
119 }
120
negZOrderList()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 ASSERT_ENABLED
132 bool isInStackingParentZOrderLists() const;
133 bool isInStackingParentNormalFlowList() const;
134 void updateStackingParentForZOrderLists(RenderLayerStackingNode* stackingParent);
135 void updateStackingParentForNormalFlowList(RenderLayerStackingNode* stackingParent);
setStackingParent(RenderLayerStackingNode * stackingParent)136 void setStackingParent(RenderLayerStackingNode* stackingParent) { m_stackingParent = stackingParent; }
137 #endif
138
139 bool shouldBeNormalFlowOnly() const;
140
141 void updateNormalFlowList();
142
isDirtyStackingContext()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 ASSERT_ENABLED
166 unsigned m_layerListMutationAllowed : 1;
167 RenderLayerStackingNode* m_stackingParent;
168 #endif
169 };
170
clearZOrderLists()171 inline void RenderLayerStackingNode::clearZOrderLists()
172 {
173 ASSERT(!isStackingContext());
174
175 #if ASSERT_ENABLED
176 updateStackingParentForZOrderLists(0);
177 #endif
178
179 m_posZOrderList.clear();
180 m_negZOrderList.clear();
181 }
182
updateZOrderLists()183 inline 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 ASSERT_ENABLED
198 class LayerListMutationDetector {
199 public:
LayerListMutationDetector(RenderLayerStackingNode * stackingNode)200 explicit LayerListMutationDetector(RenderLayerStackingNode* stackingNode)
201 : m_stackingNode(stackingNode)
202 , m_previousMutationAllowedState(stackingNode->layerListMutationAllowed())
203 {
204 m_stackingNode->setLayerListMutationAllowed(false);
205 }
206
~LayerListMutationDetector()207 ~LayerListMutationDetector()
208 {
209 m_stackingNode->setLayerListMutationAllowed(m_previousMutationAllowedState);
210 }
211
212 private:
213 RenderLayerStackingNode* m_stackingNode;
214 bool m_previousMutationAllowedState;
215 };
216 #endif
217
218 } // namespace WebCore
219
220 #endif // RenderLayerStackingNode_h
221