Incorrect background when increasing an OOPIF's width/height. |
|||||
Issue descriptionWith --site-per-process: (1) Go to http://csreis.github.io/cross-site-iframe.html (2) Click "Go cross-site (simple page)" (3) In devtools, enter: document.querySelector("iframe").style="background-color: green; position: fixed; left: 0; top: 0; width: 100%; height: 100%; " What is the expected output? The iframe is stretched to page bounds and filled with green color. What do you see instead? The iframe is stretched to a smaller area in upper left, with strange artifacts around it. I discovered this while debugging fullscreening an <iframe> element for an OOPIF, and it turned out that the problem is more generic (for fullscreen, it was triggered by applying UA styles in fullscreen.css). Note that this only happens on Linux and Windows (I've tried Linux dev 53.0.2763.0 and Windows canary 53.0.2764.0). Mac canary 53.0.2764.0 works fine. See screenshots of correct behavior (Mac) and incorrect behavior (Windows). Ken or Lucas - any ideas on what could be happening?
,
Jul 12 2016
I've been playing around with a test page for this, so the simplest repro is: run chrome with --site-per-process, go to http://alexmos17.github.io/tests/bg-frame.html, click "change width", click "change background". (The order of the two clicks doesn't matter, both lead to the bug). I still don't have a good lead on this, but I've traced each renderer's output using Frame Viewer in chrome://tracing, and outputs from both renderers appear correct (i.e., the snapshots that I see for cc::LayerTreeHostImpl): the main frame renderer has the green background for the iframe (with correct new width) as well as the two buttons, and the subframe renderer has the transparent text. So I'd guess that the bug here has something to do with how the two surfaces are composited following the resize and background change.
,
Jul 12 2016
The area outside the green is essentially garbage because no compositor is drawing to it. It's the parent compositor that's supposed to be drawing the green? Either it things the surface contents are actually opaque in that region, or it's clipping the surface contents but not realizing it.
,
Jul 12 2016
If I do "layer->setOpaque(false); layer->SetContentsOpaqueIsFixed(true);" (after making layer a cc_blink::WebLayerImpl) in ChildFrameCompositingHelper::OnSetSurface then the page seems to work. So for some reason the parent compositor thinks the child is opaque, even though it shouldn't be. Must the parent compositor always assume that the contents of the iframe could be transparent, or should there be some way to hint either way?
,
Jul 13 2016
Yes, it's the parent's compositor that's supposed to be drawing the green, since the background color is set on the iframe element. There must be something that changes in the parent compositor to make it think the layer becomes opaque on resize. I think jbauman@'s suggested fix in #4 is correct, but I'll try to poke at this today to figure out why it only happens on resize.
,
Jul 13 2016
Here's an overview of the problem: For rendering OOPIFs, we use a WebLayer created in content, which gets set here: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp?rcl=1468423091&l=547. When setting the background color on the <iframe> element, the CSS style in the LayoutIFrame changes, and it eventually triggers https://cs.chromium.org/chromium/src/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp?rcl=1468408847&l=328. Since we now have a background in the CSS style for the LayoutObject (the LayoutIFrame in this case) LayoutBox::backgroundIsKnownToBeOpaqueInRect, starts returning true (before it got short-circuited since hasAlpha was false -- the background was transparent). This will then change the opacity of the content layer: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp?rcl=1468423091&l=1049.
,
Jul 13 2016
It's not obvious to me why blink tries to change the opacity on the platform layer, and going through the history doesn't help much. This code has been there for a very long time. Overall, I think jbauman@'s suggestion in #4 should work correctly, and I'll put up a patch with it tomorrow, unless anyone else has a better idea.
,
Jul 13 2016
Also to add: There's no resize needed to trigger this. Just a background-color on the iframe, and make it big enough, since it needs to be bigger than the layer borders.
,
Jul 13 2016
Thanks John and Lucas for diagnosing this, this makes much more sense. Lucas - I'll assign to you for now if you don't mind. The suggestion in #4 makes sense, I think. It doesn't seem like that layer should ever be opaque, is there? I also noticed that this problem doesn't seem to occur with <webview>. Is that doing something different with surface setup? Just mentioning this as another thing that might be worth checking.
,
Jul 14 2016
Re#9: It does affect <webview> if you apply the background-color to the object inside the shadow dom. If you apply the background-color to the custom element, then it ends up working (I haven't debugged, but my guess is that we have 2 different LayoutObjects, and in this case the parent always draws, since the object tag is always transparent).
,
Jul 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/04c6bd6016500a2396142e07d09c582745350827 commit 04c6bd6016500a2396142e07d09c582745350827 Author: lfg <lfg@chromium.org> Date: Wed Jul 20 17:02:52 2016 Fix incorrect rendering of background color in out-of-process iframes. BUG= 619197 Review-Url: https://codereview.chromium.org/2144353002 Cr-Commit-Position: refs/heads/master@{#406591} [modify] https://crrev.com/04c6bd6016500a2396142e07d09c582745350827/content/renderer/child_frame_compositing_helper.cc
,
Jul 20 2016
|
|||||
►
Sign in to add a comment |
|||||
Comment 1 by alex...@chromium.org
, Jun 22 201628.7 KB
28.7 KB View Download