diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-16 11:45:35 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-07-17 08:59:23 +0000 |
commit | 552906b0f222c5d5dd11b9fd73829d510980461a (patch) | |
tree | 3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/third_party/blink/renderer/core/frame/frame_view.cc | |
parent | 1b05827804eaf047779b597718c03e7d38344261 (diff) | |
download | qtwebengine-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.cc | 101 |
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 |