Remove CSS_FILTERS flag
[WebKit-https.git] / Source / WebCore / rendering / RenderLayerModelObject.cpp
1 /*
2  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4  *           (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5  *           (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6  * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7  * Copyright (C) 2010, 2012 Google Inc. All rights reserved.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #include "config.h"
26 #include "RenderLayerModelObject.h"
27
28 #include "RenderLayer.h"
29 #include "RenderView.h"
30
31 namespace WebCore {
32
33 bool RenderLayerModelObject::s_wasFloating = false;
34 bool RenderLayerModelObject::s_hadLayer = false;
35 bool RenderLayerModelObject::s_hadTransform = false;
36 bool RenderLayerModelObject::s_layerWasSelfPainting = false;
37
38 RenderLayerModelObject::RenderLayerModelObject(Element& element, PassRef<RenderStyle> style, unsigned baseTypeFlags)
39     : RenderElement(element, WTF::move(style), baseTypeFlags | RenderLayerModelObjectFlag)
40 {
41 }
42
43 RenderLayerModelObject::RenderLayerModelObject(Document& document, PassRef<RenderStyle> style, unsigned baseTypeFlags)
44     : RenderElement(document, WTF::move(style), baseTypeFlags | RenderLayerModelObjectFlag)
45 {
46 }
47
48 RenderLayerModelObject::~RenderLayerModelObject()
49 {
50     // Our layer should have been destroyed and cleared by now
51     ASSERT(!hasLayer());
52     ASSERT(!m_layer);
53 }
54
55 void RenderLayerModelObject::destroyLayer()
56 {
57     ASSERT(!hasLayer()); // Callers should have already called setHasLayer(false)
58     ASSERT(m_layer);
59     m_layer = nullptr;
60 }
61
62 void RenderLayerModelObject::createLayer()
63 {
64     ASSERT(!m_layer);
65     m_layer = std::make_unique<RenderLayer>(*this);
66     setHasLayer(true);
67     m_layer->insertOnlyThisLayer();
68 }
69
70 bool RenderLayerModelObject::hasSelfPaintingLayer() const
71 {
72     return m_layer && m_layer->isSelfPaintingLayer();
73 }
74
75 void RenderLayerModelObject::willBeDestroyed()
76 {
77     if (isPositioned()) {
78         if (style().hasViewportConstrainedPosition())
79             view().frameView().removeViewportConstrainedObject(this);
80     }
81
82     // RenderObject::willBeDestroyed calls back to destroyLayer() for layer destruction
83     RenderElement::willBeDestroyed();
84 }
85
86 void RenderLayerModelObject::styleWillChange(StyleDifference diff, const RenderStyle& newStyle)
87 {
88     s_wasFloating = isFloating();
89     s_hadLayer = hasLayer();
90     s_hadTransform = hasTransform();
91     if (s_hadLayer)
92         s_layerWasSelfPainting = layer()->isSelfPaintingLayer();
93
94     // If our z-index changes value or our visibility changes,
95     // we need to dirty our stacking context's z-order list.
96     const RenderStyle* oldStyle = hasInitializedStyle() ? &style() : nullptr;
97     if (oldStyle) {
98         if (parent()) {
99             // Do a repaint with the old style first, e.g., for example if we go from
100             // having an outline to not having an outline.
101             if (diff == StyleDifferenceRepaintLayer) {
102                 layer()->repaintIncludingDescendants();
103                 if (!(oldStyle->clip() == newStyle.clip()))
104                     layer()->clearClipRectsIncludingDescendants();
105             } else if (diff == StyleDifferenceRepaint || newStyle.outlineSize() < oldStyle->outlineSize())
106                 repaint();
107         }
108
109         if (diff == StyleDifferenceLayout || diff == StyleDifferenceSimplifiedLayout) {
110             // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could
111             // end up being destroyed.
112             if (hasLayer()) {
113                 if (oldStyle->position() != newStyle.position()
114                     || oldStyle->zIndex() != newStyle.zIndex()
115                     || oldStyle->hasAutoZIndex() != newStyle.hasAutoZIndex()
116                     || !(oldStyle->clip() == newStyle.clip())
117                     || oldStyle->hasClip() != newStyle.hasClip()
118                     || oldStyle->opacity() != newStyle.opacity()
119                     || oldStyle->transform() != newStyle.transform()
120                     || oldStyle->filter() != newStyle.filter()
121                     )
122                 layer()->repaintIncludingDescendants();
123             } else if (newStyle.hasTransform() || newStyle.opacity() < 1 || newStyle.hasFilter()) {
124                 // If we don't have a layer yet, but we are going to get one because of transform or opacity,
125                 //  then we need to repaint the old position of the object.
126                 repaint();
127             }
128         }
129     }
130
131     RenderElement::styleWillChange(diff, newStyle);
132 }
133
134 void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
135 {
136     RenderElement::styleDidChange(diff, oldStyle);
137     updateFromStyle();
138
139     if (requiresLayer()) {
140         if (!layer() && layerCreationAllowedForSubtree()) {
141             if (s_wasFloating && isFloating())
142                 setChildNeedsLayout();
143             createLayer();
144             if (parent() && !needsLayout() && containingBlock()) {
145                 layer()->setRepaintStatus(NeedsFullRepaint);
146                 // There is only one layer to update, it is not worth using |cachedOffset| since
147                 // we are not sure the value will be used.
148                 layer()->updateLayerPositions(0);
149             }
150         }
151     } else if (layer() && layer()->parent()) {
152 #if ENABLE(CSS_COMPOSITING)
153         if (oldStyle->hasBlendMode())
154             layer()->parent()->dirtyAncestorChainHasBlendingDescendants();
155 #endif
156         setHasTransform(false); // Either a transform wasn't specified or the object doesn't support transforms, so just null out the bit.
157         setHasReflection(false);
158         layer()->removeOnlyThisLayer(); // calls destroyLayer() which clears m_layer
159         if (s_wasFloating && isFloating())
160             setChildNeedsLayout();
161         if (s_hadTransform)
162             setNeedsLayoutAndPrefWidthsRecalc();
163     }
164
165     if (layer()) {
166         layer()->styleChanged(diff, oldStyle);
167         if (s_hadLayer && layer()->isSelfPaintingLayer() != s_layerWasSelfPainting)
168             setChildNeedsLayout();
169     }
170
171     bool newStyleIsViewportConstrained = style().hasViewportConstrainedPosition();
172     bool oldStyleIsViewportConstrained = oldStyle && oldStyle->hasViewportConstrainedPosition();
173     if (newStyleIsViewportConstrained != oldStyleIsViewportConstrained) {
174         if (newStyleIsViewportConstrained && layer())
175             view().frameView().addViewportConstrainedObject(this);
176         else
177             view().frameView().removeViewportConstrainedObject(this);
178     }
179 }
180
181 } // namespace WebCore
182