summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc749
1 files changed, 389 insertions, 360 deletions
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
index 91ceb4707ee..1b460151f02 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc
@@ -167,7 +167,7 @@ static FloatPoint StickyPositionOffsetForLayer(PaintLayer& layer) {
static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
const LayoutObject& layout_object) {
- int min_border_width = std::min(
+ const int min_border_width = std::min(
layout_object.StyleRef().BorderTopWidth(),
std::min(layout_object.StyleRef().BorderLeftWidth(),
std::min(layout_object.StyleRef().BorderRightWidth(),
@@ -178,23 +178,45 @@ static bool NeedsDecorationOutlineLayer(const PaintLayer& paint_layer,
paint_layer.GetScrollableArea()->UsesCompositedScrolling()) ||
layout_object.IsCanvas() || IsA<LayoutVideo>(layout_object);
+ // Unlike normal outlines (whole width is outside of the offset), focus
+ // rings can be drawn with the center of the path aligned with the offset, so
+ // only 2/3 of the width is outside of the offset.
+ const int outline_drawn_inside =
+ layout_object.StyleRef().OutlineStyleIsAuto()
+ ? std::ceil(
+ layout_object.StyleRef().GetOutlineStrokeWidthForFocusRing() /
+ 3.f) +
+ 1
+ : 0;
+
return could_obscure_decorations && layout_object.StyleRef().HasOutline() &&
- layout_object.StyleRef().OutlineOffsetInt() < -min_border_width;
+ (layout_object.StyleRef().OutlineOffsetInt() - outline_drawn_inside) <
+ -min_border_width;
}
CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
: owning_layer_(layer),
pending_update_scope_(kGraphicsLayerUpdateNone),
- scrolling_contents_are_empty_(false),
draws_background_onto_content_layer_(false) {
CreatePrimaryGraphicsLayer();
}
CompositedLayerMapping::~CompositedLayerMapping() {
+ RemoveSquashedLayers(non_scrolling_squashed_layers_);
+ RemoveSquashedLayers(squashed_layers_in_scrolling_contents_);
+ UpdateOverflowControlsLayers(false, false, false);
+ UpdateForegroundLayer(false);
+ UpdateMaskLayer(false);
+ UpdateScrollingContentsLayer(false);
+ UpdateSquashingLayers(false);
+}
+
+void CompositedLayerMapping::RemoveSquashedLayers(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers) {
// Do not leave the destroyed pointer dangling on any Layers that painted to
// this mapping's squashing layer.
- for (wtf_size_t i = 0; i < squashed_layers_.size(); ++i) {
- PaintLayer* old_squashed_layer = squashed_layers_[i].paint_layer;
+ for (auto& squashed_layer : squashed_layers) {
+ PaintLayer* old_squashed_layer = squashed_layer.paint_layer;
// Assert on incorrect mappings between layers and groups
DCHECK_EQ(old_squashed_layer->GroupedMapping(), this);
if (old_squashed_layer->GroupedMapping() == this) {
@@ -203,12 +225,6 @@ CompositedLayerMapping::~CompositedLayerMapping() {
old_squashed_layer->SetLostGroupedMapping(true);
}
}
-
- UpdateOverflowControlsLayers(false, false, false);
- UpdateForegroundLayer(false);
- UpdateMaskLayer(false);
- UpdateScrollingLayers(false);
- UpdateSquashingLayers(false);
}
std::unique_ptr<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer(
@@ -254,6 +270,24 @@ void CompositedLayerMapping::CreatePrimaryGraphicsLayer() {
graphics_layer_->SetHitTestable(true);
}
+void CompositedLayerMapping::UpdateGraphicsLayerContentsOpaque(
+ bool should_check_children) {
+ if (BackgroundPaintsOntoGraphicsLayer()) {
+ bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
+ CompositedBounds(), should_check_children);
+ graphics_layer_->SetContentsOpaque(contents_opaque);
+ if (!contents_opaque) {
+ graphics_layer_->SetContentsOpaqueForText(
+ GetLayoutObject().TextIsKnownToBeOnOpaqueBackground());
+ }
+ } else {
+ // If we only paint the background onto the scrolling contents layer we
+ // are going to leave a hole in the m_graphicsLayer where the background
+ // is so it is not opaque.
+ graphics_layer_->SetContentsOpaque(false);
+ }
+}
+
void CompositedLayerMapping::UpdateContentsOpaque() {
// If there is a foreground layer, children paint into that layer and
// not graphics_layer_, and so don't contribute to the opaqueness of the
@@ -283,45 +317,55 @@ void CompositedLayerMapping::UpdateContentsOpaque() {
// determined from the main thread. Or can it?
graphics_layer_->SetContentsOpaque(false);
} else if (BackgroundPaintsOntoScrollingContentsLayer()) {
- DCHECK(HasScrollingLayer());
+ DCHECK(scrolling_contents_layer_);
// Backgrounds painted onto the foreground are clipped by the padding box
// rect.
// TODO(flackr): This should actually check the entire overflow rect
// within the scrolling contents layer but since we currently only trigger
// this for solid color backgrounds the answer will be the same.
- scrolling_contents_layer_->SetContentsOpaque(
- owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
- ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect(),
- should_check_children));
-
- if (BackgroundPaintsOntoGraphicsLayer()) {
- graphics_layer_->SetContentsOpaque(
- owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
- CompositedBounds(), should_check_children));
- } else {
- // If we only paint the background onto the scrolling contents layer we
- // are going to leave a hole in the m_graphicsLayer where the background
- // is so it is not opaque.
- graphics_layer_->SetContentsOpaque(false);
+ bool contents_opaque = owning_layer_.BackgroundIsKnownToBeOpaqueInRect(
+ ToLayoutBox(GetLayoutObject()).PhysicalPaddingBoxRect(),
+ should_check_children);
+ scrolling_contents_layer_->SetContentsOpaque(contents_opaque);
+ if (!contents_opaque) {
+ scrolling_contents_layer_->SetContentsOpaqueForText(
+ GetLayoutObject().TextIsKnownToBeOnOpaqueBackground());
}
+
+ UpdateGraphicsLayerContentsOpaque(should_check_children);
} else {
DCHECK(BackgroundPaintsOntoGraphicsLayer());
- if (HasScrollingLayer())
+ if (scrolling_contents_layer_)
scrolling_contents_layer_->SetContentsOpaque(false);
- graphics_layer_->SetContentsOpaque(
- owning_layer_.BackgroundIsKnownToBeOpaqueInRect(CompositedBounds(),
- should_check_children));
+ UpdateGraphicsLayerContentsOpaque(should_check_children);
+ }
+
+ if (non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_->SetContentsOpaque(false);
+ bool contents_opaque_for_text = true;
+ for (const GraphicsLayerPaintInfo& squashed_layer :
+ non_scrolling_squashed_layers_) {
+ if (!squashed_layer.paint_layer->GetLayoutObject()
+ .TextIsKnownToBeOnOpaqueBackground()) {
+ contents_opaque_for_text = false;
+ break;
+ }
+ }
+ non_scrolling_squashing_layer_->SetContentsOpaqueForText(
+ contents_opaque_for_text);
}
}
void CompositedLayerMapping::UpdateRasterizationPolicy() {
bool transformed_rasterization_allowed =
!(owning_layer_.GetCompositingReasons() &
- CompositingReason::kComboAllDirectReasons);
+ CompositingReason::kComboTransformedRasterizationDisallowedReasons);
graphics_layer_->CcLayer()->SetTransformedRasterizationAllowed(
transformed_rasterization_allowed);
- if (squashing_layer_)
- squashing_layer_->CcLayer()->SetTransformedRasterizationAllowed(true);
+ if (non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_->CcLayer()
+ ->SetTransformedRasterizationAllowed(true);
+ }
}
void CompositedLayerMapping::UpdateCompositedBounds() {
@@ -360,7 +404,7 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
compositor->NeedsContentsCompositingLayer(&owning_layer_)))
layer_config_changed = true;
- if (UpdateScrollingLayers(owning_layer_.NeedsCompositedScrolling()))
+ if (UpdateScrollingContentsLayer(owning_layer_.NeedsCompositedScrolling()))
layer_config_changed = true;
// If the outline needs to draw over the composited scrolling contents layer
@@ -377,25 +421,19 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
RequiresScrollCornerLayer()))
layer_config_changed = true;
- if (UpdateSquashingLayers(!squashed_layers_.IsEmpty()))
+ if (UpdateSquashingLayers(!non_scrolling_squashed_layers_.IsEmpty()))
layer_config_changed = true;
- if (layer_config_changed)
- UpdateInternalHierarchy();
-
- // A mask layer is not part of the hierarchy proper, it's an auxiliary layer
- // that's plugged into another GraphicsLayer that is part of the hierarchy.
- // It has no parent or child GraphicsLayer. For that reason, we process it
- // here, after the hierarchy has been updated.
bool has_mask =
CSSMaskPainter::MaskBoundingBox(GetLayoutObject(), PhysicalOffset())
.has_value();
bool has_clip_path =
ClipPathClipper::LocalClipPathBoundingBox(GetLayoutObject()).has_value();
- if (UpdateMaskLayer(has_mask || has_clip_path)) {
- graphics_layer_->SetMaskLayer(mask_layer_.get());
+ if (UpdateMaskLayer(has_mask || has_clip_path))
layer_config_changed = true;
- }
+
+ if (layer_config_changed)
+ UpdateInternalHierarchy();
UpdateBackgroundColor();
@@ -410,9 +448,6 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
remote->GetCcLayer(), remote->WebLayerHasFixedContentsOpaque());
}
}
- if (PaintLayerCompositor::AttachFrameContentLayersToIframeLayer(
- ToLayoutEmbeddedContent(layout_object)))
- layer_config_changed = true;
} else if (IsA<LayoutVideo>(layout_object)) {
auto* media_element = To<HTMLMediaElement>(layout_object.GetNode());
graphics_layer_->SetContentsToCcLayer(
@@ -555,7 +590,7 @@ void CompositedLayerMapping::UpdateSquashingLayerGeometry(
const IntPoint& snapped_offset_from_composited_ancestor,
Vector<GraphicsLayerPaintInfo>& layers,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
- if (!squashing_layer_)
+ if (!non_scrolling_squashing_layer_)
return;
IntPoint graphics_layer_parent_location;
@@ -656,24 +691,24 @@ void CompositedLayerMapping::UpdateSquashingLayerGeometry(
layers[i].paint_layer->SetSubpixelAccumulation(subpixel_accumulation);
}
- squashing_layer_->SetSize(gfx::Size(squash_layer_bounds.Size()));
- // We can't squashing_layer_->SetOffsetFromLayoutObject().
+ non_scrolling_squashing_layer_->SetSize(
+ gfx::Size(squash_layer_bounds.Size()));
+ // We can't non_scrolling_squashing_layer_->SetOffsetFromLayoutObject().
// Squashing layer has special paint and invalidation logic that already
// compensated for compositing bounds, setting it here would end up
// double adjustment.
auto new_offset = squash_layer_bounds.Location() -
snapped_offset_from_composited_ancestor +
ToIntSize(graphics_layer_parent_location);
- if (new_offset != squashing_layer_offset_from_layout_object_) {
- squashing_layer_offset_from_layout_object_ = new_offset;
+ if (new_offset != non_scrolling_squashing_layer_offset_from_layout_object_) {
+ non_scrolling_squashing_layer_offset_from_layout_object_ = new_offset;
// Need to update squashing LayerState according to the new offset.
// The pre-paint tree walk does this.
GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
- for (wtf_size_t i = 0; i < layers.size(); ++i) {
- LocalClipRectForSquashedLayer(owning_layer_, layers, layers[i]);
- }
+ for (auto& layer : layers)
+ UpdateLocalClipRectForSquashedLayer(owning_layer_, layers, layer);
}
void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
@@ -691,14 +726,11 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
UpdateOverflowControlsHostLayerGeometry(compositing_container);
UpdateSquashingLayerGeometry(
compositing_container, snapped_offset_from_composited_ancestor,
- squashed_layers_, layers_needing_paint_invalidation);
+ non_scrolling_squashed_layers_, layers_needing_paint_invalidation);
UpdateMaskLayerGeometry();
- // TODO(yigu): Currently the decoration layer uses the same contentSize
- // as the foreground layer. There are scenarios where the sizes could be
- // different so the decoration layer size should be calculated separately.
UpdateDecorationOutlineLayerGeometry(local_compositing_bounds.Size());
- UpdateScrollingLayerGeometry();
+ UpdateScrollingContentsLayerGeometry(layers_needing_paint_invalidation);
UpdateForegroundLayerGeometry();
if (owning_layer_.GetScrollableArea() &&
@@ -788,22 +820,22 @@ void CompositedLayerMapping::UpdateMaskLayerGeometry() {
graphics_layer_->OffsetFromLayoutObject());
}
-void CompositedLayerMapping::UpdateScrollingLayerGeometry() {
- if (!scrolling_layer_)
+void CompositedLayerMapping::UpdateScrollingContentsLayerGeometry(
+ Vector<PaintLayer*>& layers_needing_paint_invalidation) {
+ if (!scrolling_contents_layer_) {
+ DCHECK(squashed_layers_in_scrolling_contents_.IsEmpty());
return;
+ }
DCHECK(scrolling_contents_layer_);
LayoutBox& layout_box = ToLayoutBox(GetLayoutObject());
IntRect overflow_clip_rect = PixelSnappedIntRect(
layout_box.OverflowClipRect(owning_layer_.SubpixelAccumulation()));
- auto old_scroll_container_size = scrolling_layer_->Size();
- scrolling_layer_->SetSize(gfx::Size(overflow_clip_rect.Size()));
bool scroll_container_size_changed =
- old_scroll_container_size != scrolling_layer_->Size();
-
- scrolling_layer_->SetOffsetFromLayoutObject(
- ToIntSize(overflow_clip_rect.Location()));
+ previous_scroll_container_size_ != overflow_clip_rect.Size();
+ if (scroll_container_size_changed)
+ previous_scroll_container_size_ = overflow_clip_rect.Size();
PaintLayerScrollableArea* scrollable_area = owning_layer_.GetScrollableArea();
IntSize scroll_size = scrollable_area->PixelSnappedContentsSize(
@@ -825,6 +857,33 @@ void CompositedLayerMapping::UpdateScrollingLayerGeometry() {
scrolling_contents_layer_->SetOffsetFromLayoutObject(
overflow_clip_rect.Location() - scrollable_area->ScrollOrigin());
+
+ for (auto& layer : squashed_layers_in_scrolling_contents_) {
+ layer.composited_bounds = layer.paint_layer->BoundingBoxForCompositing();
+ PhysicalOffset offset_from_scrolling_contents_layer =
+ layer.paint_layer->ComputeOffsetFromAncestor(owning_layer_) +
+ owning_layer_.SubpixelAccumulation() -
+ PhysicalOffset(scrolling_contents_layer_->OffsetFromLayoutObject());
+ IntSize new_offset_from_layout_object =
+ -ToIntSize(RoundedIntPoint(offset_from_scrolling_contents_layer));
+ PhysicalOffset subpixel_accumulation =
+ offset_from_scrolling_contents_layer +
+ PhysicalOffset(new_offset_from_layout_object);
+
+ if (layer.offset_from_layout_object_set &&
+ layer.offset_from_layout_object != new_offset_from_layout_object) {
+ ObjectPaintInvalidator(layer.paint_layer->GetLayoutObject())
+ .InvalidatePaintIncludingNonCompositingDescendants();
+ layers_needing_paint_invalidation.push_back(layer.paint_layer);
+ }
+ layer.offset_from_layout_object = new_offset_from_layout_object;
+ layer.offset_from_layout_object_set = true;
+ layer.paint_layer->SetSubpixelAccumulation(subpixel_accumulation);
+ }
+ for (auto& layer : squashed_layers_in_scrolling_contents_) {
+ UpdateLocalClipRectForSquashedLayer(
+ owning_layer_, squashed_layers_in_scrolling_contents_, layer);
+ }
}
bool CompositedLayerMapping::RequiresHorizontalScrollbarLayer() const {
@@ -852,7 +911,7 @@ void CompositedLayerMapping::UpdateForegroundLayerGeometry() {
IntRect compositing_bounds(
IntPoint(graphics_layer_->OffsetFromLayoutObject()),
IntSize(graphics_layer_->Size()));
- if (scrolling_layer_) {
+ if (scrolling_contents_layer_) {
// Override compositing bounds to include full overflow if composited
// scrolling is used.
compositing_bounds =
@@ -885,47 +944,36 @@ void CompositedLayerMapping::UpdateDecorationOutlineLayerGeometry(
}
void CompositedLayerMapping::UpdateInternalHierarchy() {
- // m_foregroundLayer has to be inserted in the correct order with child
- // layers, so it's not inserted here.
+ // foreground_layer_ has to be inserted in the correct order with child
+ // layers in SetSubLayers(), so it's not inserted here.
graphics_layer_->RemoveFromParent();
- // Layer to which children should be attached as we build the hierarchy.
- GraphicsLayer* bottom_layer = graphics_layer_.get();
- auto update_bottom_layer = [&bottom_layer](GraphicsLayer* layer) {
- if (layer) {
- bottom_layer->AddChild(layer);
- bottom_layer = layer;
- }
- };
-
- update_bottom_layer(scrolling_layer_.get());
+ if (scrolling_contents_layer_)
+ graphics_layer_->AddChild(scrolling_contents_layer_.get());
// Now constructing the subtree for the overflow controls.
- bottom_layer = graphics_layer_.get();
- update_bottom_layer(overflow_controls_host_layer_.get());
- if (layer_for_horizontal_scrollbar_) {
- overflow_controls_host_layer_->AddChild(
- layer_for_horizontal_scrollbar_.get());
- }
- if (layer_for_vertical_scrollbar_) {
- overflow_controls_host_layer_->AddChild(
- layer_for_vertical_scrollbar_.get());
+ if (overflow_controls_host_layer_) {
+ graphics_layer_->AddChild(overflow_controls_host_layer_.get());
+ if (layer_for_horizontal_scrollbar_) {
+ overflow_controls_host_layer_->AddChild(
+ layer_for_horizontal_scrollbar_.get());
+ }
+ if (layer_for_vertical_scrollbar_) {
+ overflow_controls_host_layer_->AddChild(
+ layer_for_vertical_scrollbar_.get());
+ }
+ if (layer_for_scroll_corner_)
+ overflow_controls_host_layer_->AddChild(layer_for_scroll_corner_.get());
}
- if (layer_for_scroll_corner_)
- overflow_controls_host_layer_->AddChild(layer_for_scroll_corner_.get());
- // Now add the DecorationOutlineLayer as a subtree to GraphicsLayer
- if (decoration_outline_layer_.get())
+ if (decoration_outline_layer_)
graphics_layer_->AddChild(decoration_outline_layer_.get());
- // The squashing containment layer, if it exists, becomes a no-op parent.
- if (squashing_layer_) {
- if (squashing_containment_layer_) {
- squashing_containment_layer_->RemoveAllChildren();
- squashing_containment_layer_->AddChild(graphics_layer_.get());
- squashing_containment_layer_->AddChild(squashing_layer_.get());
- }
- }
+ if (mask_layer_)
+ graphics_layer_->AddChild(mask_layer_.get());
+
+ if (non_scrolling_squashing_layer_)
+ graphics_layer_->AddChild(non_scrolling_squashing_layer_.get());
}
void CompositedLayerMapping::UpdatePaintingPhases() {
@@ -975,15 +1023,15 @@ void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() {
GetPluginContainer(GetLayoutObject())->WantsWheelEvents()));
graphics_layer_->SetPaintsHitTest(paints_hit_test || paints_scroll_hit_test);
- if (scrolling_layer_) {
- // m_scrollingLayer never has backing store.
- // m_scrollingContentsLayer only needs backing store if the scrolled
+ if (scrolling_contents_layer_) {
+ // scrolling_contents_layer_ only needs backing store if the scrolled
// contents need to paint.
- scrolling_contents_are_empty_ =
- !owning_layer_.HasVisibleContent() ||
- !(GetLayoutObject().StyleRef().HasBackground() ||
- GetLayoutObject().HasNonInitialBackdropFilter() || PaintsChildren());
- scrolling_contents_layer_->SetDrawsContent(!scrolling_contents_are_empty_);
+ bool has_painted_scrolling_contents =
+ !squashed_layers_in_scrolling_contents_.IsEmpty() ||
+ (owning_layer_.HasVisibleContent() &&
+ (GetLayoutObject().StyleRef().HasBackground() ||
+ GetLayoutObject().HasNonInitialBackdropFilter() || PaintsChildren()));
+ scrolling_contents_layer_->SetDrawsContent(has_painted_scrolling_contents);
scrolling_contents_layer_->SetPaintsHitTest(paints_hit_test);
}
@@ -1145,85 +1193,32 @@ void CompositedLayerMapping::PositionOverflowControlsLayers() {
}
}
-enum ApplyToGraphicsLayersModeFlags {
- kApplyToLayersAffectedByPreserve3D = (1 << 0),
- kApplyToSquashingLayer = (1 << 1),
- kApplyToScrollbarLayers = (1 << 2),
- kApplyToMaskLayers = (1 << 3),
- kApplyToContentLayers = (1 << 4),
- kApplyToChildContainingLayers =
- (1 << 5), // layers between m_graphicsLayer and children
- kApplyToNonScrollingContentLayers = (1 << 6),
- kApplyToScrollingContentLayers = (1 << 7),
- kApplyToDecorationOutlineLayer = (1 << 8),
- kApplyToAllGraphicsLayers =
- (kApplyToSquashingLayer | kApplyToScrollbarLayers | kApplyToMaskLayers |
- kApplyToLayersAffectedByPreserve3D | kApplyToContentLayers |
- kApplyToScrollingContentLayers | kApplyToDecorationOutlineLayer)
+enum ApplyToGraphicsLayersMode {
+ kApplyToContentLayers,
+ kApplyToAllGraphicsLayers,
};
-typedef unsigned ApplyToGraphicsLayersMode;
-
-// Flags to layers mapping matrix:
-// bit 0 1 2 3 4 5 6 7 8
-// ChildTransform * *
-// Main * * *
-// Clipping * *
-// Scrolling * *
-// ScrollingContents * * * *
-// Foreground * * *
-// Squashing *
-// Mask * * *
-// HorizontalScrollbar *
-// VerticalScrollbar *
-// ScrollCorner *
-// DecorationOutline * *
-template <typename Func>
+
+template <typename Function>
static void ApplyToGraphicsLayers(const CompositedLayerMapping* mapping,
- const Func& f,
+ const Function& function,
ApplyToGraphicsLayersMode mode) {
- DCHECK(mode);
-
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToContentLayers) ||
- (mode & kApplyToNonScrollingContentLayers)) &&
- mapping->MainGraphicsLayer())
- f(mapping->MainGraphicsLayer());
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToChildContainingLayers)) &&
- mapping->ScrollingLayer())
- f(mapping->ScrollingLayer());
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToContentLayers) ||
- (mode & kApplyToChildContainingLayers) ||
- (mode & kApplyToScrollingContentLayers)) &&
- mapping->ScrollingContentsLayer())
- f(mapping->ScrollingContentsLayer());
- if (((mode & kApplyToLayersAffectedByPreserve3D) ||
- (mode & kApplyToContentLayers) ||
- (mode & kApplyToScrollingContentLayers)) &&
- mapping->ForegroundLayer())
- f(mapping->ForegroundLayer());
-
- if ((mode & kApplyToSquashingLayer) && mapping->SquashingLayer())
- f(mapping->SquashingLayer());
-
- if (((mode & kApplyToMaskLayers) || (mode & kApplyToContentLayers) ||
- (mode & kApplyToNonScrollingContentLayers)) &&
- mapping->MaskLayer())
- f(mapping->MaskLayer());
-
- if ((mode & kApplyToScrollbarLayers) &&
- mapping->LayerForHorizontalScrollbar())
- f(mapping->LayerForHorizontalScrollbar());
- if ((mode & kApplyToScrollbarLayers) && mapping->LayerForVerticalScrollbar())
- f(mapping->LayerForVerticalScrollbar());
- if ((mode & kApplyToScrollbarLayers) && mapping->LayerForScrollCorner())
- f(mapping->LayerForScrollCorner());
-
- if (((mode & kApplyToDecorationOutlineLayer) ||
- (mode & kApplyToNonScrollingContentLayers)) &&
- mapping->DecorationOutlineLayer())
- f(mapping->DecorationOutlineLayer());
+ auto null_checking_function = [&function](GraphicsLayer* layer) {
+ if (layer)
+ function(layer);
+ };
+
+ null_checking_function(mapping->MainGraphicsLayer());
+ null_checking_function(mapping->ScrollingContentsLayer());
+ null_checking_function(mapping->ForegroundLayer());
+ null_checking_function(mapping->MaskLayer());
+ null_checking_function(mapping->DecorationOutlineLayer());
+
+ if (mode == kApplyToAllGraphicsLayers) {
+ null_checking_function(mapping->NonScrollingSquashingLayer());
+ null_checking_function(mapping->LayerForHorizontalScrollbar());
+ null_checking_function(mapping->LayerForVerticalScrollbar());
+ null_checking_function(mapping->LayerForScrollCorner());
+ }
}
// You receive an element id if you have an animation, or you're a scroller (and
@@ -1301,24 +1296,18 @@ bool CompositedLayerMapping::UpdateMaskLayer(bool needs_mask_layer) {
return layer_changed;
}
-bool CompositedLayerMapping::UpdateScrollingLayers(
- bool needs_scrolling_layers) {
+bool CompositedLayerMapping::UpdateScrollingContentsLayer(
+ bool needs_scrolling_contents_layer) {
ScrollingCoordinator* scrolling_coordinator =
owning_layer_.GetScrollingCoordinator();
auto* scrollable_area = owning_layer_.GetScrollableArea();
if (scrollable_area)
- scrollable_area->SetUsesCompositedScrolling(needs_scrolling_layers);
+ scrollable_area->SetUsesCompositedScrolling(needs_scrolling_contents_layer);
bool layer_changed = false;
- if (needs_scrolling_layers) {
- if (!scrolling_layer_) {
- // Outer layer which corresponds with the scroll view.
- scrolling_layer_ =
- CreateGraphicsLayer(CompositingReason::kLayerForScrollingContainer);
- scrolling_layer_->SetDrawsContent(false);
- scrolling_layer_->SetHitTestable(false);
-
+ if (needs_scrolling_contents_layer) {
+ if (!scrolling_contents_layer_) {
// Inner layer which renders the content that scrolls.
scrolling_contents_layer_ =
CreateGraphicsLayer(CompositingReason::kLayerForScrollingContents);
@@ -1327,8 +1316,6 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
auto element_id = scrollable_area->GetScrollElementId();
scrolling_contents_layer_->SetElementId(element_id);
- scrolling_layer_->AddChild(scrolling_contents_layer_.get());
-
layer_changed = true;
if (scrolling_coordinator && scrollable_area) {
scrolling_coordinator->ScrollableAreaScrollLayerDidChange(
@@ -1338,8 +1325,7 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
layout_view->GetFrameView()->ScrollableAreasDidChange();
}
}
- } else if (scrolling_layer_) {
- scrolling_layer_ = nullptr;
+ } else if (scrolling_contents_layer_) {
scrolling_contents_layer_ = nullptr;
layer_changed = true;
if (scrolling_coordinator && scrollable_area) {
@@ -1359,32 +1345,21 @@ bool CompositedLayerMapping::UpdateSquashingLayers(
bool layers_changed = false;
if (needs_squashing_layers) {
- if (!squashing_layer_) {
- squashing_layer_ =
+ if (!non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_ =
CreateGraphicsLayer(CompositingReason::kLayerForSquashingContents);
- squashing_layer_->SetDrawsContent(true);
- squashing_layer_->SetHitTestable(true);
- layers_changed = true;
- }
- if (!squashing_containment_layer_) {
- squashing_containment_layer_ =
- CreateGraphicsLayer(CompositingReason::kLayerForSquashingContainer);
+ non_scrolling_squashing_layer_->SetDrawsContent(true);
+ non_scrolling_squashing_layer_->SetHitTestable(true);
layers_changed = true;
}
- DCHECK(squashing_layer_);
+ DCHECK(non_scrolling_squashing_layer_);
} else {
- if (squashing_layer_) {
- squashing_layer_->RemoveFromParent();
- squashing_layer_ = nullptr;
+ if (non_scrolling_squashing_layer_) {
+ non_scrolling_squashing_layer_->RemoveFromParent();
+ non_scrolling_squashing_layer_ = nullptr;
layers_changed = true;
}
- if (squashing_containment_layer_) {
- squashing_containment_layer_->RemoveFromParent();
- squashing_containment_layer_ = nullptr;
- layers_changed = true;
- }
- DCHECK(!squashing_layer_);
- DCHECK(!squashing_containment_layer_);
+ DCHECK(!non_scrolling_squashing_layer_);
}
return layers_changed;
@@ -1421,9 +1396,13 @@ Color CompositedLayerMapping::LayoutObjectBackgroundColor() const {
void CompositedLayerMapping::UpdateBackgroundColor() {
auto color = LayoutObjectBackgroundColor().Rgb();
- graphics_layer_->SetBackgroundColor(color);
- if (scrolling_contents_layer_)
- scrolling_contents_layer_->SetBackgroundColor(color);
+ graphics_layer_->SetBackgroundColor(
+ BackgroundPaintsOntoGraphicsLayer() ? color : SK_ColorTRANSPARENT);
+ if (scrolling_contents_layer_) {
+ scrolling_contents_layer_->SetBackgroundColor(
+ BackgroundPaintsOntoScrollingContentsLayer() ? color
+ : SK_ColorTRANSPARENT);
+ }
}
bool CompositedLayerMapping::PaintsChildren() const {
@@ -1439,7 +1418,7 @@ bool CompositedLayerMapping::PaintsChildren() const {
static bool IsCompositedPlugin(LayoutObject& layout_object) {
return layout_object.IsEmbeddedObject() &&
- ToLayoutEmbeddedObject(layout_object).RequiresAcceleratedCompositing();
+ layout_object.AdditionalCompositingReasons();
}
bool CompositedLayerMapping::HasVisibleNonCompositingDescendant(
@@ -1468,7 +1447,7 @@ bool CompositedLayerMapping::ContainsPaintedContent() const {
// fill the border box entirely, and set background color on the layer in that
// case, instead of allocating backing store and painting.
auto* layout_video = DynamicTo<LayoutVideo>(layout_object);
- if (layout_video && layout_video->ShouldDisplayVideo())
+ if (layout_video && layout_video->GetDisplayMode() == LayoutVideo::kVideo)
return owning_layer_.HasBoxDecorationsOrBackground();
if (layout_object.GetNode() && layout_object.GetNode()->IsDocumentNode()) {
@@ -1556,13 +1535,6 @@ GraphicsLayer* CompositedLayerMapping::DetachLayerForOverflowControls() {
return overflow_controls_host_layer_.get();
}
-GraphicsLayer* CompositedLayerMapping::DetachLayerForDecorationOutline() {
- if (!decoration_outline_layer_.get())
- return nullptr;
- decoration_outline_layer_->RemoveFromParent();
- return decoration_outline_layer_.get();
-}
-
GraphicsLayer* CompositedLayerMapping::ParentForSublayers() const {
if (scrolling_contents_layer_)
return scrolling_contents_layer_.get();
@@ -1572,28 +1544,28 @@ GraphicsLayer* CompositedLayerMapping::ParentForSublayers() const {
void CompositedLayerMapping::SetSublayers(
const GraphicsLayerVector& sublayers) {
- GraphicsLayer* overflow_controls_container =
- overflow_controls_host_layer_.get();
GraphicsLayer* parent = ParentForSublayers();
- bool needs_overflow_controls_reattached =
- overflow_controls_container &&
- overflow_controls_container->Parent() == parent;
-
- parent->SetChildren(sublayers);
- // If we have scrollbars, but are not using composited scrolling, then
- // parentForSublayers may return m_graphicsLayer. In that case, the above
- // call to setChildren has clobbered the overflow controls host layer, so we
- // need to reattach it.
- if (needs_overflow_controls_reattached)
- parent->AddChild(overflow_controls_container);
-}
+ // TODO(szager): Remove after diagnosing crash crbug.com/1092673
+ CHECK(parent);
+
+ // Some layers are managed by CompositedLayerMapping under |parent| need to
+ // be reattached after SetChildren() below which will clobber all children.
+ GraphicsLayerVector layers_needing_reattachment;
+ auto add_layer_needing_reattachment =
+ [parent, &layers_needing_reattachment](GraphicsLayer* layer) {
+ if (layer && layer->Parent() == parent)
+ layers_needing_reattachment.push_back(layer);
+ };
+ add_layer_needing_reattachment(overflow_controls_host_layer_.get());
+ add_layer_needing_reattachment(decoration_outline_layer_.get());
+ add_layer_needing_reattachment(mask_layer_.get());
+ add_layer_needing_reattachment(non_scrolling_squashing_layer_.get());
-GraphicsLayer* CompositedLayerMapping::ChildForSuperlayers() const {
- if (squashing_containment_layer_)
- return squashing_containment_layer_.get();
+ parent->SetChildren(sublayers);
- return graphics_layer_.get();
+ for (GraphicsLayer* layer : layers_needing_reattachment)
+ parent->AddChild(layer);
}
GraphicsLayerUpdater::UpdateType CompositedLayerMapping::UpdateTypeForChildren(
@@ -1603,6 +1575,19 @@ GraphicsLayerUpdater::UpdateType CompositedLayerMapping::UpdateTypeForChildren(
return update_type;
}
+GraphicsLayer* CompositedLayerMapping::SquashingLayer(
+ const PaintLayer& squashed_layer) const {
+#if DCHECK_IS_ON()
+ AssertInSquashedLayersVector(squashed_layer);
+#endif
+ if (MayBeSquashedIntoScrollingContents(squashed_layer)) {
+ DCHECK(ScrollingContentsLayer());
+ return ScrollingContentsLayer();
+ }
+ DCHECK(NonScrollingSquashingLayer());
+ return NonScrollingSquashingLayer();
+}
+
struct SetContentsNeedsDisplayFunctor {
void operator()(GraphicsLayer* layer) const {
if (layer->PaintsContentOrHitTest())
@@ -1610,13 +1595,12 @@ struct SetContentsNeedsDisplayFunctor {
}
};
-void CompositedLayerMapping::SetSquashingContentsNeedDisplay() {
+void CompositedLayerMapping::SetAllLayersNeedDisplay() {
ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(),
- kApplyToSquashingLayer);
+ kApplyToAllGraphicsLayers);
}
void CompositedLayerMapping::SetContentsNeedDisplay() {
- // FIXME: need to split out paint invalidations for the background.
ApplyToGraphicsLayers(this, SetContentsNeedsDisplayFunctor(),
kApplyToContentLayers);
}
@@ -1646,20 +1630,23 @@ const GraphicsLayerPaintInfo* CompositedLayerMapping::ContainingSquashedLayer(
return nullptr;
}
-const GraphicsLayerPaintInfo* CompositedLayerMapping::ContainingSquashedLayer(
+const GraphicsLayerPaintInfo*
+CompositedLayerMapping::ContainingSquashedLayerInSquashingLayer(
const LayoutObject* layout_object,
- unsigned max_squashed_layer_index) {
- return CompositedLayerMapping::ContainingSquashedLayer(
- layout_object, squashed_layers_, max_squashed_layer_index);
+ unsigned max_squashed_layer_index) const {
+ return ContainingSquashedLayer(layout_object, non_scrolling_squashed_layers_,
+ max_squashed_layer_index);
}
-void CompositedLayerMapping::LocalClipRectForSquashedLayer(
+void CompositedLayerMapping::UpdateLocalClipRectForSquashedLayer(
const PaintLayer& reference_layer,
const Vector<GraphicsLayerPaintInfo>& layers,
GraphicsLayerPaintInfo& paint_info) {
const LayoutObject* clipping_container =
paint_info.paint_layer->ClippingContainer();
- if (clipping_container == reference_layer.ClippingContainer()) {
+ if (clipping_container == reference_layer.ClippingContainer() ||
+ // When squashing into scrolling contents without other clips.
+ clipping_container == &reference_layer.GetLayoutObject()) {
paint_info.local_clip_rect_for_squashed_layer =
ClipRect(PhysicalRect(LayoutRect::InfiniteIntRect()));
paint_info.offset_from_clip_rect_root = PhysicalOffset();
@@ -1672,7 +1659,7 @@ void CompositedLayerMapping::LocalClipRectForSquashedLayer(
const GraphicsLayerPaintInfo* ancestor_paint_info =
ContainingSquashedLayer(clipping_container, layers, layers.size());
// Must be there, otherwise
- // CompositingLayerAssigner::canSquashIntoCurrentSquashingOwner would have
+ // CompositingLayerAssigner::GetReasonsPreventingSquashing() would have
// disallowed squashing.
DCHECK(ancestor_paint_info);
@@ -1924,7 +1911,7 @@ IntRect CompositedLayerMapping::ComputeInterestRect(
return previous_interest_rect;
if (graphics_layer != graphics_layer_.get() &&
- graphics_layer != squashing_layer_.get() &&
+ graphics_layer != non_scrolling_squashing_layer_.get() &&
graphics_layer != scrolling_contents_layer_.get())
return whole_layer_rect;
@@ -1968,6 +1955,31 @@ bool CompositedLayerMapping::AdjustForCompositedScrolling(
return false;
}
+static constexpr PaintLayerFlags PaintLayerFlagsFromGraphicsLayerPaintingPhase(
+ GraphicsLayerPaintingPhase graphics_layer_painting_phase) {
+ PaintLayerFlags paint_layer_flags = 0;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintBackground)
+ paint_layer_flags |= kPaintLayerPaintingCompositingBackgroundPhase;
+ else
+ paint_layer_flags |= kPaintLayerPaintingSkipRootBackground;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintForeground)
+ paint_layer_flags |= kPaintLayerPaintingCompositingForegroundPhase;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintMask)
+ paint_layer_flags |= kPaintLayerPaintingCompositingMaskPhase;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintOverflowContents)
+ paint_layer_flags |= kPaintLayerPaintingOverflowContents;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintCompositedScroll)
+ paint_layer_flags |= kPaintLayerPaintingCompositingScrollingPhase;
+ if (graphics_layer_painting_phase & kGraphicsLayerPaintDecoration)
+ paint_layer_flags |= kPaintLayerPaintingCompositingDecorationPhase;
+ return paint_layer_flags;
+}
+
+// Always paint all phases for squashed layers.
+static constexpr PaintLayerFlags kPaintLayerFlagsForSquashedLayer =
+ PaintLayerFlagsFromGraphicsLayerPaintingPhase(
+ kGraphicsLayerPaintAllWithOverflowClip);
+
void CompositedLayerMapping::PaintContents(
const GraphicsLayer* graphics_layer,
GraphicsContext& context,
@@ -1993,21 +2005,9 @@ void CompositedLayerMapping::PaintContents(
inspector_paint_event::Data(&owning_layer_.GetLayoutObject(),
PhysicalRect(interest_rect), graphics_layer));
- PaintLayerFlags paint_layer_flags = 0;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintBackground)
- paint_layer_flags |= kPaintLayerPaintingCompositingBackgroundPhase;
- else
- paint_layer_flags |= kPaintLayerPaintingSkipRootBackground;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintForeground)
- paint_layer_flags |= kPaintLayerPaintingCompositingForegroundPhase;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintMask)
- paint_layer_flags |= kPaintLayerPaintingCompositingMaskPhase;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintOverflowContents)
- paint_layer_flags |= kPaintLayerPaintingOverflowContents;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintCompositedScroll)
- paint_layer_flags |= kPaintLayerPaintingCompositingScrollingPhase;
- if (graphics_layer_painting_phase & kGraphicsLayerPaintDecoration)
- paint_layer_flags |= kPaintLayerPaintingCompositingDecorationPhase;
+ PaintLayerFlags paint_layer_flags =
+ PaintLayerFlagsFromGraphicsLayerPaintingPhase(
+ graphics_layer_painting_phase);
if (graphics_layer == graphics_layer_.get() ||
graphics_layer == foreground_layer_.get() ||
@@ -2033,10 +2033,23 @@ void CompositedLayerMapping::PaintContents(
// compute and cache clipRects.
DoPaintTask(paint_info, *graphics_layer, paint_layer_flags, context,
interest_rect);
- } else if (graphics_layer == squashing_layer_.get()) {
- for (wtf_size_t i = 0; i < squashed_layers_.size(); ++i) {
- DoPaintTask(squashed_layers_[i], *graphics_layer, paint_layer_flags,
- context, interest_rect);
+
+ if (graphics_layer == scrolling_contents_layer_.get() &&
+ !squashed_layers_in_scrolling_contents_.IsEmpty()) {
+ // We have squashed_layers_in_scrolling_contents_ only if owning_layer_
+ // is not a stacking context, thus doesn't have foreground_layer_.
+ // (Otherwise we would need to squash into foreground_layer_.)
+ DCHECK(!foreground_layer_);
+ for (auto& squashed_layer : squashed_layers_in_scrolling_contents_) {
+ DoPaintTask(squashed_layer, *graphics_layer,
+ kPaintLayerFlagsForSquashedLayer, context, interest_rect);
+ }
+ }
+ } else if (graphics_layer == non_scrolling_squashing_layer_.get()) {
+ DCHECK_EQ(kPaintLayerFlagsForSquashedLayer, paint_layer_flags);
+ for (auto& squashed_layer : non_scrolling_squashed_layers_) {
+ DoPaintTask(squashed_layer, *graphics_layer, paint_layer_flags, context,
+ interest_rect);
}
} else if (IsScrollableAreaLayer(graphics_layer)) {
PaintScrollableArea(graphics_layer, context, interest_rect);
@@ -2144,109 +2157,129 @@ void CompositedLayerMapping::VerifyNotPainting() {
}
#endif
-bool CompositedLayerMapping::InvalidateLayerIfNoPrecedingEntry(
- wtf_size_t index_to_clear) {
- PaintLayer* layer_to_remove = squashed_layers_[index_to_clear].paint_layer;
- wtf_size_t previous_index = 0;
- for (; previous_index < index_to_clear; ++previous_index) {
- if (squashed_layers_[previous_index].paint_layer == layer_to_remove)
- break;
- }
- if (previous_index == index_to_clear &&
- layer_to_remove->GroupedMapping() == this) {
- Compositor()->PaintInvalidationOnCompositingChange(layer_to_remove);
- return true;
- }
- return false;
-}
-
-bool CompositedLayerMapping::UpdateSquashingLayerAssignment(
- PaintLayer* squashed_layer,
+bool CompositedLayerMapping::UpdateSquashingLayerAssignmentInternal(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ PaintLayer& squashed_layer,
wtf_size_t next_squashed_layer_index) {
GraphicsLayerPaintInfo paint_info;
- paint_info.paint_layer = squashed_layer;
+ paint_info.paint_layer = &squashed_layer;
// NOTE: composited bounds are updated elsewhere
// NOTE: offsetFromLayoutObject is updated elsewhere
// Change tracking on squashing layers: at the first sign of something
// changed, just invalidate the layer.
// FIXME: Perhaps we can find a tighter more clever mechanism later.
- if (next_squashed_layer_index < squashed_layers_.size()) {
+ if (next_squashed_layer_index < squashed_layers.size()) {
if (paint_info.paint_layer ==
- squashed_layers_[next_squashed_layer_index].paint_layer)
+ squashed_layers[next_squashed_layer_index].paint_layer)
return false;
-
- // Must invalidate before adding the squashed layer to the mapping.
- Compositor()->PaintInvalidationOnCompositingChange(squashed_layer);
-
- // If the layer which was previously at |nextSquashedLayerIndex| is not
- // earlier in the grouped mapping, invalidate its current backing now, since
- // it will move later or be removed from the squashing layer.
- InvalidateLayerIfNoPrecedingEntry(next_squashed_layer_index);
-
- squashed_layers_.insert(next_squashed_layer_index, paint_info);
+ squashed_layers.insert(next_squashed_layer_index, paint_info);
} else {
- // Must invalidate before adding the squashed layer to the mapping.
- Compositor()->PaintInvalidationOnCompositingChange(squashed_layer);
- squashed_layers_.push_back(paint_info);
+ squashed_layers.push_back(paint_info);
}
- squashed_layer->SetGroupedMapping(
+ // Must invalidate before adding the squashed layer to the mapping.
+ Compositor()->PaintInvalidationOnCompositingChange(&squashed_layer);
+ squashed_layer.SetGroupedMapping(
this, PaintLayer::kInvalidateLayerAndRemoveFromMapping);
return true;
}
+bool CompositedLayerMapping::UpdateSquashingLayerAssignment(
+ PaintLayer& squashed_layer,
+ wtf_size_t next_squashed_layer_in_non_scrolling_squashing_layer_index,
+ wtf_size_t next_squashed_layer_in_scrolling_contents_index) {
+ if (MayBeSquashedIntoScrollingContents(squashed_layer)) {
+ return UpdateSquashingLayerAssignmentInternal(
+ squashed_layers_in_scrolling_contents_, squashed_layer,
+ next_squashed_layer_in_scrolling_contents_index);
+ }
+ return UpdateSquashingLayerAssignmentInternal(
+ non_scrolling_squashed_layers_, squashed_layer,
+ next_squashed_layer_in_non_scrolling_squashing_layer_index);
+}
+
void CompositedLayerMapping::RemoveLayerFromSquashingGraphicsLayer(
- const PaintLayer* layer) {
- wtf_size_t layer_index = 0;
- for (; layer_index < squashed_layers_.size(); ++layer_index) {
- if (squashed_layers_[layer_index].paint_layer == layer)
- break;
+ const PaintLayer& layer) {
+ // We must try to remove the layer from both vectors because
+ // MayBeSquashedIntoScrollingContents() may not reflect the previous status.
+ for (wtf_size_t i = 0; i < non_scrolling_squashed_layers_.size(); ++i) {
+ if (non_scrolling_squashed_layers_[i].paint_layer == &layer) {
+ non_scrolling_squashed_layers_.EraseAt(i);
+ return;
+ }
+ }
+ for (wtf_size_t i = 0; i < squashed_layers_in_scrolling_contents_.size();
+ ++i) {
+ if (squashed_layers_in_scrolling_contents_[i].paint_layer == &layer) {
+ squashed_layers_in_scrolling_contents_.EraseAt(i);
+ return;
+ }
}
// Assert on incorrect mappings between layers and groups
- DCHECK_LT(layer_index, squashed_layers_.size());
- if (layer_index == squashed_layers_.size())
- return;
-
- squashed_layers_.EraseAt(layer_index);
+ NOTREACHED();
}
-#if DCHECK_IS_ON()
-bool CompositedLayerMapping::VerifyLayerInSquashingVector(
- const PaintLayer* layer) {
- for (wtf_size_t layer_index = 0; layer_index < squashed_layers_.size();
- ++layer_index) {
- if (squashed_layers_[layer_index].paint_layer == layer)
+static bool LayerInSquashedLayersVector(
+ const Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ const PaintLayer& layer) {
+ for (auto& squashed_layer : squashed_layers) {
+ if (squashed_layer.paint_layer == &layer)
return true;
}
-
return false;
}
+
+#if DCHECK_IS_ON()
+void CompositedLayerMapping::AssertInSquashedLayersVector(
+ const PaintLayer& squashed_layer) const {
+ auto* in = &non_scrolling_squashed_layers_;
+ auto* out = &squashed_layers_in_scrolling_contents_;
+ if (MayBeSquashedIntoScrollingContents(squashed_layer))
+ std::swap(in, out);
+ DCHECK(LayerInSquashedLayersVector(*in, squashed_layer));
+ DCHECK(!LayerInSquashedLayersVector(*out, squashed_layer));
+}
#endif
+static void RemoveExtraSquashedLayers(
+ Vector<GraphicsLayerPaintInfo>& squashed_layers,
+ wtf_size_t new_count,
+ Vector<PaintLayer*>& layers_needing_paint_invalidation) {
+ DCHECK_GE(squashed_layers.size(), new_count);
+ if (squashed_layers.size() == new_count)
+ return;
+ for (auto i = new_count; i < squashed_layers.size(); i++)
+ layers_needing_paint_invalidation.push_back(squashed_layers[i].paint_layer);
+ squashed_layers.Shrink(new_count);
+}
+
void CompositedLayerMapping::FinishAccumulatingSquashingLayers(
- wtf_size_t next_squashed_layer_index,
+ wtf_size_t new_non_scrolling_squashed_layer_count,
+ wtf_size_t new_squashed_layer_in_scrolling_contents_count,
Vector<PaintLayer*>& layers_needing_paint_invalidation) {
- if (next_squashed_layer_index < squashed_layers_.size()) {
- // Any additional squashed Layers in the array no longer belong here, but
- // they might have been added already at an earlier index. Clear pointers on
- // those that do not appear in the valid set before removing all the extra
- // entries.
- for (wtf_size_t i = next_squashed_layer_index; i < squashed_layers_.size();
- ++i) {
- if (InvalidateLayerIfNoPrecedingEntry(i)) {
- squashed_layers_[i].paint_layer->SetGroupedMapping(
- nullptr, PaintLayer::kDoNotInvalidateLayerAndRemoveFromMapping);
- squashed_layers_[i].paint_layer->SetLostGroupedMapping(true);
- }
- layers_needing_paint_invalidation.push_back(
- squashed_layers_[i].paint_layer);
+ wtf_size_t first_removed_layer = layers_needing_paint_invalidation.size();
+ RemoveExtraSquashedLayers(non_scrolling_squashed_layers_,
+ new_non_scrolling_squashed_layer_count,
+ layers_needing_paint_invalidation);
+ RemoveExtraSquashedLayers(squashed_layers_in_scrolling_contents_,
+ new_squashed_layer_in_scrolling_contents_count,
+ layers_needing_paint_invalidation);
+ for (auto i = first_removed_layer;
+ i < layers_needing_paint_invalidation.size(); i++) {
+ PaintLayer* layer = layers_needing_paint_invalidation[i];
+ // Deal with layers that are no longer squashed. Need to check both vectors
+ // to exclude the layers that are still squashed. A layer may change from
+ // scrolling to non-scrolling or vice versa and still be squashed.
+ if (!LayerInSquashedLayersVector(non_scrolling_squashed_layers_, *layer) &&
+ !LayerInSquashedLayersVector(squashed_layers_in_scrolling_contents_,
+ *layer)) {
+ Compositor()->PaintInvalidationOnCompositingChange(layer);
+ layer->SetGroupedMapping(
+ nullptr, PaintLayer::kDoNotInvalidateLayerAndRemoveFromMapping);
+ layer->SetLostGroupedMapping(true);
}
-
- squashed_layers_.EraseAt(
- next_squashed_layer_index,
- squashed_layers_.size() - next_squashed_layer_index);
}
}
@@ -2255,12 +2288,10 @@ String CompositedLayerMapping::DebugName(
String name;
if (graphics_layer == graphics_layer_.get()) {
name = owning_layer_.DebugName();
- } else if (graphics_layer == squashing_containment_layer_.get()) {
- name = "Squashing Containment Layer";
- } else if (graphics_layer == squashing_layer_.get()) {
+ } else if (graphics_layer == non_scrolling_squashing_layer_.get()) {
name = "Squashing Layer (first squashed layer: " +
- (squashed_layers_.size() > 0
- ? squashed_layers_[0].paint_layer->DebugName()
+ (non_scrolling_squashed_layers_.size() > 0
+ ? non_scrolling_squashed_layers_[0].paint_layer->DebugName()
: "") +
")";
} else if (graphics_layer == foreground_layer_.get()) {
@@ -2275,8 +2306,6 @@ String CompositedLayerMapping::DebugName(
name = "Scroll Corner Layer";
} else if (graphics_layer == overflow_controls_host_layer_.get()) {
name = "Overflow Controls Host Layer";
- } else if (graphics_layer == scrolling_layer_.get()) {
- name = "Scrolling Layer";
} else if (graphics_layer == scrolling_contents_layer_.get()) {
name = "Scrolling Contents Layer";
} else if (graphics_layer == decoration_outline_layer_.get()) {