Commit a2db5b9f authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

Reset squashing state when encountering composited iframe contents

Previously, <iframe> elements were always composited, and
CompositingLayerAssigner specifically disallows squashing them. Due
to a recent change (see bug), <iframe> elements are not always
composited; but we cannot squash layers across an iframe with
composited contents.

With this change, an iframe with composited contents will end the
current squashing context in the embedding document.

BUG=1095935

Change-Id: Ie60becde8b99d204395a2c8f35bc1ce1076334a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2309141
Commit-Queue: Stefan Zager <szager@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790514}
parent 1d68ca31
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "third_party/blink/renderer/core/animation/scroll_timeline.h" #include "third_party/blink/renderer/core/animation/scroll_timeline.h"
#include "third_party/blink/renderer/core/animation/worklet_animation_controller.h" #include "third_party/blink/renderer/core/animation/worklet_animation_controller.h"
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_video.h" #include "third_party/blink/renderer/core/layout/layout_video.h"
#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page.h"
...@@ -386,6 +387,16 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal( ...@@ -386,6 +387,16 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal(
true; true;
} }
} }
// If this is an iframe whose content document is composited, then we can't
// squash layers painted after the iframe with layers painted before it.
if (layer->GetLayoutObject().IsLayoutEmbeddedContent() &&
ToLayoutEmbeddedContent(layer->GetLayoutObject())
.ContentDocumentIsCompositing()) {
squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree =
false;
}
layer->ClearNeedsCompositingLayerAssignment(); layer->ClearNeedsCompositingLayerAssignment();
} }
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
namespace blink { namespace blink {
class CompositedLayerAssignerTest : public RenderingTest { class CompositedLayerAssignerTest : public RenderingTest {
public:
CompositedLayerAssignerTest()
: RenderingTest(MakeGarbageCollected<SingleChildLocalFrameClient>()) {}
private: private:
void SetUp() override { void SetUp() override {
EnableCompositing(); EnableCompositing();
...@@ -97,4 +101,23 @@ TEST_F(CompositedLayerAssignerTest, ...@@ -97,4 +101,23 @@ TEST_F(CompositedLayerAssignerTest,
EXPECT_EQ(kPaintsIntoOwnBacking, squashed->GetCompositingState()); EXPECT_EQ(kPaintsIntoOwnBacking, squashed->GetCompositingState());
} }
TEST_F(CompositedLayerAssignerTest,
SquashingAcrossCompositedInnerDocumentDisallowed) {
SetBodyInnerHTML(R"HTML(
<div id="bottom" style="position: absolute; will-change: transform">Bottom</div>
<div id="middle" style="position: absolute">
<iframe style="border: 10px solid magenta"></iframe>
</div>
<div id="top" style="position: absolute; width: 200px; height: 200px; background: green;">Top</div>
)HTML");
SetChildFrameHTML(R"HTML(
<style>body {will-change: transform; background: blue}</style>
)HTML");
LocalFrameView* frame_view = GetDocument().View();
frame_view->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest);
PaintLayer* top =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("top"))->Layer();
EXPECT_EQ(kPaintsIntoOwnBacking, top->GetCompositingState());
}
} // namespace blink } // namespace blink
...@@ -603,8 +603,14 @@ void CompositingRequirementsUpdater::UpdateRecursive( ...@@ -603,8 +603,14 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// Layer assignment is needed for allocating or removing composited // Layer assignment is needed for allocating or removing composited
// layers related to this PaintLayer; hence the below conditions. // layers related to this PaintLayer; hence the below conditions.
if (reasons_to_composite || layer->GetCompositingState() != kNotComposited || if (reasons_to_composite || layer->GetCompositingState() != kNotComposited ||
layer->LostGroupedMapping()) layer->LostGroupedMapping()) {
layer->SetNeedsCompositingLayerAssignment(); layer->SetNeedsCompositingLayerAssignment();
} else if (contains_composited_layer) {
// If this is an iframe whose content document is composited, then we need
// CompositedLayerAssigner to process this layer, to ensure that we don't
// squash layers painted before the iframe with layers painted after it.
layer->PropagateDescendantNeedsCompositingLayerAssignment();
}
// At this point we have finished collecting all reasons to composite this // At this point we have finished collecting all reasons to composite this
// layer. // layer.
......
...@@ -2360,7 +2360,10 @@ bool PaintLayer::IsReplacedNormalFlowStacking() const { ...@@ -2360,7 +2360,10 @@ bool PaintLayer::IsReplacedNormalFlowStacking() const {
void PaintLayer::SetNeedsCompositingLayerAssignment() { void PaintLayer::SetNeedsCompositingLayerAssignment() {
needs_compositing_layer_assignment_ = true; needs_compositing_layer_assignment_ = true;
PropagateDescendantNeedsCompositingLayerAssignment();
}
void PaintLayer::PropagateDescendantNeedsCompositingLayerAssignment() {
for (PaintLayer* curr = CompositingContainer(); for (PaintLayer* curr = CompositingContainer();
curr && !curr->StackingDescendantNeedsCompositingLayerAssignment(); curr && !curr->StackingDescendantNeedsCompositingLayerAssignment();
curr = curr->CompositingContainer()) { curr = curr->CompositingContainer()) {
......
...@@ -1106,6 +1106,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient { ...@@ -1106,6 +1106,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
void SetNeedsCompositingLayerAssignment(); void SetNeedsCompositingLayerAssignment();
void ClearNeedsCompositingLayerAssignment(); void ClearNeedsCompositingLayerAssignment();
void PropagateDescendantNeedsCompositingLayerAssignment();
bool NeedsCompositingLayerAssignment() const { bool NeedsCompositingLayerAssignment() const {
return needs_compositing_layer_assignment_; return needs_compositing_layer_assignment_;
......
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