Skip to content

Commit

Permalink
Always create cached_rects_ for IntersectionOptimization
Browse files Browse the repository at this point in the history
This allows cached rects for implicit root with target in the outermost
main frame. If the target is in a sub frame, IntersectionGeometry won't
use the cached rects due to the relationship.

Bug: 1400495
Change-Id: Idc2efb9e3affbbcfacb87d989eaa0c139b6516e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4592749
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Stefan Zager <szager@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1156635}
  • Loading branch information
wangxianzhu authored and Chromium LUCI CQ committed Jun 13, 2023
1 parent 012d894 commit 5e59092
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,8 @@ IntersectionGeometry::PrepareComputeGeometry(const Node* root_node,
RootAndTarget root_and_target(root_node, target_element);

if (ShouldUseCachedRects()) {
CHECK(!RootIsImplicit());
CHECK(!RootIsImplicit() ||
RuntimeEnabledFeatures::IntersectionOptimizationEnabled());
// Cached rects can only be used if there are no scrollable objects in the
// hierarchy between target and root (a scrollable root is ok). The reason
// is that a scroll change in an intermediate scroller would change the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ IntersectionObservation::IntersectionObservation(IntersectionObserver& observer,
// should be -1, but since last_threshold_index_ is unsigned, we use a
// different sentinel value.
last_threshold_index_(kMaxThresholdIndex - 1) {
if (!observer.RootIsImplicit())
if (!observer.RootIsImplicit() ||
RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
// TODO(crbug.com/1400495): Avoid unique_ptr for IntersectionOptimization.
cached_rects_ = std::make_unique<IntersectionGeometry::CachedRects>();
}
}

int64_t IntersectionObservation::ComputeIntersection(
Expand All @@ -64,7 +67,8 @@ int64_t IntersectionObservation::ComputeIntersection(
[this](unsigned geometry_flags) {
return IntersectionGeometry(
observer_->root(), *Target(), observer_->RootMargin(),
observer_->thresholds(), observer_->TargetMargin(), geometry_flags);
observer_->thresholds(), observer_->TargetMargin(), geometry_flags,
cached_rects_.get());
},
compute_flags, monotonic_time);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,59 @@ TEST_P(IntersectionObserverTest, CachedRectsWithoutIntermediateScrollable) {
}
}

TEST_P(IntersectionObserverTest, CachedRectsImplicitRoot) {
WebView().MainFrameViewWidget()->Resize(gfx::Size(800, 600));
SimRequest main_resource("https://example.com/", "text/html");
SimRequest iframe_resource("https://example.com/iframe.html", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(R"HTML(
<div id="target-in-main">Hello, world!</div>
<iframe src="iframe.html" style="width:200px; height:100px"></iframe>
<div id='spacer' style='height:2000px'></div>
)HTML");
iframe_resource.Complete(R"HTML(
<div id='target-in-frame'>Hello, world!</div>
<div id='spacer' style='height:2000px'></div>
)HTML");

auto do_nothing = base::DoNothingAs<void(
const HeapVector<Member<IntersectionObserverEntry>>&)>();
IntersectionObserver* observer_in_main = IntersectionObserver::Create(
{}, {}, &GetDocument(), do_nothing, LocalFrameUkmAggregator::kLayout);
Document* iframe_document = To<WebLocalFrameImpl>(MainFrame().FirstChild())
->GetFrame()
->GetDocument();
Element* target_in_main = GetDocument().getElementById("target-in-main");
DummyExceptionStateForTesting exception_state;
observer_in_main->observe(target_in_main, exception_state);
ASSERT_FALSE(exception_state.HadException());

IntersectionObserver* observer_in_frame = IntersectionObserver::Create(
{}, {}, iframe_document, do_nothing, LocalFrameUkmAggregator::kLayout);
Element* target_in_frame = iframe_document->getElementById("target-in-frame");
observer_in_frame->observe(target_in_frame, exception_state);
ASSERT_FALSE(exception_state.HadException());

IntersectionObservation* observation_in_main =
target_in_main->IntersectionObserverData()->GetObservationFor(
*observer_in_main);
EXPECT_FALSE(observation_in_main->CanUseCachedRectsForTesting());
IntersectionObservation* observation_in_frame =
target_in_frame->IntersectionObserverData()->GetObservationFor(
*observer_in_frame);
EXPECT_FALSE(observation_in_frame->CanUseCachedRectsForTesting());

// Generate initial notifications and populate cache.
Compositor().BeginFrame();
test::RunPendingTasks();

if (RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
EXPECT_TRUE(observation_in_main->CanUseCachedRectsForTesting());
} else {
EXPECT_FALSE(observation_in_main->CanUseCachedRectsForTesting());
}
}

TEST_P(IntersectionObserverTest, MinScrollDeltaToUpdateThresholdZero) {
if (!RuntimeEnabledFeatures::IntersectionOptimizationEnabled()) {
return;
Expand Down

0 comments on commit 5e59092

Please sign in to comment.