diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-31 15:50:41 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:35:23 +0000 |
commit | 7b2ffa587235a47d4094787d72f38102089f402a (patch) | |
tree | 30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/third_party/blink/renderer/core/frame/frame_view.cc | |
parent | d94af01c90575348c4e81a418257f254b6f8d225 (diff) | |
download | qtwebengine-chromium-7b2ffa587235a47d4094787d72f38102089f402a.tar.gz |
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647
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 | 152 |
1 files changed, 152 insertions, 0 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 new file mode 100644 index 00000000000..0ae6f08f2b4 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/frame/frame_view.cc @@ -0,0 +1,152 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/frame/frame_view.h" + +#include "third_party/blink/renderer/core/frame/frame_client.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/remote_frame.h" +#include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/core/intersection_observer/intersection_geometry.h" +#include "third_party/blink/renderer/core/intersection_observer/intersection_observer.h" +#include "third_party/blink/renderer/core/layout/layout_embedded_content.h" + +namespace blink { + +Frame& FrameView::GetFrame() const { + if (const LocalFrameView* lfv = DynamicTo<LocalFrameView>(this)) + return lfv->GetFrame(); + return DynamicTo<RemoteFrameView>(this)->GetFrame(); +} + +bool FrameView::CanThrottleRenderingForPropagation() const { + if (CanThrottleRendering()) + return true; + if (!RuntimeEnabledFeatures::RenderingPipelineThrottlingEnabled()) + return false; + LocalFrame* parent_frame = DynamicTo<LocalFrame>(GetFrame().Tree().Parent()); + if (!parent_frame) + return false; + Frame& frame = GetFrame(); + LayoutEmbeddedContent* owner = frame.OwnerLayoutObject(); + return !owner && frame.IsCrossOriginSubframe(); +} + +void FrameView::UpdateViewportIntersection(unsigned flags, + bool needs_occlusion_tracking) { + if (!(flags & IntersectionObservation::kImplicitRootObserversNeedUpdate)) + return; + // This should only run in child frames. + Frame& frame = GetFrame(); + HTMLFrameOwnerElement* owner_element = frame.DeprecatedLocalOwner(); + if (!owner_element) + return; + Document& owner_document = owner_element->GetDocument(); + IntRect viewport_intersection; + DocumentLifecycle::LifecycleState parent_lifecycle_state = + owner_document.Lifecycle().GetState(); + FrameOcclusionState occlusion_state = + owner_document.GetFrame()->GetOcclusionState(); + bool should_compute_occlusion = + needs_occlusion_tracking && + occlusion_state == FrameOcclusionState::kGuaranteedNotOccluded && + parent_lifecycle_state >= DocumentLifecycle::kPrePaintClean && + RuntimeEnabledFeatures::IntersectionObserverV2Enabled(); + + LayoutEmbeddedContent* owner_layout_object = + owner_element->GetLayoutEmbeddedContent(); + if (!owner_layout_object || owner_layout_object->ContentSize().IsEmpty()) { + // The frame is detached from layout, not visible, or zero size; leave + // viewport_intersection empty, and signal the frame as occluded if + // necessary. + occlusion_state = FrameOcclusionState::kPossiblyOccluded; + } else if (parent_lifecycle_state >= DocumentLifecycle::kLayoutClean) { + unsigned geometry_flags = + IntersectionGeometry::kShouldUseReplacedContentRect; + if (should_compute_occlusion) + geometry_flags |= IntersectionGeometry::kShouldComputeVisibility; + + IntersectionGeometry geometry(nullptr, *owner_element, {}, + {IntersectionObserver::kMinimumThreshold}, + geometry_flags); + // geometry.IntersectionRect() is in absolute coordinates of the owning + // document. Map it down to absolute coordinates in the child document. + PhysicalRect intersection_rect = owner_layout_object->AncestorToLocalRect( + nullptr, geometry.IntersectionRect()); + // Map from the box coordinates of the owner to the inner frame. + intersection_rect.Move(-owner_layout_object->PhysicalContentBoxOffset()); + // Don't let EnclosingIntRect turn an empty rect into a non-empty one. + if (intersection_rect.IsEmpty()) { + viewport_intersection = + IntRect(FlooredIntPoint(intersection_rect.offset), IntSize()); + } else { + viewport_intersection = EnclosingIntRect(intersection_rect); + } + if (should_compute_occlusion && !geometry.IsVisible()) + occlusion_state = FrameOcclusionState::kPossiblyOccluded; + } else if (occlusion_state == FrameOcclusionState::kGuaranteedNotOccluded) { + // If the parent LocalFrameView is throttled and out-of-date, then we can't + // get any useful information. + occlusion_state = FrameOcclusionState::kUnknown; + } + + SetViewportIntersection(viewport_intersection, occlusion_state); + + UpdateFrameVisibility(!viewport_intersection.IsEmpty()); + + // 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() && + !FrameRect().IsEmpty() && owner_layout_object; + bool subtree_throttled = false; + Frame* parent_frame = GetFrame().Tree().Parent(); + if (parent_frame && parent_frame->View()) { + subtree_throttled = + parent_frame->View()->CanThrottleRenderingForPropagation(); + } + UpdateRenderThrottlingStatus(hidden_for_throttling, subtree_throttled); +} + +void FrameView::UpdateFrameVisibility(bool intersects_viewport) { + blink::mojom::FrameVisibility frame_visibility; + if (LifecycleUpdatesThrottled()) + return; + if (IsVisible()) { + frame_visibility = + intersects_viewport + ? blink::mojom::FrameVisibility::kRenderedInViewport + : blink::mojom::FrameVisibility::kRenderedOutOfViewport; + } else { + frame_visibility = blink::mojom::FrameVisibility::kNotRendered; + } + if (frame_visibility != frame_visibility_) { + frame_visibility_ = frame_visibility; + if (FrameClient* client = GetFrame().Client()) + client->VisibilityChanged(frame_visibility); + } +} + +void FrameView::UpdateRenderThrottlingStatus(bool hidden_for_throttling, + bool subtree_throttled, + bool recurse) { + bool was_throttled = CanThrottleRendering(); + hidden_for_throttling_ = hidden_for_throttling; + subtree_throttled_ = subtree_throttled; + bool throttling_did_change = (was_throttled != CanThrottleRendering()); + if (throttling_did_change) + RenderThrottlingStatusChanged(); + if (recurse) { + for (Frame* child = GetFrame().Tree().FirstChild(); child; + child = child->Tree().NextSibling()) { + if (FrameView* child_view = child->View()) { + child_view->UpdateRenderThrottlingStatus( + child_view->IsHiddenForThrottling(), + child_view->IsAttached() && CanThrottleRenderingForPropagation(), + true); + } + } + } +} + +} // namespace blink |