Commit c6410dbb authored by Vladimir Levin's avatar Vladimir Levin Committed by Commit Bot

content-visibility: Ensure to restore compositing update recursion properly.

If, for any reason, we should have recursed into a subtree for a
compositing update but it was prevented by the display lock, then we
have to restore this state so that we can recurse later.

This is a real DCHECK that I have seen, and also
is a speculative fix for the referenced bug.

R=chrishtr@chromium.org

Bug: 1133244
Change-Id: I5adfa04563d94702fa1b38dd2753e76e2a86e317
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2453790
Commit-Queue: vmpstr <vmpstr@chromium.org>
Reviewed-by: default avatarChris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815123}
parent 5a34d8ec
...@@ -238,6 +238,9 @@ void CompositingRequirementsUpdater::Update( ...@@ -238,6 +238,9 @@ void CompositingRequirementsUpdater::Update(
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
static void CheckSubtreeHasNoCompositing(PaintLayer* layer) { static void CheckSubtreeHasNoCompositing(PaintLayer* layer) {
if (layer->GetLayoutObject().ChildPrePaintBlockedByDisplayLock())
return;
PaintLayerPaintOrderIterator iterator(*layer, kAllChildren); PaintLayerPaintOrderIterator iterator(*layer, kAllChildren);
while (PaintLayer* cur_layer = iterator.Next()) { while (PaintLayer* cur_layer = iterator.Next()) {
DCHECK(cur_layer->GetCompositingState() == kNotComposited); DCHECK(cur_layer->GetCompositingState() == kNotComposited);
...@@ -422,14 +425,15 @@ void CompositingRequirementsUpdater::UpdateRecursive( ...@@ -422,14 +425,15 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// e.g. change of stacking order) // e.g. change of stacking order)
bool recursion_blocked_by_display_lock = bool recursion_blocked_by_display_lock =
layer->GetLayoutObject().ChildPrePaintBlockedByDisplayLock(); layer->GetLayoutObject().ChildPrePaintBlockedByDisplayLock();
bool skip_children = bool skip_children_ignoring_display_lock =
recursion_blocked_by_display_lock ||
(!layer->DescendantHasDirectOrScrollingCompositingReason() && (!layer->DescendantHasDirectOrScrollingCompositingReason() &&
!needs_recursion_for_composited_scrolling_plus_fixed_or_sticky && !needs_recursion_for_composited_scrolling_plus_fixed_or_sticky &&
!needs_recursion_for_out_of_flow_descendant && !needs_recursion_for_out_of_flow_descendant &&
layer->GetLayoutObject().ShouldClipOverflowAlongEitherAxis() && layer->GetLayoutObject().ShouldClipOverflowAlongEitherAxis() &&
!layer->HasCompositingDescendant() && !layer->HasCompositingDescendant() &&
!layer->DescendantMayNeedCompositingRequirementsUpdate()); !layer->DescendantMayNeedCompositingRequirementsUpdate());
bool skip_children =
recursion_blocked_by_display_lock || skip_children_ignoring_display_lock;
if (!skip_children) { if (!skip_children) {
PaintLayerPaintOrderIterator iterator(*layer, kNegativeZOrderChildren); PaintLayerPaintOrderIterator iterator(*layer, kNegativeZOrderChildren);
...@@ -496,7 +500,7 @@ void CompositingRequirementsUpdater::UpdateRecursive( ...@@ -496,7 +500,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
} }
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
if (skip_children && !recursion_blocked_by_display_lock) if (skip_children)
CheckSubtreeHasNoCompositing(layer); CheckSubtreeHasNoCompositing(layer);
#endif #endif
...@@ -615,11 +619,11 @@ void CompositingRequirementsUpdater::UpdateRecursive( ...@@ -615,11 +619,11 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// 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.
layer->SetCompositingReasons(reasons_to_composite); layer->SetCompositingReasons(reasons_to_composite);
// If we've skipped recursing down to children but children needed an // If we've skipped recursing down to children, but we would have recursed if
// update, remember this on the display lock context, so that we can restore // it were not for the display lock, remember this on the display lock
// the dirty bit when the lock is unlocked. // context, so that we can restore the dirty bit and cause recursion when the
if (layer->DescendantMayNeedCompositingRequirementsUpdate() && // lock is unlocked.
skip_children) { if (skip_children && !skip_children_ignoring_display_lock) {
auto* context = layer->GetLayoutObject().GetDisplayLockContext(); auto* context = layer->GetLayoutObject().GetDisplayLockContext();
DCHECK(recursion_blocked_by_display_lock); DCHECK(recursion_blocked_by_display_lock);
DCHECK(context); DCHECK(context);
......
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