Skip to content

Commit

Permalink
RenderElement::addLayers should check for dialog content before inser…
Browse files Browse the repository at this point in the history
…ting layers

https://bugs.webkit.org/show_bug.cgi?id=241874

Reviewed by Simon Fraser.

addLayers stops (recursive) descending in the render tree soon after it finds a root (R) with layer.
It says that if a subtree root (R) has a layer then all layers in this subtree must have already been inserted into the layer tree at an earlier time.
(it simply assumes that any layer in the subtree is a child of (R), or some other layers in the subtree)

<div id=container>
  <div id=R>
    <div id=child>

The insertion is bottom to top; we attach
1, (child) to (R) first
2, followed by (R) to (container)
addLayers assumes that when (R) is being inserted (#2), we don't have to descend into (R)'s subtree since any renderer's layer that was inserted before (at #1) must have already been parented.

However toplayer/backdrop content is an exception where the parent layer may be outside of the subtree but still accessible. In such cases subsequent insertions (and the recursive nature of finding layer parents) could lead to double parenting where we try to insert the same layer into the layer tree multiple times.

* Source/WebCore/rendering/RenderElement.cpp:
(WebCore::addLayers):
(WebCore::RenderElement::insertedIntoTree):
(WebCore::RenderElement::addLayers): Deleted.
* Source/WebCore/rendering/RenderElement.h:

Canonical link: https://commits.webkit.org/251772@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@295767 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
alanbaradlay committed Jun 23, 2022
1 parent daa5f7a commit 21bee4c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 17 deletions.
32 changes: 16 additions & 16 deletions Source/WebCore/rendering/RenderElement.cpp
Expand Up @@ -636,26 +636,26 @@ static RenderLayer* layerNextSiblingRespectingTopLayer(const RenderElement& rend
return findNextLayer(*renderer.parent(), parentLayer, &renderer);
}

static void addLayers(const RenderElement& addedRenderer, RenderElement& currentRenderer, RenderLayer* parentLayer)
static void addLayers(const RenderElement& insertedRenderer, RenderElement& currentRenderer, RenderLayer& parentLayer)
{
if (currentRenderer.hasLayer()) {
if (isInTopLayerOrBackdrop(currentRenderer.style(), currentRenderer.element()))
parentLayer = addedRenderer.view().layer();
RenderLayer* beforeChild = layerNextSiblingRespectingTopLayer(addedRenderer, *parentLayer);
parentLayer->addChild(*downcast<RenderLayerModelObject>(currentRenderer).layer(), beforeChild);
auto* layerToUse = &parentLayer;
if (isInTopLayerOrBackdrop(currentRenderer.style(), currentRenderer.element())) {
// The special handling of a toplayer/backdrop content may result in trying to insert the associated
// layer twice as we connect subtrees.
if (auto* parentLayer = downcast<RenderLayerModelObject>(currentRenderer).layer()->parent()) {
ASSERT(parentLayer == currentRenderer.view().layer());
return;
}
layerToUse = insertedRenderer.view().layer();
}
auto* beforeChild = layerNextSiblingRespectingTopLayer(insertedRenderer, *layerToUse);
layerToUse->addChild(*downcast<RenderLayerModelObject>(currentRenderer).layer(), beforeChild);
return;
}

for (auto& child : childrenOfType<RenderElement>(currentRenderer))
addLayers(addedRenderer, child, parentLayer);
}

void RenderElement::addLayers(RenderLayer* parentLayer)
{
if (!parentLayer)
return;

WebCore::addLayers(*this, *this, parentLayer);
addLayers(insertedRenderer, child, parentLayer);
}

void RenderElement::removeLayers()
Expand Down Expand Up @@ -937,8 +937,8 @@ void RenderElement::insertedIntoTree(IsInternalMove isInternalMove)
// and don't have a layer attached to ourselves.
RenderLayer* parentLayer = nullptr;
if (firstChild() || hasLayer()) {
auto* parentLayer = layerParent();
addLayers(parentLayer);
if (auto* parentLayer = layerParent())
addLayers(*this, *this, *parentLayer);
}

// If |this| is visible but this object was not, tell the layer it has some visible content
Expand Down
1 change: 0 additions & 1 deletion Source/WebCore/rendering/RenderElement.h
Expand Up @@ -119,7 +119,6 @@ class RenderElement : public RenderObject {
// can contain a mixture of boxes and other object types, these functions need to be in the base class.
RenderLayer* layerParent() const;
RenderLayer* layerNextSibling(RenderLayer& parentLayer) const;
void addLayers(RenderLayer* parentLayer);
void removeLayers();
void moveLayers(RenderLayer& newParent);

Expand Down

0 comments on commit 21bee4c

Please sign in to comment.