Commit da4450bf authored by Morten Stenshorne's avatar Morten Stenshorne Committed by Commit Bot

Partially fix perf regression in HitTestContentsForFragments().

Copying a HitTestLocation object has a cost in the (micro)benchmark
perf_tests/events/hit-test-lots-of-layers.html , so only do this when
it's necessary.

This still doesn't bring performance back to what it used to be prior to
CL:2490111, but the second half of the regression is due to the fact that
HitTestContentsForFragments() no longer gets inlined automatically,
presumably because the code size now exceeds some magical limit.

Had to update a DCHECK in LayoutInline::NodeAtPoint(), since we now only
set a target fragment if there is more than one of them.

Bug: 1142801b
Change-Id: I7845aac259a187610e8cf929d5859875af436d51
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2503555Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: default avatarKoji Ishii <kojii@chromium.org>
Commit-Queue: Morten Stenshorne <mstensho@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821889}
parent d2cf48ea
......@@ -1119,7 +1119,10 @@ bool LayoutInline::NodeAtPoint(HitTestResult& result,
if (!cursor)
return false;
int target_fragment_idx = hit_test_location.FragmentIndex();
DCHECK(!CanTraversePhysicalFragments() || target_fragment_idx >= 0);
// Fragment traversal requires a target fragment to be specified,
// unless there's only one.
DCHECK(!CanTraversePhysicalFragments() || target_fragment_idx >= 0 ||
!FirstFragment().NextFragment());
// Convert from inline fragment index to container fragment index, as the
// inline may not start in the first fragment generated for the inline
// formatting context.
......
......@@ -2255,18 +2255,21 @@ bool PaintLayer::HitTestContentsForFragments(
PhysicalOffset fragment_offset = offset;
fragment_offset += fragment.layer_bounds.offset;
// When hit-testing a relatively positioned inline, we'll search for it in
// each fragment of the containing block. Each fragment has its own offset,
// and we need to do one fragment at a time.
int limit_to_fragment = -1;
if (GetLayoutObject().IsLayoutInline() &&
GetLayoutObject().CanTraversePhysicalFragments())
limit_to_fragment = i;
HitTestLocation location_for_fragment(hit_test_location, limit_to_fragment);
if (HitTestContents(result, fragment.physical_fragment, fragment_offset,
location_for_fragment, hit_test_filter))
if (UNLIKELY(layer_fragments.size() > 1 &&
GetLayoutObject().IsLayoutInline() &&
GetLayoutObject().CanTraversePhysicalFragments())) {
// When hit-testing a relatively positioned inline, we'll search for it in
// each fragment of the containing block. Each fragment has its own
// offset, and we need to do one fragment at a time.
HitTestLocation location_for_fragment(hit_test_location, i);
if (HitTestContents(result, fragment.physical_fragment, fragment_offset,
location_for_fragment, hit_test_filter))
return true;
} else if (HitTestContents(result, fragment.physical_fragment,
fragment_offset, hit_test_location,
hit_test_filter)) {
return true;
}
}
return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment