Commit 349207a3 authored by Daniel Libby's avatar Daniel Libby Committed by Commit Bot

Repaint remote frames when new layer is set

Remote frames in CAP can end up incorrectly sized 0,0 on initial render
which makes the iframes content not show up. The initial
RenderFrameProxy::SynchronizeVisualProperties can come in before the
RemoteFrameView has updated its compositing rect, which leaves the
created SurfaceLayer with a 0,0 size.

The RemoteFrameView compositing rect is only updated after Paint in the
document lifecycle (see LocalFrameView::UpdateLifecyclePhasesInternal)
and RenderFrameProxy::SynchronizeVisualProperties is called during
intersection observer steps (also after paint). Since the synchronized
properties have changed, a new SurfaceLayer is created at the correct
size. When setting this SurfaceLayer on RemoteFrame, the existing
invalidation of SetNeedsCompositingUpdate is not sufficient in CAP to
have a new frame generated with the updated layer.

In pre-CAP, this is not an issue - the oopif content appears with the
first frame produced due to the ContentsLayer size update via
CompositedLayerMapping::UpdateContentsRect in the compositing phase of
the document lifecycle.

To fix this for CAP, we add a SetNeedsPaint on the frame owner
element's paint layer, and schedule another frame to ensure this gets
picked up, since these updates typically will come in outside of the
document lifecycle.

R=pdr@chromium.org

Bug: 1078255
Change-Id: I7333a79b3cfbca303fe388bea6d7df176b0e1f41
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2227897Reviewed-by: default avatarStefan Zager <szager@chromium.org>
Commit-Queue: Daniel Libby <dlibby@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#774868}
parent d64d48c1
...@@ -688,9 +688,18 @@ cc::Layer* RenderFrameProxy::GetLayer() { ...@@ -688,9 +688,18 @@ cc::Layer* RenderFrameProxy::GetLayer() {
void RenderFrameProxy::SetLayer(scoped_refptr<cc::Layer> layer, void RenderFrameProxy::SetLayer(scoped_refptr<cc::Layer> layer,
bool prevent_contents_opaque_changes, bool prevent_contents_opaque_changes,
bool is_surface_layer) { bool is_surface_layer) {
// |ancestor_render_widget_| can be null if this is a proxy for a remote main
// frame, or a subframe of that proxy. However, we should not be setting a
// layer on such a proxy (the layer is used for embedding a child proxy).
DCHECK(ancestor_render_widget_);
if (web_frame()) { if (web_frame()) {
web_frame()->SetCcLayer(layer.get(), prevent_contents_opaque_changes, web_frame()->SetCcLayer(layer.get(), prevent_contents_opaque_changes,
is_surface_layer); is_surface_layer);
// Schedule an animation so that a new frame is produced with the updated
// layer, otherwise this local root's visible content may not be up to date.
ancestor_render_widget_->ScheduleAnimation();
} }
embedded_layer_ = std::move(layer); embedded_layer_ = std::move(layer);
} }
......
...@@ -729,8 +729,17 @@ void RemoteFrame::SetCcLayer(cc::Layer* cc_layer, ...@@ -729,8 +729,17 @@ void RemoteFrame::SetCcLayer(cc::Layer* cc_layer,
IsIgnoredForHitTest()); IsIgnoredForHitTest());
} }
} }
HTMLFrameOwnerElement* owner = To<HTMLFrameOwnerElement>(Owner());
To<HTMLFrameOwnerElement>(Owner())->SetNeedsCompositingUpdate(); owner->SetNeedsCompositingUpdate();
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// New layers for remote frames are controlled by Blink's embedder.
// To ensure the new surface is painted, we need to repaint the frame
// owner's PaintLayer.
LayoutBoxModelObject* layout_object = owner->GetLayoutBoxModelObject();
if (layout_object && layout_object->Layer())
layout_object->Layer()->SetNeedsRepaint();
}
} }
void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type, void RemoteFrame::AdvanceFocus(mojom::blink::FocusType type,
......
...@@ -35,8 +35,6 @@ compositing/overflow/scrolls-with-respect-to.html [ Skip ] ...@@ -35,8 +35,6 @@ compositing/overflow/scrolls-with-respect-to.html [ Skip ]
external/wpt/paint-timing/fcp-only/fcp-opacity.html [ Skip ] external/wpt/paint-timing/fcp-only/fcp-opacity.html [ Skip ]
external/wpt/paint-timing/fcp-only/fcp-pseudo-element-opacity.html [ Skip ] external/wpt/paint-timing/fcp-only/fcp-pseudo-element-opacity.html [ Skip ]
crbug.com/1090431 external/wpt/html/user-activation/message-event-activation-api-iframe-cross-origin.sub.tentative.html [ Timeout ]
# Can't rebaseline because the file path is too long. # Can't rebaseline because the file path is too long.
virtual/compositor_threaded_scrollbar_scrolling/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Skip ] virtual/compositor_threaded_scrollbar_scrolling/paint/invalidation/scroll/sticky/invalidate-after-composited-scroll-with-sticky.html [ Skip ]
......
<!doctype html>
<title>Test reference</title>
<iframe src="/images/green.png"></iframe>
<!doctype html>
<title>Rendering of iframe element with src attribute from another domain</title>
<link rel="match" href="cross-domain-iframe.sub-ref.html">
<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
<meta name="assert" content="Checks that iframe content is correctly rendered even if it is retrieved from a different domain.">
<iframe src="http://{{domains[www1]}}:{{ports[http][0]}}/images/green.png"></iframe>
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