diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc index eb8bc29eb7f..4e47cecad90 100644 --- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc +++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_assigner.cc @@ -28,6 +28,7 @@ #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/layout/layout_embedded_content.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/page/page.h" @@ -54,9 +55,10 @@ void CompositingLayerAssigner::Assign( SquashingState squashing_state; AssignLayersToBackingsInternal(update_root, squashing_state, layers_needing_paint_invalidation); - if (squashing_state.has_most_recent_mapping) { + if (squashing_state.most_recent_mapping) { squashing_state.most_recent_mapping->FinishAccumulatingSquashingLayers( - squashing_state.next_squashed_layer_index, + squashing_state.next_non_scrolling_squashed_layer_index, + squashing_state.next_squashed_layer_in_scrolling_contents_index, layers_needing_paint_invalidation); } } @@ -64,19 +66,29 @@ void CompositingLayerAssigner::Assign( void CompositingLayerAssigner::SquashingState:: UpdateSquashingStateForNewMapping( CompositedLayerMapping* new_composited_layer_mapping, - bool has_new_composited_layer_mapping, Vector<PaintLayer*>& layers_needing_paint_invalidation) { // The most recent backing is done accumulating any more squashing layers. - if (has_most_recent_mapping) { + if (most_recent_mapping) { most_recent_mapping->FinishAccumulatingSquashingLayers( - next_squashed_layer_index, layers_needing_paint_invalidation); + next_non_scrolling_squashed_layer_index, + next_squashed_layer_in_scrolling_contents_index, + layers_needing_paint_invalidation); } - next_squashed_layer_index = 0; + next_non_scrolling_squashed_layer_index = 0; + next_squashed_layer_in_scrolling_contents_index = 0; bounding_rect = IntRect(); most_recent_mapping = new_composited_layer_mapping; - has_most_recent_mapping = has_new_composited_layer_mapping; have_assigned_backings_to_entire_squashing_layer_subtree = false; + // We may squash layers with CompositingReason::kOverflowScrollingParent into + // scrolling contents. These layers are stacked, and scrolled by a + // non-stacking-context scroller. See CompositingReasonFinder. + next_layer_may_squash_into_scrolling_contents = + most_recent_mapping && + most_recent_mapping->OwningLayer().NeedsCompositedScrolling() && + !most_recent_mapping->OwningLayer() + .GetLayoutObject() + .IsStackingContext(); } bool CompositingLayerAssigner::SquashingWouldExceedSparsityTolerance( @@ -133,7 +145,7 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing( if (!squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree) return SquashingDisallowedReason::kWouldBreakPaintOrder; - DCHECK(squashing_state.has_most_recent_mapping); + DCHECK(squashing_state.most_recent_mapping); const PaintLayer& squashing_layer = squashing_state.most_recent_mapping->OwningLayer(); @@ -150,22 +162,31 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing( kSquashingLayoutEmbeddedContentIsDisallowed; } - if (SquashingWouldExceedSparsityTolerance(layer, squashing_state)) - return SquashingDisallowedReason::kSquashingSparsityExceeded; + // The layer may squash into scrolling contents if the squashing layer allows, + // and it's scrolled and clipped by the squashing layer. + bool may_squash_into_scrolling_contents = + squashing_state.next_layer_may_squash_into_scrolling_contents && + layer->AncestorScrollingLayer() == &squashing_layer && + layer->ClippingContainer() == &squashing_layer.GetLayoutObject(); + if (!may_squash_into_scrolling_contents) { + if (SquashingWouldExceedSparsityTolerance(layer, squashing_state)) + return SquashingDisallowedReason::kSquashingSparsityExceeded; + + if (layer->ClippingContainer() != squashing_layer.ClippingContainer() && + !squashing_layer.GetCompositedLayerMapping() + ->ContainingSquashedLayerInSquashingLayer( + layer->ClippingContainer(), + squashing_state.next_non_scrolling_squashed_layer_index)) + return SquashingDisallowedReason::kClippingContainerMismatch; + + if (layer->ScrollsWithRespectTo(&squashing_layer)) + return SquashingDisallowedReason::kScrollsWithRespectToSquashingLayer; + } if (layer->GetLayoutObject().StyleRef().HasBlendMode() || squashing_layer.GetLayoutObject().StyleRef().HasBlendMode()) return SquashingDisallowedReason::kSquashingBlendingIsDisallowed; - if (layer->ClippingContainer() != squashing_layer.ClippingContainer() && - !squashing_layer.GetCompositedLayerMapping()->ContainingSquashedLayer( - layer->ClippingContainer(), - squashing_state.next_squashed_layer_index)) - return SquashingDisallowedReason::kClippingContainerMismatch; - - if (layer->ScrollsWithRespectTo(&squashing_layer)) - return SquashingDisallowedReason::kScrollsWithRespectToSquashingLayer; - if (layer->OpacityAncestor() != squashing_layer.OpacityAncestor()) return SquashingDisallowedReason::kOpacityAncestorMismatch; @@ -227,11 +248,12 @@ void CompositingLayerAssigner::UpdateSquashingAssignment( // A layer that is squashed with other layers cannot have its own // CompositedLayerMapping. DCHECK(!layer->HasCompositedLayerMapping()); - DCHECK(squashing_state.has_most_recent_mapping); + DCHECK(squashing_state.most_recent_mapping); bool changed_squashing_layer = squashing_state.most_recent_mapping->UpdateSquashingLayerAssignment( - layer, squashing_state.next_squashed_layer_index); + *layer, squashing_state.next_non_scrolling_squashed_layer_index, + squashing_state.next_squashed_layer_in_scrolling_contents_index); if (!changed_squashing_layer) return; @@ -281,7 +303,10 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal( layer->SetCompositingReasons(layer->GetCompositingReasons() | CompositingReason::kSquashingDisallowed); layer->SetSquashingDisallowedReasons(reasons_preventing_squashing); + squashing_state.next_layer_may_squash_into_scrolling_contents = false; } + } else { + squashing_state.next_layer_may_squash_into_scrolling_contents = false; } CompositingStateTransitionType composited_layer_update = @@ -315,11 +340,17 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal( (composited_layer_update == kNoCompositingStateChange && layer->GroupedMapping()); if (layer_is_squashed) { - squashing_state.next_squashed_layer_index++; - IntRect layer_bounds = layer->ClippedAbsoluteBoundingBox(); - squashing_state.total_area_of_squashed_rects += - layer_bounds.Size().Area(); - squashing_state.bounding_rect.Unite(layer_bounds); + if (layer->AncestorScrollingLayer() == + &squashing_state.most_recent_mapping->OwningLayer()) { + squashing_state.next_squashed_layer_in_scrolling_contents_index++; + } else { + squashing_state.next_non_scrolling_squashed_layer_index++; + squashing_state.next_layer_may_squash_into_scrolling_contents = false; + IntRect layer_bounds = layer->ClippedAbsoluteBoundingBox(); + squashing_state.total_area_of_squashed_rects += + layer_bounds.Size().Area(); + squashing_state.bounding_rect.Unite(layer_bounds); + } } } @@ -337,8 +368,7 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal( layer->GetCompositingState() == kPaintsIntoOwnBacking) { DCHECK(!RequiresSquashing(layer->GetCompositingReasons())); squashing_state.UpdateSquashingStateForNewMapping( - layer->GetCompositedLayerMapping(), layer->HasCompositedLayerMapping(), - layers_needing_paint_invalidation); + layer->GetCompositedLayerMapping(), layers_needing_paint_invalidation); } if (layer->StackingDescendantNeedsCompositingLayerAssignment()) { @@ -351,12 +381,22 @@ void CompositingLayerAssigner::AssignLayersToBackingsInternal( } if (layer->NeedsCompositingLayerAssignment()) { - if (squashing_state.has_most_recent_mapping && + if (squashing_state.most_recent_mapping && &squashing_state.most_recent_mapping->OwningLayer() == layer) { squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree = 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(); } |