Commit 93b15c2c authored by Vladimir Levin's avatar Vladimir Levin Committed by Commit Bot

[RLS] Ensure that iframes graphics layers are attached.

This patch ensures that if we remove a child frame's graphics layer from
its parent, that we reattach its (possibly new) root graphics layer back
to the parent it had before.

The parent does not change during this, because we're in a stack
processing the child frame, and the parent would reference the parent
frame that is currently paused.

This mimics pre-RLS code path where the child frame always had a parent
accessible directly from the compositor (ie root_content_layer_), except
here we save off whatever we were attached to already.

R=chrishtr@chromium.org, skobes@chromium.org, pdr@chromium.org

Bug: 815121
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I9e63d2d513df24eaa13a30ee36582b5c807f4aff
Reviewed-on: https://chromium-review.googlesource.com/946566
Commit-Queue: vmpstr <vmpstr@chromium.org>
Reviewed-by: default avatarSteve Kobes <skobes@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540692}
parent 3782630e
<!doctype HTML>
<style>
#frame {
width: 200px;
height: 200px;
overflow-y: scroll;
}
#parent {
width: 100px;
height: 500px;
background-color: lightblue;
}
#child {
width: 50px;
height: 50px;
background-color: blue;
will-change: transform;
}
</style>
<div id="frame">
<div id="parent">
<div id="child"></div>
</div>
</div>
<!doctype HTML>
<script>
if (window.testRunner) {
testRunner.waitUntilDone();
window.onmessage = function() {
testRunner.notifyDone();
};
}
</script>
<style>
iframe {
width: 200px;
height: 200px;
}
</style>
<iframe marginwidth=0 marginheight=0 frameborder=0 src="resources/iframe-graphics-tree-changes-parents-does-not-frame.html"></iframe>
<!doctype HTML>
<style>
#parent {
width: 100px;
height: 100px;
background-color: lightblue;
}
#child {
width: 50px;
height: 50px;
background-color: blue;
will-change: transform;
}
</style>
<div id="parent">
<div id="child"></div>
</div>
<script src="../../resources/run-after-layout-and-paint.js"></script>
<script>
runAfterLayoutAndPaint(function() {
document.getElementById("parent").style = "height: 500px;";
parent.postMessage('done', '*');
});
</script>
...@@ -388,16 +388,18 @@ static void ForceRecomputeVisualRectsIncludingNonCompositingDescendants( ...@@ -388,16 +388,18 @@ static void ForceRecomputeVisualRectsIncludingNonCompositingDescendants(
} }
} }
GraphicsLayer* PaintLayerCompositor::ParentForContentLayers() const { GraphicsLayer* PaintLayerCompositor::ParentForContentLayers(
GraphicsLayer* child_frame_parent_candidate) const {
if (root_content_layer_) if (root_content_layer_)
return root_content_layer_.get(); return root_content_layer_.get();
DCHECK(RuntimeEnabledFeatures::RootLayerScrollingEnabled()); DCHECK(RuntimeEnabledFeatures::RootLayerScrollingEnabled());
// Iframe content layers will be connected by the parent frame using // Iframe content layers were connected by the parent frame using
// attachFrameContentLayersToIframeLayer. // AttachFrameContentLayersToIframeLayer. Return whatever candidate was given
// to us as the child frame parent.
if (!IsMainFrame()) if (!IsMainFrame())
return nullptr; return child_frame_parent_candidate;
// If this is a popup, don't hook into the VisualViewport layers. // If this is a popup, don't hook into the VisualViewport layers.
if (!layout_view_.GetDocument() if (!layout_view_.GetDocument()
...@@ -495,6 +497,24 @@ void PaintLayerCompositor::UpdateIfNeeded( ...@@ -495,6 +497,24 @@ void PaintLayerCompositor::UpdateIfNeeded(
} }
} }
GraphicsLayer* current_parent = nullptr;
if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
// Save off our current parent. We need this in subframes, because our
// parent attached us to itself via AttachFrameContentLayersToIframeLayer().
// However, if we're about to update our layer structure in
// GraphicsLayerUpdater, we will sometimes remove our root graphics layer
// from its parent. If there are no further tree updates, this means that
// our root graphics layer will not be attached to anything. Below, we would
// normally get the ParentForContentLayer to fix up this situation. However,
// in RLS non-main frames don't have this parent. So, instead use this
// saved-off parent.
if (!IsMainFrame() && update_root->GetCompositedLayerMapping()) {
current_parent = update_root->GetCompositedLayerMapping()
->ChildForSuperlayers()
->Parent();
}
}
GraphicsLayerUpdater updater; GraphicsLayerUpdater updater;
updater.Update(*update_root, layers_needing_paint_invalidation); updater.Update(*update_root, layers_needing_paint_invalidation);
...@@ -516,8 +536,10 @@ void PaintLayerCompositor::UpdateIfNeeded( ...@@ -516,8 +536,10 @@ void PaintLayerCompositor::UpdateIfNeeded(
if (!child_list.IsEmpty()) { if (!child_list.IsEmpty()) {
CHECK(compositing_); CHECK(compositing_);
if (GraphicsLayer* content_parent = ParentForContentLayers()) if (GraphicsLayer* content_parent =
ParentForContentLayers(current_parent)) {
content_parent->SetChildren(child_list); content_parent->SetChildren(child_list);
}
} }
ApplyOverlayFullscreenVideoAdjustmentIfNeeded(); ApplyOverlayFullscreenVideoAdjustmentIfNeeded();
......
...@@ -260,7 +260,8 @@ class CORE_EXPORT PaintLayerCompositor final : public GraphicsLayerClient { ...@@ -260,7 +260,8 @@ class CORE_EXPORT PaintLayerCompositor final : public GraphicsLayerClient {
bool IsMainFrame() const; bool IsMainFrame() const;
VisualViewport& GetVisualViewport() const; VisualViewport& GetVisualViewport() const;
GraphicsLayer* ParentForContentLayers() const; GraphicsLayer* ParentForContentLayers(
GraphicsLayer* child_frame_parent_candidate = nullptr) const;
LayoutView& layout_view_; LayoutView& layout_view_;
......
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