Commit 880521f7 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Partial re-land: [IO] Only compute intersection observations if any property...

Partial re-land: [IO] Only compute intersection observations if any property tree state has changed, and only for full-frame updates.

This CL includes only the refactoring aspect of the original CL, not the part about avoiding
intersection observations when possible.

Bug: 831762
Change-Id: I6dd2786e61faedd4b3b6fdedc0f6d3080b4a9bf1
Reviewed-on: https://chromium-review.googlesource.com/1141065Reviewed-by: default avatarvmpstr <vmpstr@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576343}
parent 8ff771d9
......@@ -5,7 +5,6 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_VIEW_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_VIEW_H_
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/frame/embedded_content_view.h"
namespace blink {
......@@ -15,8 +14,7 @@ struct IntrinsicSizingInfo;
class CORE_EXPORT FrameView : public EmbeddedContentView {
public:
~FrameView() override = default;
virtual void UpdateViewportIntersectionsForSubtree(
DocumentLifecycle::LifecycleState) = 0;
virtual void UpdateViewportIntersectionsForSubtree() = 0;
virtual bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const = 0;
virtual bool HasIntrinsicSizingInfo() const = 0;
......
......@@ -2379,8 +2379,7 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
&current_update_lifecycle_phases_target_state_, target_state);
if (ShouldThrottleRendering()) {
UpdateViewportIntersectionsForSubtree(
std::min(target_state, DocumentLifecycle::kCompositingClean));
UpdateThrottlingStatusForSubtree();
return Lifecycle().GetState() == target_state;
}
......@@ -2410,7 +2409,7 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
}
if (target_state == DocumentLifecycle::kLayoutClean) {
UpdateViewportIntersectionsForSubtree(target_state);
UpdateThrottlingStatusForSubtree();
return Lifecycle().GetState() == target_state;
}
......@@ -2420,7 +2419,9 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
// OOPIF local frame roots that are throttled can return now that layout
// is clean and intersection observations can be calculated.
if (ShouldThrottleRendering()) {
UpdateViewportIntersectionsForSubtree(target_state);
if (target_state == DocumentLifecycle::kPaintClean)
UpdateViewportIntersectionsForSubtree();
UpdateThrottlingStatusForSubtree();
return Lifecycle().GetState() == target_state;
}
......@@ -2515,6 +2516,14 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
}
}
{
TRACE_EVENT0("blink,benchmark",
"LocalFrameView::UpdateViewportIntersectionsForSubtree");
SCOPED_UMA_AND_UKM_TIMER("Blink.IntersectionObservation.UpdateTime",
UkmMetricNames::kIntersectionObservation);
UpdateViewportIntersectionsForSubtree();
}
DCHECK(!frame_->Selection().NeedsLayoutSelectionUpdate());
DCHECK(ShouldThrottleRendering() ||
(frame_->GetDocument()->Printing() &&
......@@ -2530,13 +2539,7 @@ bool LocalFrameView::UpdateLifecyclePhasesInternal(
});
}
{
TRACE_EVENT0("blink,benchmark",
"LocalFrameView::UpdateViewportIntersectionsForSubtree");
SCOPED_UMA_AND_UKM_TIMER("Blink.IntersectionObservation.UpdateTime",
UkmMetricNames::kIntersectionObservation);
UpdateViewportIntersectionsForSubtree(target_state);
}
UpdateThrottlingStatusForSubtree();
return Lifecycle().GetState() == target_state;
}
......@@ -3871,8 +3874,7 @@ void LocalFrameView::CollectAnnotatedRegions(
CollectAnnotatedRegions(*curr, regions);
}
void LocalFrameView::UpdateViewportIntersectionsForSubtree(
DocumentLifecycle::LifecycleState target_state) {
void LocalFrameView::UpdateViewportIntersectionsForSubtree() {
// TODO(dcheng): Since LocalFrameView tree updates are deferred, FrameViews
// might still be in the LocalFrameView hierarchy even though the associated
// Document is already detached. Investigate if this check and a similar check
......@@ -3881,19 +3883,29 @@ void LocalFrameView::UpdateViewportIntersectionsForSubtree(
if (!GetFrame().GetDocument()->IsActive())
return;
if (target_state == DocumentLifecycle::kPaintClean) {
RecordDeferredLoadingStats();
if (!NeedsLayout()) {
// Notify javascript IntersectionObservers
if (GetFrame().GetDocument()->GetIntersectionObserverController()) {
GetFrame()
.GetDocument()
->GetIntersectionObserverController()
->ComputeTrackedIntersectionObservations();
}
RecordDeferredLoadingStats();
if (!NeedsLayout()) {
// Notify javascript IntersectionObservers
if (GetFrame().GetDocument()->GetIntersectionObserverController()) {
GetFrame()
.GetDocument()
->GetIntersectionObserverController()
->ComputeTrackedIntersectionObservations();
}
}
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
child->View()->UpdateViewportIntersectionsForSubtree();
}
needs_intersection_observation_ = false;
}
void LocalFrameView::UpdateThrottlingStatusForSubtree() {
if (!GetFrame().GetDocument()->IsActive())
return;
// Don't throttle display:none frames (see updateRenderThrottlingStatus).
HTMLFrameOwnerElement* owner_element = frame_->DeprecatedLocalOwner();
if (hidden_for_throttling_ && owner_element &&
......@@ -3905,11 +3917,9 @@ void LocalFrameView::UpdateViewportIntersectionsForSubtree(
kDontNotifyChildren);
}
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
child->View()->UpdateViewportIntersectionsForSubtree(target_state);
}
needs_intersection_observation_ = false;
ForAllChildLocalFrameViews([](LocalFrameView& child_view) {
child_view.UpdateThrottlingStatusForSubtree();
});
}
void LocalFrameView::UpdateRenderThrottlingStatusForTesting() {
......
......@@ -734,8 +734,8 @@ class CORE_EXPORT LocalFrameView final
template <typename Function>
void ForAllNonThrottledLocalFrameViews(const Function&);
void UpdateViewportIntersectionsForSubtree(
DocumentLifecycle::LifecycleState) override;
void UpdateViewportIntersectionsForSubtree() override;
void UpdateThrottlingStatusForSubtree();
void NotifyResizeObservers();
......
......@@ -63,12 +63,9 @@ RemoteFrameView* RemoteFrameView::Create(RemoteFrame* remote_frame) {
return view;
}
void RemoteFrameView::UpdateViewportIntersectionsForSubtree(
DocumentLifecycle::LifecycleState target_state) {
void RemoteFrameView::UpdateViewportIntersectionsForSubtree() {
if (!remote_frame_->OwnerLayoutObject())
return;
if (target_state < DocumentLifecycle::kPaintClean)
return;
LocalFrameView* local_root_view =
ToLocalFrame(remote_frame_->Tree().Parent())->LocalFrameRoot().View();
......
......@@ -56,8 +56,7 @@ class RemoteFrameView final : public GarbageCollectedFinalized<RemoteFrameView>,
void Show() override;
void SetParentVisible(bool) override;
void UpdateViewportIntersectionsForSubtree(
DocumentLifecycle::LifecycleState) override;
void UpdateViewportIntersectionsForSubtree() override;
bool GetIntrinsicSizingInfo(IntrinsicSizingInfo&) const override;
......
......@@ -710,6 +710,9 @@ TEST_P(FrameThrottlingTest,
// layout, but should still unthrottle the frame.
frame_element->setAttribute(styleAttr, "transform: translateY(0px)");
CompositeFrame(); // Unthrottle the frame.
EXPECT_FALSE(
frame_element->contentDocument()->View()->ShouldThrottleRendering());
CompositeFrame(); // Handle the pending visual update of the unthrottled
// frame.
EXPECT_EQ(DocumentLifecycle::kPaintClean,
......
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