Commit 641c8ccb authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

Calculate and save RemoteFrame compositing rect during lifecycle

RemoteFrameView::GetCompositingRect uses geometry mapping code that
relies on a clean layout state; but it is called from
RenderFrameProxy::SynchronizeVisualProperties, which is called from
many places, including in response to IPCs.

With this change, the compositing rect is calculated and cached
during each lifecycle update, and GetCompositingRect returns the
cached value.

BUG=1033746

Change-Id: I29c50c954829ef856d667b1948e1ea840904004a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2028863
Commit-Queue: Stefan Zager <szager@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743459}
parent 988dd01e
...@@ -682,21 +682,15 @@ void RenderFrameProxy::FrameRectsChanged( ...@@ -682,21 +682,15 @@ void RenderFrameProxy::FrameRectsChanged(
void RenderFrameProxy::UpdateRemoteViewportIntersection( void RenderFrameProxy::UpdateRemoteViewportIntersection(
const blink::ViewportIntersectionState& intersection_state) { const blink::ViewportIntersectionState& intersection_state) {
DCHECK(ancestor_render_widget_); DCHECK(ancestor_render_widget_);
// TODO(szager): compositor_viewport is propagated twice, via
// If the remote viewport intersection has changed, then we should check if // ViewportIntersectionState and also via FrameVisualProperties. It should
// the compositing rect has also changed: if it has, then we should update the // only go through FrameVisualProperties.
// visible properties. if (pending_visual_properties_.compositor_viewport !=
// TODO(wjmaclean): Maybe we should always call SynchronizeVisualProperties() gfx::Rect(intersection_state.compositor_visible_rect)) {
// here? If nothing has changed, it will early out, and it avoids duplicate
// checks here.
blink::ViewportIntersectionState new_state(intersection_state);
new_state.compositor_visible_rect = web_frame_->GetCompositingRect();
if (new_state.compositor_visible_rect !=
blink::WebRect(pending_visual_properties_.compositor_viewport)) {
SynchronizeVisualProperties(); SynchronizeVisualProperties();
} }
Send(new FrameHostMsg_UpdateViewportIntersection(routing_id_,
Send(new FrameHostMsg_UpdateViewportIntersection(routing_id_, new_state)); intersection_state));
} }
void RenderFrameProxy::DidChangeOpener(blink::WebFrame* opener) { void RenderFrameProxy::DidChangeOpener(blink::WebFrame* opener) {
......
...@@ -372,6 +372,29 @@ void LocalFrameView::ForAllThrottledLocalFrameViews(const Function& function) { ...@@ -372,6 +372,29 @@ void LocalFrameView::ForAllThrottledLocalFrameViews(const Function& function) {
} }
} }
template <typename Function>
void LocalFrameView::ForAllRemoteFrameViews(const Function& function) {
for (Frame* child = frame_->Tree().FirstChild(); child;
child = child->Tree().NextSibling()) {
if (child->IsLocalFrame()) {
To<LocalFrame>(child)->View()->ForAllRemoteFrameViews(function);
} else {
DCHECK(child->IsRemoteFrame());
if (RemoteFrameView* view = To<RemoteFrame>(child)->View())
function(*view);
}
}
if (Document* document = frame_->GetDocument()) {
for (PortalContents* portal :
DocumentPortals::From(*document).GetPortals()) {
if (RemoteFrame* frame = portal->GetFrame()) {
if (RemoteFrameView* view = frame->View())
function(*view);
}
}
}
}
void LocalFrameView::Dispose() { void LocalFrameView::Dispose() {
CHECK(!IsInPerformLayout()); CHECK(!IsInPerformLayout());
...@@ -2330,6 +2353,9 @@ void LocalFrameView::UpdateLifecyclePhasesInternal( ...@@ -2330,6 +2353,9 @@ void LocalFrameView::UpdateLifecyclePhasesInternal(
DCHECK(ShouldThrottleRendering() || DCHECK(ShouldThrottleRendering() ||
frame_->GetDocument()->IsCapturingLayout() || frame_->GetDocument()->IsCapturingLayout() ||
Lifecycle().GetState() == DocumentLifecycle::kPaintClean); Lifecycle().GetState() == DocumentLifecycle::kPaintClean);
ForAllRemoteFrameViews(
[](RemoteFrameView& frame_view) { frame_view.UpdateCompositingRect(); });
} }
bool LocalFrameView::RunStyleAndLayoutLifecyclePhases( bool LocalFrameView::RunStyleAndLayoutLifecyclePhases(
......
...@@ -818,6 +818,9 @@ class CORE_EXPORT LocalFrameView final ...@@ -818,6 +818,9 @@ class CORE_EXPORT LocalFrameView final
template <typename Function> template <typename Function>
void ForAllThrottledLocalFrameViews(const Function&); void ForAllThrottledLocalFrameViews(const Function&);
template <typename Function>
void ForAllRemoteFrameViews(const Function&);
bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override; bool UpdateViewportIntersectionsForSubtree(unsigned parent_flags) override;
void DeliverSynchronousIntersectionObservations(); void DeliverSynchronousIntersectionObservations();
......
...@@ -90,10 +90,11 @@ bool RemoteFrameView::UpdateViewportIntersectionsForSubtree( ...@@ -90,10 +90,11 @@ bool RemoteFrameView::UpdateViewportIntersectionsForSubtree(
void RemoteFrameView::SetViewportIntersection( void RemoteFrameView::SetViewportIntersection(
const ViewportIntersectionState& intersection_state) { const ViewportIntersectionState& intersection_state) {
if (intersection_state != last_intersection_state_) { ViewportIntersectionState new_state(intersection_state);
last_intersection_state_ = intersection_state; new_state.compositor_visible_rect = WebRect(compositing_rect_);
remote_frame_->Client()->UpdateRemoteViewportIntersection( if (new_state != last_intersection_state_) {
intersection_state); last_intersection_state_ = new_state;
remote_frame_->Client()->UpdateRemoteViewportIntersection(new_state);
} }
} }
...@@ -107,10 +108,11 @@ void RemoteFrameView::SetNeedsOcclusionTracking(bool needs_tracking) { ...@@ -107,10 +108,11 @@ void RemoteFrameView::SetNeedsOcclusionTracking(bool needs_tracking) {
} }
} }
IntRect RemoteFrameView::GetCompositingRect() { void RemoteFrameView::UpdateCompositingRect() {
compositing_rect_ = IntRect();
LocalFrameView* local_root_view = ParentLocalRootFrameView(); LocalFrameView* local_root_view = ParentLocalRootFrameView();
if (!local_root_view || !remote_frame_->OwnerLayoutObject()) if (!local_root_view || !remote_frame_->OwnerLayoutObject())
return IntRect(); return;
// For main frames we constrain the rect that gets painted to the viewport. // For main frames we constrain the rect that gets painted to the viewport.
// If the local frame root is an OOPIF itself, then we use the root's // If the local frame root is an OOPIF itself, then we use the root's
...@@ -129,7 +131,7 @@ IntRect RemoteFrameView::GetCompositingRect() { ...@@ -129,7 +131,7 @@ IntRect RemoteFrameView::GetCompositingRect() {
local_root_view->GetLayoutView(), local_root_view->GetLayoutView(),
PhysicalRect(PhysicalOffset(), PhysicalSize(viewport_size)), PhysicalRect(PhysicalOffset(), PhysicalSize(viewport_size)),
kTraverseDocumentBoundaries); kTraverseDocumentBoundaries);
IntRect compositing_rect = EnclosingIntRect(viewport_rect); compositing_rect_ = EnclosingIntRect(viewport_rect);
IntSize frame_size = Size(); IntSize frame_size = Size();
// Iframes that fit within the window viewport get fully rastered. For // Iframes that fit within the window viewport get fully rastered. For
...@@ -140,17 +142,15 @@ IntRect RemoteFrameView::GetCompositingRect() { ...@@ -140,17 +142,15 @@ IntRect RemoteFrameView::GetCompositingRect() {
// it seems to make guttering rare with slow to medium speed wheel scrolling. // it seems to make guttering rare with slow to medium speed wheel scrolling.
// Can we collect UMA data to estimate how much extra rastering this causes, // Can we collect UMA data to estimate how much extra rastering this causes,
// and possibly how common guttering is? // and possibly how common guttering is?
compositing_rect.InflateX(ceilf(viewport_rect.Width() * 0.15f)); compositing_rect_.InflateX(ceilf(viewport_rect.Width() * 0.15f));
compositing_rect.InflateY(ceilf(viewport_rect.Height() * 0.15f)); compositing_rect_.InflateY(ceilf(viewport_rect.Height() * 0.15f));
compositing_rect.SetWidth( compositing_rect_.SetWidth(
std::min(frame_size.Width(), compositing_rect.Width())); std::min(frame_size.Width(), compositing_rect_.Width()));
compositing_rect.SetHeight( compositing_rect_.SetHeight(
std::min(frame_size.Height(), compositing_rect.Height())); std::min(frame_size.Height(), compositing_rect_.Height()));
IntPoint compositing_rect_location = compositing_rect.Location(); IntPoint compositing_rect_location = compositing_rect_.Location();
compositing_rect_location.ClampNegativeToZero(); compositing_rect_location.ClampNegativeToZero();
compositing_rect.SetLocation(compositing_rect_location); compositing_rect_.SetLocation(compositing_rect_location);
return compositing_rect;
} }
void RemoteFrameView::Dispose() { void RemoteFrameView::Dispose() {
......
...@@ -70,8 +70,10 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>, ...@@ -70,8 +70,10 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>,
// Compute the interest rect of this frame in its unscrolled space. This may // Compute the interest rect of this frame in its unscrolled space. This may
// be used by the OOPIF's compositor to limit the amount of rastered tiles, // be used by the OOPIF's compositor to limit the amount of rastered tiles,
// and reduce the number of paint-ops generated. // and reduce the number of paint-ops generated. UpdateCompositingRect must be
IntRect GetCompositingRect(); // called before the parent frame commits a compositor frame.
void UpdateCompositingRect();
IntRect GetCompositingRect() const { return compositing_rect_; }
uint32_t Print(const IntRect&, cc::PaintCanvas*) const; uint32_t Print(const IntRect&, cc::PaintCanvas*) const;
uint32_t CapturePaintPreview(const IntRect&, cc::PaintCanvas*) const; uint32_t CapturePaintPreview(const IntRect&, cc::PaintCanvas*) const;
...@@ -98,6 +100,7 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>, ...@@ -98,6 +100,7 @@ class RemoteFrameView final : public GarbageCollected<RemoteFrameView>,
// details. // details.
Member<RemoteFrame> remote_frame_; Member<RemoteFrame> remote_frame_;
ViewportIntersectionState last_intersection_state_; ViewportIntersectionState last_intersection_state_;
IntRect compositing_rect_;
IntrinsicSizingInfo intrinsic_sizing_info_; IntrinsicSizingInfo intrinsic_sizing_info_;
bool has_intrinsic_sizing_info_ = false; bool has_intrinsic_sizing_info_ = false;
......
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