Skip to content

Commit

Permalink
Cherry-pick 2e1ca5a. rdar://problem/113420795
Browse files Browse the repository at this point in the history
    Compositing overlap testing is broken with filters in some configurations
    https://bugs.webkit.org/show_bug.cgi?id=259848
    rdar://113420795

    Reviewed by Alan Baradlay.

    `RenderLayer::overlapBounds()` needs to return a rectangle which doesn't include the layer's own transform,
    since the caller applies the transform. However, if the layer has a filter that moves pixels (causing
    `overlapBoundsIncludeChildren()` to return true), then it used `defaultCalculateLayerBoundsFlags()`
    which includes `IncludeSelfTransform`.

    So pass a set of flags that cause the transform to be ignored.

    The tests exercise a filtered layer overlapping another layer, and other layers overlapping a filtered
    layer.

    This is part of a set of issues that affect reddit.com (rdar://112807737).

    * LayoutTests/compositing/layer-creation/overlap-transform-filter-contribution-expected.txt: Added.
    * LayoutTests/compositing/layer-creation/overlap-transform-filter-contribution.html: Added.
    * LayoutTests/compositing/layer-creation/overlap-transform-filter-expected.txt: Added.
    * LayoutTests/compositing/layer-creation/overlap-transform-filter.html: Added.
    * Source/WebCore/rendering/RenderLayer.cpp:
    (WebCore::RenderLayer::calculateClipRects const):
    * Source/WebCore/rendering/RenderLayerBacking.cpp:
    (WebCore::operator<<):

    Canonical link: https://commits.webkit.org/266669@main
Identifier: 265423.767@safari-7616.1.27.10-branch
  • Loading branch information
smfr authored and MyahCobbs committed Aug 9, 2023
1 parent 995de11 commit faffcf2
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 785.00 630.00)
(children 1
(GraphicsLayer
(bounds 785.00 630.00)
(contentsOpaque 1)
(children 5
(GraphicsLayer
(position 209.00 251.00)
(bounds 200.00 300.00)
(opacity 0.50)
(contentsOpaque 1)
(drawsContent 1)
(transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [100.00 -100.00 0.00 1.00])
)
(GraphicsLayer
(position 310.00 150.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
(GraphicsLayer
(position 310.00 445.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
(GraphicsLayer
(position 505.00 445.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
(GraphicsLayer
(position 505.00 150.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
)
)
)
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<!DOCTYPE html>

<html>
<head>
<style>
.container {
position: relative;
margin: 200px;
border: 1px solid black;
width: 200px;
height: 200px;

}
.box {
position: absolute;
top: 50px;
left: 0px;
width: 100%;
height: 300px;
opacity: 0.5;
object-fit: cover;
background-color: blue;
filter: blur(4px);
transform: translate(100px, -100px);
will-change: transform;
}

.dot {
position: absolute;
top: 0;
left: 0;
height: 4px;
width: 4px;
background-color: silver;
}

</style>
<script>
if (window.testRunner)
testRunner.dumpAsText();

function makeCornerDots(centerLeft, centerTop)
{
const width = 2;
const height = 2;

const spacing = 20;

for (let row = 0; row < height; ++row) {
for (let col = 0; col < width; ++col) {
const dot = document.createElement('div');
dot.className = 'dot';
dot.style.left = `${centerLeft + spacing * col}px`
dot.style.top = `${centerTop + spacing * row}px`
document.body.appendChild(dot);
}
}
}

function makeDots()
{
makeCornerDots(290, 130);
makeCornerDots(290, 445);
makeCornerDots(505, 445);
makeCornerDots(505, 130);

if (window.testRunner)
document.getElementById("layers").innerText = window.internals.layerTreeAsText(document);
}

window.addEventListener('load', makeDots, false);
</script>
</head>
<body>
<div class="container">
<div class="box"></div>
</div>
<pre id="layers">Layer tree goes here</pre>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
 This element should be composited
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(children 2
(GraphicsLayer
(position 50.00 50.00)
(bounds 100.00 100.00)
(contentsOpaque 1)
(drawsContent 1)
)
(GraphicsLayer
(position 50.00 250.00)
(bounds 200.00 200.00)
(contentsOpaque 1)
(drawsContent 1)
(transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [100.00 -100.00 0.00 1.00])
)
)
)
)
)

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html>
<head>
<style>
.composited {
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
background-color: silver;
will-change: transform;
}

.box {
position: absolute;
top: 250px;
left: 50px;
width: 200px;
height: 200px;
background-color: blue;
filter: blur(1px);
transform: translate(100px, -100px);
}
</style>
<script>
if (window.testRunner)
testRunner.dumpAsText();

window.addEventListener('load', () => {
if (window.testRunner)
document.getElementById("layers").innerText = window.internals.layerTreeAsText(document);
}, false);
</script>
</head>
<body>
<div class="composited">&nbsp;</div>
<div class="box">This element should be composited</div>
<pre id="layers">Layer tree goes here</pre>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 629.00)
(children 1
(GraphicsLayer
(bounds 800.00 629.00)
(contentsOpaque 1)
(children 5
(GraphicsLayer
(position 209.00 251.00)
(bounds 200.00 300.00)
(opacity 0.50)
(contentsOpaque 1)
(drawsContent 1)
(transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [100.00 -100.00 0.00 1.00])
)
(GraphicsLayer
(position 310.00 150.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
(GraphicsLayer
(position 310.00 445.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
(GraphicsLayer
(position 505.00 445.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
(GraphicsLayer
(position 505.00 150.00)
(bounds 4.00 4.00)
(contentsOpaque 1)
)
)
)
)
)

4 changes: 2 additions & 2 deletions Source/WebCore/rendering/RenderLayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4936,8 +4936,8 @@ FloatRect RenderLayer::absoluteBoundingBoxForPainting() const
LayoutRect RenderLayer::overlapBounds() const
{
if (overlapBoundsIncludeChildren())
return calculateLayerBounds(this, { }, defaultCalculateLayerBoundsFlags() | IncludeFilterOutsets);
return calculateLayerBounds(this, { }, { UseLocalClipRectIfPossible, IncludeFilterOutsets, UseFragmentBoxesExcludingCompositing });

return localBoundingBox();
}

Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderLayerBacking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4255,7 +4255,7 @@ TextStream& operator<<(TextStream& ts, const RenderLayerBacking& backing)
if (backing.paintsIntoCompositedAncestor())
ts << " paintsIntoCompositedAncestor";

ts << " primary layer ID " << backing.graphicsLayer()->primaryLayerID();
ts << " primary layer ID " << backing.graphicsLayer()->primaryLayerID().object();
if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::ViewportConstrained))
ts << " viewport constrained scrolling node " << nodeID;
if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling))
Expand Down

0 comments on commit faffcf2

Please sign in to comment.