@@ -65,7 +65,6 @@ void RemoteFrameView::AttachToLayout() {
65
65
SetParentVisible (true );
66
66
UpdateVisibility (true );
67
67
68
- SetupRenderThrottling ();
69
68
subtree_throttled_ = ParentFrameView ()->CanThrottleRendering ();
70
69
71
70
FrameRectsChanged ();
@@ -90,68 +89,54 @@ void RemoteFrameView::UpdateViewportIntersectionsForSubtree(
90
89
return ;
91
90
}
92
91
93
- LayoutEmbeddedContent* owner = remote_frame_->OwnerLayoutObject ();
92
+ // This should only run in child frames.
93
+ HTMLFrameOwnerElement* owner_element = remote_frame_->DeprecatedLocalOwner ();
94
+ DCHECK (owner_element);
95
+ LayoutEmbeddedContent* owner = owner_element->GetLayoutEmbeddedContent ();
94
96
if (!owner)
95
97
return ;
96
-
97
- LocalFrameView* local_root_view = ParentLocalRootFrameView ();
98
- if (!local_root_view)
99
- return ;
100
-
101
98
IntRect viewport_intersection;
102
99
bool occluded_or_obscured = false ;
103
- DocumentLifecycle::LifecycleState parent_state =
104
- owner->GetDocument ().Lifecycle ().GetState ();
105
100
106
101
// If the parent LocalFrameView is throttled and out-of-date, then we can't
107
102
// get any useful information.
103
+ DocumentLifecycle::LifecycleState parent_state =
104
+ owner_element->GetDocument ().Lifecycle ().GetState ();
108
105
if (parent_state >= DocumentLifecycle::kLayoutClean ) {
109
- // Start with rect in remote frame's coordinate space. Then
110
- // mapToVisualRectInAncestorSpace will move it to the local root's
111
- // coordinate space and account for any clip from containing elements such
112
- // as a scrollable div. Passing nullptr as an argument to
113
- // mapToVisualRectInAncestorSpace causes it to be clipped to the viewport,
114
- // even if there are RemoteFrame ancestors in the frame tree.
115
- LayoutRect rect (0 , 0 , frame_rect_.Width (), frame_rect_.Height ());
116
- rect.Move (owner->PhysicalContentBoxOffset ());
117
- if (owner->MapToVisualRectInAncestorSpace (nullptr , rect,
118
- kUseGeometryMapper )) {
119
- IntRect root_visible_rect (IntPoint (), local_root_view->Size ());
120
- IntRect intersected_rect = EnclosingIntRect (rect);
121
- intersected_rect.Intersect (root_visible_rect);
122
-
123
- // Translate the intersection rect from the root frame's coordinate space
124
- // to the remote frame's coordinate space.
125
- FloatRect viewport_intersection_float =
126
- remote_frame_->OwnerLayoutObject ()
127
- ->AncestorToLocalQuad (
128
- local_root_view->GetLayoutView (), FloatQuad (intersected_rect),
129
- kTraverseDocumentBoundaries | kUseTransforms )
130
- .BoundingBox ();
131
- viewport_intersection_float.Move (
132
- -remote_frame_->OwnerLayoutObject ()->PhysicalContentBoxOffset ());
133
- viewport_intersection = EnclosingIntRect (viewport_intersection_float);
106
+ unsigned geometry_flags =
107
+ IntersectionGeometry::kShouldUseReplacedContentRect ;
108
+ if (parent_state >= DocumentLifecycle::kPrePaintClean &&
109
+ RuntimeEnabledFeatures::IntersectionObserverV2Enabled ()) {
110
+ geometry_flags |= IntersectionGeometry::kShouldComputeVisibility ;
134
111
}
135
- }
136
-
137
- if (parent_state >= DocumentLifecycle::kPrePaintClean &&
138
- RuntimeEnabledFeatures::IntersectionObserverV2Enabled ()) {
139
- // TODO(layout-dev): As an optimization, we should only check for
140
- // occlusion and effects if the remote frame needs it, i.e., if it has at
141
- // least one active IntersectionObserver with trackVisibility:true.
142
- if (owner->GetDocument ()
143
- .GetFrame ()
144
- ->LocalFrameRoot ()
145
- .MayBeOccludedOrObscuredByRemoteAncestor () ||
146
- owner->HasDistortingVisualEffects ()) {
147
- occluded_or_obscured = true ;
112
+ IntersectionGeometry geometry (nullptr , *owner_element, {},
113
+ {IntersectionObserver::kMinimumThreshold },
114
+ geometry_flags);
115
+ // geometry.IntersectionRect() is in absolute coordinates of the owning
116
+ // document. Map it down to absolute coordinates in the child document.
117
+ LayoutRect intersection_rect = LayoutRect (
118
+ owner
119
+ ->AncestorToLocalQuad (
120
+ nullptr , FloatQuad (FloatRect (geometry.IntersectionRect ())),
121
+ kUseTransforms )
122
+ .BoundingBox ());
123
+ // Map from the box coordinates of the owner to the inner frame.
124
+ intersection_rect.Move (-owner->PhysicalContentBoxOffset ());
125
+ // Don't let EnclosingIntRect turn an empty rect into a non-empty one.
126
+ if (intersection_rect.IsEmpty ()) {
127
+ viewport_intersection =
128
+ IntRect (FlooredIntPoint (intersection_rect.Location ()), IntSize ());
148
129
} else {
149
- HitTestResult result (owner->HitTestForOcclusion ());
150
- occluded_or_obscured =
151
- result.InnerNode () && result.InnerNode () != owner->GetNode ();
130
+ viewport_intersection = EnclosingIntRect (intersection_rect);
152
131
}
132
+ occluded_or_obscured = !geometry.IsVisible ();
153
133
}
154
134
135
+ // TODO(szager): There are some redundant IPC's here; clean them up.
136
+ bool is_visible_for_throttling = !viewport_intersection.IsEmpty ();
137
+ UpdateVisibility (is_visible_for_throttling);
138
+ UpdateRenderThrottlingStatus (!is_visible_for_throttling, subtree_throttled_);
139
+
155
140
if (viewport_intersection == last_viewport_intersection_ &&
156
141
occluded_or_obscured == last_occluded_or_obscured_) {
157
142
return ;
@@ -341,29 +326,6 @@ void RemoteFrameView::UpdateVisibility(bool scroll_visible) {
341
326
remote_frame_->Client ()->VisibilityChanged (visibility);
342
327
}
343
328
344
- void RemoteFrameView::OnViewportIntersectionChanged (
345
- const HeapVector<Member<IntersectionObserverEntry>>& entries) {
346
- bool is_visible = entries.back ()->intersectionRatio () > 0 ;
347
- UpdateVisibility (is_visible);
348
- UpdateRenderThrottlingStatus (!is_visible, subtree_throttled_);
349
- }
350
-
351
- void RemoteFrameView::SetupRenderThrottling () {
352
- if (visibility_observer_)
353
- return ;
354
-
355
- Element* target_element = GetFrame ().DeprecatedLocalOwner ();
356
- if (!target_element)
357
- return ;
358
-
359
- visibility_observer_ = IntersectionObserver::Create (
360
- {}, {IntersectionObserver::kMinimumThreshold },
361
- &target_element->GetDocument (),
362
- WTF::BindRepeating (&RemoteFrameView::OnViewportIntersectionChanged,
363
- WrapWeakPersistent (this )));
364
- visibility_observer_->observe (target_element);
365
- }
366
-
367
329
void RemoteFrameView::UpdateRenderThrottlingStatus (bool hidden,
368
330
bool subtree_throttled) {
369
331
TRACE_EVENT0 (" blink" , " RemoteFrameView::UpdateRenderThrottlingStatus" );
0 commit comments