Diff
Modified: trunk/Source/WebCore/ChangeLog (156189 => 156190)
--- trunk/Source/WebCore/ChangeLog 2013-09-20 19:29:47 UTC (rev 156189)
+++ trunk/Source/WebCore/ChangeLog 2013-09-20 19:56:33 UTC (rev 156190)
@@ -1,3 +1,24 @@
+2013-09-20 Antti Koivisto <[email protected]>
+
+ Move layer hierarchy functions from RenderObject to RenderElement
+ https://bugs.webkit.org/show_bug.cgi?id=121692
+
+ Reviewed by Andreas Kling.
+
+ * rendering/RenderElement.cpp:
+ (WebCore::RenderElement::addLayers):
+ (WebCore::RenderElement::removeLayers):
+ (WebCore::RenderElement::moveLayers):
+ (WebCore::RenderElement::findNextLayer):
+ (WebCore::RenderElement::layerCreationAllowedForSubtree):
+
+ Move these from RenderObject.
+
+ (WebCore::RenderElement::insertedIntoTree):
+ (WebCore::RenderElement::willBeRemovedFromTree):
+
+ Factor the layer related portion of these virtuals here.
+
2013-09-20 Benjamin Poulain <[email protected]>
Start cleaning the API of SelectorChecker
Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (156189 => 156190)
--- trunk/Source/WebCore/rendering/RenderElement.cpp 2013-09-20 19:29:47 UTC (rev 156189)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp 2013-09-20 19:56:33 UTC (rev 156190)
@@ -192,5 +192,159 @@
children()->removeChildNode(this, oldChild);
}
+static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderElement*& newObject, RenderLayer*& beforeChild)
+{
+ if (obj->hasLayer()) {
+ if (!beforeChild && newObject) {
+ // We need to figure out the layer that follows newObject. We only do
+ // this the first time we find a child layer, and then we update the
+ // pointer values for newObject and beforeChild used by everyone else.
+ beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
+ newObject = nullptr;
+ }
+ parentLayer->addChild(toRenderLayerModelObject(obj)->layer(), beforeChild);
+ return;
+ }
+ for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling())
+ addLayers(curr, parentLayer, newObject, beforeChild);
}
+
+void RenderElement::addLayers(RenderLayer* parentLayer)
+{
+ if (!parentLayer)
+ return;
+
+ RenderElement* renderer = this;
+ RenderLayer* beforeChild = nullptr;
+ WebCore::addLayers(this, parentLayer, renderer, beforeChild);
+}
+
+void RenderElement::removeLayers(RenderLayer* parentLayer)
+{
+ if (!parentLayer)
+ return;
+
+ if (hasLayer()) {
+ parentLayer->removeChild(toRenderLayerModelObject(this)->layer());
+ return;
+ }
+
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isRenderElement())
+ toRenderElement(child)->removeLayers(parentLayer);
+ }
+}
+
+void RenderElement::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
+{
+ if (!newParent)
+ return;
+
+ if (hasLayer()) {
+ RenderLayer* layer = toRenderLayerModelObject(this)->layer();
+ ASSERT(oldParent == layer->parent());
+ if (oldParent)
+ oldParent->removeChild(layer);
+ newParent->addChild(layer);
+ return;
+ }
+
+ for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+ if (child->isRenderElement())
+ toRenderElement(child)->moveLayers(oldParent, newParent);
+ }
+}
+
+RenderLayer* RenderElement::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent)
+{
+ // Error check the parent layer passed in. If it's null, we can't find anything.
+ if (!parentLayer)
+ return 0;
+
+ // Step 1: If our layer is a child of the desired parent, then return our layer.
+ RenderLayer* ourLayer = hasLayer() ? toRenderLayerModelObject(this)->layer() : nullptr;
+ if (ourLayer && ourLayer->parent() == parentLayer)
+ return ourLayer;
+
+ // Step 2: If we don't have a layer, or our layer is the desired parent, then descend
+ // into our siblings trying to find the next layer whose parent is the desired parent.
+ if (!ourLayer || ourLayer == parentLayer) {
+ for (RenderObject* child = startPoint ? startPoint->nextSibling() : firstChild(); child; child = child->nextSibling()) {
+ if (!child->isRenderElement())
+ continue;
+ RenderLayer* nextLayer = toRenderElement(child)->findNextLayer(parentLayer, nullptr, false);
+ if (nextLayer)
+ return nextLayer;
+ }
+ }
+
+ // Step 3: If our layer is the desired parent layer, then we're finished. We didn't
+ // find anything.
+ if (parentLayer == ourLayer)
+ return nullptr;
+
+ // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that
+ // follow us to see if we can locate a layer.
+ if (checkParent && parent())
+ return parent()->findNextLayer(parentLayer, this, true);
+
+ return nullptr;
+}
+
+bool RenderElement::layerCreationAllowedForSubtree() const
+{
+#if ENABLE(SVG)
+ RenderElement* parentRenderer = parent();
+ while (parentRenderer) {
+ if (parentRenderer->isSVGHiddenContainer())
+ return false;
+ parentRenderer = parentRenderer->parent();
+ }
+#endif
+
+ return true;
+}
+
+void RenderElement::insertedIntoTree()
+{
+ RenderObject::insertedIntoTree();
+
+ // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
+ // and don't have a layer attached to ourselves.
+ RenderLayer* layer = nullptr;
+ if (firstChild() || hasLayer()) {
+ layer = parent()->enclosingLayer();
+ addLayers(layer);
+ }
+
+ // If |this| is visible but this object was not, tell the layer it has some visible content
+ // that needs to be drawn and layer visibility optimization can't be used
+ if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
+ if (!layer)
+ layer = parent()->enclosingLayer();
+ if (layer)
+ layer->setHasVisibleContent();
+ }
+}
+
+void RenderElement::willBeRemovedFromTree()
+{
+ // If we remove a visible child from an invisible parent, we don't know the layer visibility any more.
+ RenderLayer* layer = nullptr;
+ if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
+ if ((layer = parent()->enclosingLayer()))
+ layer->dirtyVisibleContentStatus();
+ }
+ // Keep our layer hierarchy updated.
+ if (firstChild() || hasLayer()) {
+ if (!layer)
+ layer = parent()->enclosingLayer();
+ removeLayers(layer);
+ }
+
+ RenderObject::willBeRemovedFromTree();
+}
+
+
+}
Modified: trunk/Source/WebCore/rendering/RenderElement.h (156189 => 156190)
--- trunk/Source/WebCore/rendering/RenderElement.h 2013-09-20 19:29:47 UTC (rev 156189)
+++ trunk/Source/WebCore/rendering/RenderElement.h 2013-09-20 19:56:33 UTC (rev 156190)
@@ -43,19 +43,25 @@
virtual void addChildIgnoringContinuation(RenderObject* newChild, RenderObject* beforeChild = 0) { return addChild(newChild, beforeChild); }
virtual void removeChild(RenderObject*);
+ // The following functions are used when the render tree hierarchy changes to make sure layers get
+ // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
+ // can contain a mixture of boxes and other object types, these functions need to be in the base class.
+ void addLayers(RenderLayer* parentLayer);
+ void removeLayers(RenderLayer* parentLayer);
+ void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
+ RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
+
protected:
explicit RenderElement(Element*);
- LayoutUnit valueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages = false) const
- {
- return WebCore::valueForLength(length, maximumValue, &view(), roundPercentages);
- }
+ bool layerCreationAllowedForSubtree() const;
- LayoutUnit minimumValueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages = false) const
- {
- return WebCore::minimumValueForLength(length, maximumValue, &view(), roundPercentages);
- }
+ LayoutUnit valueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
+ LayoutUnit minimumValueForLength(const Length&, LayoutUnit maximumValue, bool roundPercentages = false) const;
+ virtual void insertedIntoTree() OVERRIDE;
+ virtual void willBeRemovedFromTree() OVERRIDE;
+
private:
void node() const WTF_DELETED_FUNCTION;
void nonPseudoNode() const WTF_DELETED_FUNCTION;
@@ -63,6 +69,16 @@
void isText() const WTF_DELETED_FUNCTION;
};
+inline LayoutUnit RenderElement::valueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const
+{
+ return WebCore::valueForLength(length, maximumValue, &view(), roundPercentages);
+}
+
+inline LayoutUnit RenderElement::minimumValueForLength(const Length& length, LayoutUnit maximumValue, bool roundPercentages) const
+{
+ return WebCore::minimumValueForLength(length, maximumValue, &view(), roundPercentages);
+}
+
inline RenderElement& toRenderElement(RenderObject& object)
{
ASSERT_WITH_SECURITY_IMPLICATION(object.isRenderElement());
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (156189 => 156190)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2013-09-20 19:29:47 UTC (rev 156189)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2013-09-20 19:56:33 UTC (rev 156190)
@@ -1898,8 +1898,10 @@
}
// Remove all descendant layers from the hierarchy and add them to the new position.
- for (RenderObject* curr = renderer().firstChild(); curr; curr = curr->nextSibling())
- curr->moveLayers(m_parent, this);
+ for (RenderObject* curr = renderer().firstChild(); curr; curr = curr->nextSibling()) {
+ if (curr->isRenderElement())
+ toRenderElement(curr)->moveLayers(m_parent, this);
+ }
// Clear out all the clip rects.
clearClipRectsIncludingDescendants();
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (156189 => 156190)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2013-09-20 19:29:47 UTC (rev 156189)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2013-09-20 19:56:33 UTC (rev 156190)
@@ -526,103 +526,6 @@
}
#endif // ENABLE(IOS_TEXT_AUTOSIZING)
-static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*& newObject,
- RenderLayer*& beforeChild)
-{
- if (obj->hasLayer()) {
- if (!beforeChild && newObject) {
- // We need to figure out the layer that follows newObject. We only do
- // this the first time we find a child layer, and then we update the
- // pointer values for newObject and beforeChild used by everyone else.
- beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject);
- newObject = 0;
- }
- parentLayer->addChild(toRenderLayerModelObject(obj)->layer(), beforeChild);
- return;
- }
-
- for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling())
- addLayers(curr, parentLayer, newObject, beforeChild);
-}
-
-void RenderObject::addLayers(RenderLayer* parentLayer)
-{
- if (!parentLayer)
- return;
-
- RenderObject* object = this;
- RenderLayer* beforeChild = 0;
- WebCore::addLayers(this, parentLayer, object, beforeChild);
-}
-
-void RenderObject::removeLayers(RenderLayer* parentLayer)
-{
- if (!parentLayer)
- return;
-
- if (hasLayer()) {
- parentLayer->removeChild(toRenderLayerModelObject(this)->layer());
- return;
- }
-
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
- curr->removeLayers(parentLayer);
-}
-
-void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent)
-{
- if (!newParent)
- return;
-
- if (hasLayer()) {
- RenderLayer* layer = toRenderLayerModelObject(this)->layer();
- ASSERT(oldParent == layer->parent());
- if (oldParent)
- oldParent->removeChild(layer);
- newParent->addChild(layer);
- return;
- }
-
- for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling())
- curr->moveLayers(oldParent, newParent);
-}
-
-RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint,
- bool checkParent)
-{
- // Error check the parent layer passed in. If it's null, we can't find anything.
- if (!parentLayer)
- return 0;
-
- // Step 1: If our layer is a child of the desired parent, then return our layer.
- RenderLayer* ourLayer = hasLayer() ? toRenderLayerModelObject(this)->layer() : 0;
- if (ourLayer && ourLayer->parent() == parentLayer)
- return ourLayer;
-
- // Step 2: If we don't have a layer, or our layer is the desired parent, then descend
- // into our siblings trying to find the next layer whose parent is the desired parent.
- if (!ourLayer || ourLayer == parentLayer) {
- for (RenderObject* curr = startPoint ? startPoint->nextSibling() : firstChild();
- curr; curr = curr->nextSibling()) {
- RenderLayer* nextLayer = curr->findNextLayer(parentLayer, 0, false);
- if (nextLayer)
- return nextLayer;
- }
- }
-
- // Step 3: If our layer is the desired parent layer, then we're finished. We didn't
- // find anything.
- if (parentLayer == ourLayer)
- return 0;
-
- // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that
- // follow us to see if we can locate a layer.
- if (checkParent && parent())
- return parent()->findNextLayer(parentLayer, this, true);
-
- return 0;
-}
-
RenderLayer* RenderObject::enclosingLayer() const
{
const RenderObject* curr = this;
@@ -635,20 +538,6 @@
return 0;
}
-bool RenderObject::layerCreationAllowedForSubtree() const
-{
-#if ENABLE(SVG)
- RenderElement* parentRenderer = parent();
- while (parentRenderer) {
- if (parentRenderer->isSVGHiddenContainer())
- return false;
- parentRenderer = parentRenderer->parent();
- }
-#endif
-
- return true;
-}
-
bool RenderObject::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
{
RenderLayer* enclosingLayer = this->enclosingLayer();
@@ -2586,23 +2475,6 @@
{
// FIXME: We should ASSERT(isRooted()) here but generated content makes some out-of-order insertion.
- // Keep our layer hierarchy updated. Optimize for the common case where we don't have any children
- // and don't have a layer attached to ourselves.
- RenderLayer* layer = 0;
- if (firstChild() || hasLayer()) {
- layer = parent()->enclosingLayer();
- addLayers(layer);
- }
-
- // If |this| is visible but this object was not, tell the layer it has some visible content
- // that needs to be drawn and layer visibility optimization can't be used
- if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
- if (!layer)
- layer = parent()->enclosingLayer();
- if (layer)
- layer->setHasVisibleContent();
- }
-
if (!isFloating() && parent()->childrenInline())
parent()->dirtyLinesFromChangedChild(this);
@@ -2620,20 +2492,6 @@
view().frameView().removeSlowRepaintObject(this);
}
- // If we remove a visible child from an invisible parent, we don't know the layer visibility any more.
- RenderLayer* layer = 0;
- if (parent()->style()->visibility() != VISIBLE && style()->visibility() == VISIBLE && !hasLayer()) {
- if ((layer = parent()->enclosingLayer()))
- layer->dirtyVisibleContentStatus();
- }
-
- // Keep our layer hierarchy updated.
- if (firstChild() || hasLayer()) {
- if (!layer)
- layer = parent()->enclosingLayer();
- removeLayers(layer);
- }
-
if (isOutOfFlowPositioned() && parent()->childrenInline())
parent()->dirtyLinesFromChangedChild(this);
Modified: trunk/Source/WebCore/rendering/RenderObject.h (156189 => 156190)
--- trunk/Source/WebCore/rendering/RenderObject.h 2013-09-20 19:29:47 UTC (rev 156189)
+++ trunk/Source/WebCore/rendering/RenderObject.h 2013-09-20 19:56:33 UTC (rev 156190)
@@ -220,14 +220,7 @@
void resetTextAutosizing();
#endif
- // The following six functions are used when the render tree hierarchy changes to make sure layers get
- // properly added and removed. Since containership can be implemented by any subclass, and since a hierarchy
- // can contain a mixture of boxes and other object types, these functions need to be in the base class.
RenderLayer* enclosingLayer() const;
- void addLayers(RenderLayer* parentLayer);
- void removeLayers(RenderLayer* parentLayer);
- void moveLayers(RenderLayer* oldParent, RenderLayer* newParent);
- RenderLayer* findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent = true);
// Scrolling is a RenderBox concept, however some code just cares about recursively scrolling our enclosing ScrollableArea(s).
bool scrollRectToVisible(const LayoutRect&, const ScrollAlignment& alignX = ScrollAlignment::alignCenterIfNeeded, const ScrollAlignment& alignY = ScrollAlignment::alignCenterIfNeeded);
@@ -992,8 +985,6 @@
RespectImageOrientationEnum shouldRespectImageOrientation() const;
protected:
- bool layerCreationAllowedForSubtree() const;
-
// Overrides should call the superclass at the end
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
// Overrides should call the superclass at the start