Skip to content

Commit

Permalink
REGRESSION(275801@main): In some cases, InteractionRegion layers accu…
Browse files Browse the repository at this point in the history
…mulate in the layer tree

https://bugs.webkit.org/show_bug.cgi?id=271195
<rdar://124972680>

Reviewed by Mike Wyrzykowski.

The code managing InteractionRegion layers in the RemoteLayerTree has a
strict requirement for no <IntRect, InteractionRegion::Type> duplicate.
We use the `m_interactionRects` / `m_occlusionRects` / `m_elementGuardRects`
sets on the EventRegionContext to ensure this.

But 275801@main introduced a code-path where we insert extra Interaction
Regions for photos in `shrinkWrapInteractionRegions`. We need to maintain
the no-duplicate rule there too.

* Source/WebCore/rendering/EventRegion.cpp:
(WebCore::EventRegionContext::shrinkWrapInteractionRegions):
Make sure the extra regions "to add after merge" do not create
<IntRect, InteractionRegion::Type> duplicates. Update the existing
region's content hint instead.

* LayoutTests/interaction-region/content-hint-overlap-dedupe-expected.txt: Added.
* LayoutTests/interaction-region/content-hint-overlap-dedupe.html: Added.
Add a test covering this and exercising the assertions in the
RemoteLayerTree code.

Canonical link: https://commits.webkit.org/276335@main
  • Loading branch information
etiennesegonzac committed Mar 19, 2024
1 parent 86ebc77 commit 3472dac
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #FFFFFF)
(event region
(rect (0,0) width=800 height=600)

(interaction regions [
(interaction (0,0) width=400 height=300)
(content hint photo)])
)
)
)
)

67 changes: 67 additions & 0 deletions LayoutTests/interaction-region/content-hint-overlap-dedupe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<style>
body { margin: 0; }

#interactive {
background: blue;
}
.rect {
position: absolute;
top: 0;
left: 0;
width: 400px;
height: 300px;
opacity: 0.5;
}
span {
position: absolute;
top: 200px;
left: 100px;
}
</style>
<script src="../resources/ui-helper.js"></script>
<body>
<section id="test">
<a href="#">
<div id="interactive" class="rect"></div>
<img src="../fast/media/resources/apple_logo_big.jpg" alt="apple logo" class="rect" />
<span>link</span>
</a>
<div id="counter"></div>
</section>

<pre id="results"></pre>
<script>
document.body.addEventListener("click", function(e) {
console.log(e, "event delegation");
});

if (window.testRunner) {
testRunner.waitUntilDone();
testRunner.dumpAsText();
}

window.onload = async function () {
if (!window.internals)
return;

await UIHelper.animationFrame();
await UIHelper.ensureStablePresentationUpdate();

// Re-render.
for (var i = 0; i <= 3; i++) {
document.getElementById("counter").textContent = i;
await UIHelper.animationFrame();
await UIHelper.ensureStablePresentationUpdate();
}

results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
document.getElementById('test').remove();

testRunner.notifyDone();
};
</script>
</body>
</html>

14 changes: 10 additions & 4 deletions Source/WebCore/rendering/EventRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,16 @@ void EventRegionContext::shrinkWrapInteractionRegions()
region.cornerRadius = 0;
}

for (auto& region : toAddAfterMerge) {
auto rectForTracking = enclosingIntRect(region.rectInLayerCoordinates);
region.contentHint = m_interactionRectsAndContentHints.get(rectForTracking);
m_interactionRegions.insert(++i, WTFMove(region));
auto finalRegionRectForTracking = enclosingIntRect(region.rectInLayerCoordinates);
for (auto& extraRegion : toAddAfterMerge) {
auto extraRectForTracking = enclosingIntRect(extraRegion.rectInLayerCoordinates);
// Do not insert a new region if it creates a duplicated Interaction Rect.
if (finalRegionRectForTracking == extraRectForTracking) {
region.contentHint = m_interactionRectsAndContentHints.get(extraRectForTracking);
continue;
}
extraRegion.contentHint = m_interactionRectsAndContentHints.get(extraRectForTracking);
m_interactionRegions.insert(++i, WTFMove(extraRegion));
}
}
}
Expand Down

0 comments on commit 3472dac

Please sign in to comment.