summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/frame/frame_view.cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/third_party/blink/renderer/core/frame/frame_view.cc
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/frame/frame_view.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/frame/frame_view.cc101
1 files changed, 81 insertions, 20 deletions
diff --git a/chromium/third_party/blink/renderer/core/frame/frame_view.cc b/chromium/third_party/blink/renderer/core/frame/frame_view.cc
index b7eae97648b..e52d60795fb 100644
--- a/chromium/third_party/blink/renderer/core/frame/frame_view.cc
+++ b/chromium/third_party/blink/renderer/core/frame/frame_view.cc
@@ -30,7 +30,7 @@ bool FrameView::CanThrottleRenderingForPropagation() const {
return false;
Frame& frame = GetFrame();
LayoutEmbeddedContent* owner = frame.OwnerLayoutObject();
- return !owner && frame.IsCrossOriginSubframe();
+ return !owner && frame.IsCrossOriginToMainFrame();
}
bool FrameView::DisplayLockedInParentFrame() {
@@ -42,18 +42,21 @@ bool FrameView::DisplayLockedInParentFrame() {
return owner && DisplayLockUtilities::NearestLockedInclusiveAncestor(*owner);
}
-void FrameView::UpdateViewportIntersection(unsigned flags,
+bool FrameView::UpdateViewportIntersection(unsigned flags,
bool needs_occlusion_tracking) {
+ bool can_skip_sticky_frame_tracking =
+ flags & IntersectionObservation::kCanSkipStickyFrameTracking;
+
if (!(flags & IntersectionObservation::kImplicitRootObserversNeedUpdate))
- return;
+ return can_skip_sticky_frame_tracking;
// This should only run in child frames.
Frame& frame = GetFrame();
HTMLFrameOwnerElement* owner_element = frame.DeprecatedLocalOwner();
if (!owner_element)
- return;
+ return can_skip_sticky_frame_tracking;
Document& owner_document = owner_element->GetDocument();
IntPoint viewport_offset;
- IntRect viewport_intersection;
+ IntRect viewport_intersection, mainframe_document_intersection;
DocumentLifecycle::LifecycleState parent_lifecycle_state =
owner_document.Lifecycle().GetState();
FrameOcclusionState occlusion_state =
@@ -103,23 +106,52 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
PhysicalOffset content_box_offset =
owner_layout_object->PhysicalContentBoxOffset();
- if (NeedsViewportOffset()) {
- viewport_offset =
- RoundedIntPoint(owner_layout_object->LocalToAbsolutePoint(
- content_box_offset,
- kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset));
+ if (NeedsViewportOffset() || !can_skip_sticky_frame_tracking) {
+ viewport_offset = -RoundedIntPoint(
+ owner_layout_object->AbsoluteToLocalPoint(
+ PhysicalOffset(),
+ kTraverseDocumentBoundaries | kApplyRemoteRootFrameOffset) -
+ content_box_offset);
+ if (!can_skip_sticky_frame_tracking) {
+ // If the frame is small, skip tracking this frame and its subframes.
+ if (frame.GetMainFrameViewportSize().IsEmpty() ||
+ !StickyFrameTracker::IsLarge(
+ frame.GetMainFrameViewportSize(),
+ new_rect_in_parent.PixelSnappedSize())) {
+ can_skip_sticky_frame_tracking = true;
+ }
+ // If the frame is a large sticky ad, record a use counter and skip
+ // tracking its subframes; otherwise continue tracking its subframes.
+ else if (frame.IsAdSubframe() &&
+ GetStickyFrameTracker()->UpdateStickyStatus(
+ frame.GetMainFrameScrollOffset(), viewport_offset)) {
+ UseCounter::Count(owner_element->GetDocument(),
+ WebFeature::kLargeStickyAd);
+ can_skip_sticky_frame_tracking = true;
+ }
+ }
}
+ // Generate matrix to transform from the space of the containing document
+ // to the space of the iframe's contents.
+ TransformState parent_frame_to_iframe_content_transform(
+ TransformState::kUnapplyInverseTransformDirection);
+ // First transform to box coordinates of the iframe element...
+ owner_layout_object->MapAncestorToLocal(
+ nullptr, parent_frame_to_iframe_content_transform, 0);
+ // ... then apply content_box_offset to translate to the coordinate of the
+ // child frame.
+ parent_frame_to_iframe_content_transform.Move(
+ owner_layout_object->PhysicalContentBoxOffset());
+ TransformationMatrix matrix =
+ parent_frame_to_iframe_content_transform.AccumulatedTransform()
+ .Inverse();
if (geometry.IsIntersecting()) {
- // geometry.IntersectionRect() is in the coordinate system of the document
- // containing the iframe. First map it down to border-box coordinates for
- // the iframe, then apply content_box_offset to translate to the
- // coordinates of the child frame.
- PhysicalRect intersection_rect = owner_layout_object->AncestorToLocalRect(
- nullptr, geometry.IntersectionRect());
- intersection_rect.Move(-content_box_offset);
-
- // Don't let EnclosingIntRect turn an empty rect into a non-empty one.
+ PhysicalRect intersection_rect = PhysicalRect::EnclosingRect(
+ matrix.ProjectQuad(FloatRect(geometry.IntersectionRect()))
+ .BoundingBox());
+
+ // Don't let EnclosingRect turn an empty rect into a non-empty one.
if (intersection_rect.IsEmpty()) {
viewport_intersection =
IntRect(FlooredIntPoint(intersection_rect.offset), IntSize());
@@ -127,6 +159,21 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
viewport_intersection = EnclosingIntRect(intersection_rect);
}
}
+
+ PhysicalRect mainframe_intersection_rect;
+ if (!geometry.UnclippedIntersectionRect().IsEmpty()) {
+ mainframe_intersection_rect = PhysicalRect::EnclosingRect(
+ matrix.ProjectQuad(FloatRect(geometry.UnclippedIntersectionRect()))
+ .BoundingBox());
+
+ if (mainframe_intersection_rect.IsEmpty()) {
+ mainframe_document_intersection = IntRect(
+ FlooredIntPoint(mainframe_intersection_rect.offset), IntSize());
+ } else {
+ mainframe_document_intersection =
+ EnclosingIntRect(mainframe_intersection_rect);
+ }
+ }
} else if (occlusion_state == FrameOcclusionState::kGuaranteedNotOccluded) {
// If the parent LocalFrameView is throttled and out-of-date, then we can't
// get any useful information.
@@ -134,10 +181,17 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
}
SetViewportIntersection(
- {viewport_offset, viewport_intersection, WebRect(), occlusion_state});
+ {viewport_offset, viewport_intersection, mainframe_document_intersection,
+ WebRect(), occlusion_state, frame.GetMainFrameViewportSize(),
+ frame.GetMainFrameScrollOffset(), can_skip_sticky_frame_tracking});
UpdateFrameVisibility(!viewport_intersection.IsEmpty());
+ if (ShouldReportMainFrameIntersection()) {
+ GetFrame().Client()->OnMainFrameDocumentIntersectionChanged(
+ mainframe_document_intersection);
+ }
+
// We don't throttle 0x0 or display:none iframes, because in practice they are
// sometimes used to drive UI logic.
bool hidden_for_throttling = viewport_intersection.IsEmpty() &&
@@ -149,6 +203,7 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
parent_frame->View()->CanThrottleRenderingForPropagation();
}
UpdateRenderThrottlingStatus(hidden_for_throttling, subtree_throttled);
+ return can_skip_sticky_frame_tracking;
}
void FrameView::UpdateFrameVisibility(bool intersects_viewport) {
@@ -204,4 +259,10 @@ bool FrameView::RectInParentIsStable(
return parent->RectInParentIsStable(event_timestamp);
}
+StickyFrameTracker* FrameView::GetStickyFrameTracker() {
+ if (!sticky_frame_tracker_)
+ sticky_frame_tracker_ = std::make_unique<StickyFrameTracker>();
+ return sticky_frame_tracker_.get();
+}
+
} // namespace blink