diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/layout_object.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/layout/layout_object.cc | 152 |
1 files changed, 107 insertions, 45 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_object.cc b/chromium/third_party/blink/renderer/core/layout/layout_object.cc index 688121f8ab6..3827e90b420 100644 --- a/chromium/third_party/blink/renderer/core/layout/layout_object.cc +++ b/chromium/third_party/blink/renderer/core/layout/layout_object.cc @@ -80,10 +80,6 @@ #include "third_party/blink/renderer/core/layout/layout_list_marker.h" #include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" -#include "third_party/blink/renderer/core/layout/layout_table_caption.h" -#include "third_party/blink/renderer/core/layout/layout_table_cell.h" -#include "third_party/blink/renderer/core/layout/layout_table_col.h" -#include "third_party/blink/renderer/core/layout/layout_table_row.h" #include "third_party/blink/renderer/core/layout/layout_text_fragment.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/layout_view.h" @@ -245,24 +241,16 @@ LayoutObject* LayoutObject::CreateObject(Element* element, return LayoutObjectFactory::CreateBlockFlow(*element, style, legacy); case EDisplay::kTable: case EDisplay::kInlineTable: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTable(element); + return LayoutObjectFactory::CreateTable(*element, style, legacy); case EDisplay::kTableRowGroup: case EDisplay::kTableHeaderGroup: case EDisplay::kTableFooterGroup: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTableSection(element); + return LayoutObjectFactory::CreateTableSection(*element, style, legacy); case EDisplay::kTableRow: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTableRow(element); + return LayoutObjectFactory::CreateTableRow(*element, style, legacy); case EDisplay::kTableColumnGroup: case EDisplay::kTableColumn: - UseCounter::Count(element->GetDocument(), - WebFeature::kLegacyLayoutByTable); - return new LayoutTableCol(element); + return LayoutObjectFactory::CreateTableColumn(*element, style, legacy); case EDisplay::kTableCell: return LayoutObjectFactory::CreateTableCell(*element, style, legacy); case EDisplay::kTableCaption: @@ -431,7 +419,7 @@ void LayoutObject::AddChild(LayoutObject* new_child, !after_child->IsBeforeContent()) { table = after_child; } else { - table = LayoutTable::CreateAnonymousWithParent(this); + table = LayoutObjectFactory::CreateAnonymousTableWithParent(*this); children->InsertChildNode(this, table, before_child); } table->AddChild(new_child); @@ -845,7 +833,6 @@ LayoutBox* LayoutObject::EnclosingBox() const { } LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const { - DCHECK(IsInline()); for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) { if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) { // Skip |LayoutFlowThread| because it is skipped when finding the first @@ -859,7 +846,6 @@ LayoutBlockFlow* LayoutObject::RootInlineFormattingContext() const { } LayoutBlockFlow* LayoutObject::FragmentItemsContainer() const { - DCHECK(IsInline()); for (LayoutObject* parent = Parent(); parent; parent = parent->Parent()) { if (auto* block_flow = DynamicTo<LayoutBlockFlow>(parent)) return block_flow; @@ -937,7 +923,10 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) { // Positioned objects always have self-painting layers and are safe to use as // relayout boundaries. bool is_svg_root = object->IsSVGRoot(); - if (!object->IsPositioned() && !is_svg_root) + bool has_self_painting_layer = + object->HasLayer() && + ToLayoutBoxModelObject(object)->HasSelfPaintingLayer(); + if (!has_self_painting_layer && !is_svg_root) return false; // LayoutInline can't be relayout roots since LayoutBlockFlow is responsible @@ -989,11 +978,12 @@ static inline bool ObjectIsRelayoutBoundary(const LayoutObject* object) { // In LayoutNG, if box has any OOF descendants, they are propagated to // parent. Therefore, we must mark parent chain for layout. - if (layout_box->GetCachedLayoutResult() && - layout_box->GetCachedLayoutResult() - ->PhysicalFragment() - .HasOutOfFlowPositionedDescendants()) - return false; + if (const NGLayoutResult* layouot_result = + layout_box->GetCachedLayoutResult()) { + if (layouot_result->PhysicalFragment() + .HasOutOfFlowPositionedDescendants()) + return false; + } } if (object->IsTextControl()) @@ -1290,11 +1280,6 @@ inline void LayoutObject::InvalidateContainerIntrinsicLogicalWidths() { LayoutObject* LayoutObject::ContainerForAbsolutePosition( AncestorSkipInfo* skip_info) const { return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) { - if (!candidate->StyleRef().CanContainAbsolutePositionObjects() && - candidate->ShouldApplyLayoutContainment()) { - UseCounter::Count(candidate->GetDocument(), - WebFeature::kCSSContainLayoutPositionedDescendants); - } return candidate->CanContainAbsolutePositionObjects(); }); } @@ -1303,12 +1288,6 @@ LayoutObject* LayoutObject::ContainerForFixedPosition( AncestorSkipInfo* skip_info) const { DCHECK(!IsText()); return FindAncestorByPredicate(this, skip_info, [](LayoutObject* candidate) { - if (!candidate->StyleRef().CanContainFixedPositionObjects( - candidate->IsDocumentElement()) && - candidate->ShouldApplyLayoutContainment()) { - UseCounter::Count(candidate->GetDocument(), - WebFeature::kCSSContainLayoutPositionedDescendants); - } return candidate->CanContainFixedPositionObjects(); }); } @@ -1358,6 +1337,13 @@ LayoutBlock* LayoutObject::ContainingBlock(AncestorSkipInfo* skip_info) const { return DynamicTo<LayoutBlock>(object); } +LayoutObject* LayoutObject::NonAnonymousAncestor() const { + LayoutObject* ancestor = Parent(); + while (ancestor && ancestor->IsAnonymous()) + ancestor = ancestor->Parent(); + return ancestor; +} + LayoutBlock* LayoutObject::FindNonAnonymousContainingBlock( LayoutObject* container, AncestorSkipInfo* skip_info) { @@ -1397,6 +1383,11 @@ bool LayoutObject::ComputeIsFixedContainer(const ComputedStyle* style) const { if (IsA<LayoutView>(this) || IsSVGForeignObject() || IsTextControl()) return true; // https://www.w3.org/TR/css-transforms-1/#containing-block-for-all-descendants + + if (RuntimeEnabledFeatures::TransformInteropEnabled() && + style->TransformStyle3D() == ETransformStyle3D::kPreserve3d) + return true; + if (style->HasTransformRelatedProperty()) { if (!IsInline() || IsAtomicInlineLevel()) return true; @@ -2051,10 +2042,18 @@ StyleDifference LayoutObject::AdjustStyleDifference( (IsText() && !IsBR() && ToLayoutText(this)->HasInlineFragments()) || (IsSVG() && StyleRef().SvgStyle().IsFillColorCurrentColor()) || (IsSVG() && StyleRef().SvgStyle().IsStrokeColorCurrentColor()) || - IsListMarker() || IsDetailsMarker() || IsMathML()) + IsListMarkerForNormalContent() || IsDetailsMarker() || IsMathML()) diff.SetNeedsPaintInvalidation(); } + // TODO(1088373): Pixel_WebGLHighToLowPower fails without this. This isn't the + // right way to ensure GPU switching. Investigate and do it in the right way. + if (RuntimeEnabledFeatures::CSSReducedFontLoadingInvalidationsEnabled() && + !diff.NeedsPaintInvalidation() && IsLayoutView() && Style() && + !Style()->GetFont().IsFallbackValid()) { + diff.SetNeedsPaintInvalidation(); + } + // The answer to layerTypeRequired() for plugins, iframes, and canvas can // change without the actual style changing, since it depends on whether we // decide to composite these elements. When the/ layer status of one of these @@ -2383,8 +2382,9 @@ void LayoutObject::StyleWillChange(StyleDifference diff, bool visibility_changed = style_->Visibility() != new_style.Visibility(); // If our z-index changes value or our visibility changes, // we need to dirty our stacking context's z-order list. - if (visibility_changed || style_->ZIndex() != new_style.ZIndex() || - style_->IsStackingContext() != new_style.IsStackingContext()) { + if (visibility_changed || + style_->EffectiveZIndex() != new_style.EffectiveZIndex() || + IsStackingContext(*style_) != IsStackingContext(new_style)) { GetDocument().SetAnnotatedRegionsDirty(true); if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) { if (GetNode()) @@ -2540,6 +2540,20 @@ void LayoutObject::StyleDidChange(StyleDifference diff, } } + if (HasHiddenBackface()) { + bool preserve_3d = + (Parent() && Parent()->StyleRef().UsedTransformStyle3D() == + ETransformStyle3D::kPreserve3d); + if (style_->HasTransform() || preserve_3d) { + UseCounter::Count(GetDocument(), + WebFeature::kHiddenBackfaceWithPossible3D); + } + if (preserve_3d) { + UseCounter::Count(GetDocument(), + WebFeature::kHiddenBackfaceWithPreserve3D); + } + } + // First assume the outline will be affected. It may be updated when we know // it's not affected. bool has_outline = style_->HasOutline(); @@ -2980,8 +2994,13 @@ void LayoutObject::GetTransformFromContainer( transform.PostTranslate(offset_in_container.left.ToFloat(), offset_in_container.top.ToFloat()); - if (container_object && container_object->HasLayer() && - container_object->StyleRef().HasPerspective()) { + bool has_perspective = container_object && container_object->HasLayer() && + container_object->StyleRef().HasPerspective(); + if (has_perspective && RuntimeEnabledFeatures::TransformInteropEnabled() && + container_object != NonAnonymousAncestor()) + has_perspective = false; + + if (has_perspective) { // Perspective on the container affects us, so we have to factor it in here. DCHECK(container_object->HasLayer()); FloatPoint perspective_origin = @@ -3468,9 +3487,26 @@ void LayoutObject::DestroyAndCleanupAnonymousWrappers() { if (destroy_root_parent->IsLayoutFlowThread()) break; - if (destroy_root->PreviousSibling() || destroy_root->NextSibling()) - break; // Need to keep the anonymous parent, since it won't become empty - // by the removal of this LayoutObject. + // We need to keep the anonymous parent, if it won't become empty by the + // removal of this LayoutObject. + if (destroy_root->PreviousSibling()) + break; + if (const LayoutObject* sibling = destroy_root->NextSibling()) { + if (destroy_root->GetNode()) { + // When there are inline continuations, there may be multiple layout + // objects generated from the same node, and those are special. They + // will be removed as part of destroying |this|, in + // LayoutInline::WillBeDestroyed(). So if that's all we have left, we + // need to realize now that the anonymous containing block will become + // empty. So we have to destroy it. + while (sibling && sibling->GetNode() == destroy_root->GetNode()) + sibling = sibling->NextSibling(); + } + if (sibling) + break; + DCHECK(destroy_root->IsLayoutInline()); + DCHECK(ToLayoutInline(destroy_root)->Continuation()); + } } destroy_root->Destroy(); @@ -3709,7 +3745,7 @@ bool LayoutObject::WillRenderImage() { return false; // We will not render a new image when ExecutionContext is paused - if (GetDocument().IsContextPaused()) + if (GetDocument().GetExecutionContext()->IsContextPaused()) return false; // Suspend animations when the page is not visible. @@ -3728,6 +3764,18 @@ bool LayoutObject::GetImageAnimationPolicy(ImageAnimationPolicy& policy) { return true; } +bool LayoutObject::IsInsideListMarker() const { + return (IsListMarkerForNormalContent() && + ToLayoutListMarker(this)->IsInside()) || + IsInsideListMarkerForCustomContent(); +} + +bool LayoutObject::IsOutsideListMarker() const { + return (IsListMarkerForNormalContent() && + !ToLayoutListMarker(this)->IsInside()) || + IsOutsideListMarkerForCustomContent(); +} + int LayoutObject::CaretMinOffset() const { return 0; } @@ -4093,6 +4141,20 @@ bool LayoutObject::PaintInvalidationStateIsDirty() const { } #endif +void LayoutObject::ClearPaintFlags() { + DCHECK_EQ(GetDocument().Lifecycle().GetState(), + DocumentLifecycle::kInPrePaint); + ClearPaintInvalidationFlags(); + bitfields_.SetNeedsPaintPropertyUpdate(false); + bitfields_.SetEffectiveAllowedTouchActionChanged(false); + + if (!PrePaintBlockedByDisplayLock(DisplayLockLifecycleTarget::kChildren)) { + bitfields_.SetDescendantNeedsPaintPropertyUpdate(false); + bitfields_.SetDescendantEffectiveAllowedTouchActionChanged(false); + bitfields_.ResetSubtreePaintPropertyUpdateReasons(); + } +} + bool LayoutObject::IsAllowedToModifyLayoutTreeStructure(Document& document) { return document.Lifecycle().StateAllowsLayoutTreeMutations(); } |