diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc | 112 |
1 files changed, 68 insertions, 44 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc index 1128e3f3cf1..f1c2dfea9dd 100644 --- a/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc +++ b/chromium/third_party/blink/renderer/core/layout/layout_box_model_object.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/html/html_body_element.h" @@ -39,7 +40,7 @@ #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/style/shadow_list.h" -#include "third_party/blink/renderer/platform/length_functions.h" +#include "third_party/blink/renderer/platform/geometry/length_functions.h" #include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h" #include "third_party/blink/renderer/platform/transforms/transform_state.h" @@ -97,18 +98,30 @@ bool LayoutBoxModelObject::UsesCompositedScrolling() const { } BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation( - uint32_t* reasons) const { - bool has_custom_scrollbars = false; + uint32_t* main_thread_scrolling_reasons) const { + bool may_have_scrolling_layers_without_scrolling = IsLayoutView(); + const auto* scrollable_area = GetScrollableArea(); + bool scrolls_overflow = scrollable_area && scrollable_area->ScrollsOverflow(); + if (!scrolls_overflow && !may_have_scrolling_layers_without_scrolling) + return kBackgroundPaintInGraphicsLayer; + + // If we care about LCD text, paint root backgrounds into scrolling contents + // layer even if style suggests otherwise. (For non-root scrollers, we just + // avoid compositing - see PLSA::ComputeNeedsCompositedScrolling.) + if (IsLayoutView()) { + DCHECK(Layer()->Compositor()); + if (!Layer()->Compositor()->PreferCompositingToLCDTextEnabled()) + return kBackgroundPaintInScrollingContents; + } + // TODO(flackr): Detect opaque custom scrollbars which would cover up a // border-box background. - if (PaintLayerScrollableArea* scrollable_area = GetScrollableArea()) { - if ((scrollable_area->HorizontalScrollbar() && - scrollable_area->HorizontalScrollbar()->IsCustomScrollbar()) || - (scrollable_area->VerticalScrollbar() && - scrollable_area->VerticalScrollbar()->IsCustomScrollbar())) { - has_custom_scrollbars = true; - } - } + bool has_custom_scrollbars = + scrollable_area && + ((scrollable_area->HorizontalScrollbar() && + scrollable_area->HorizontalScrollbar()->IsCustomScrollbar()) || + (scrollable_area->VerticalScrollbar() && + scrollable_area->VerticalScrollbar()->IsCustomScrollbar())); // TODO(flackr): When we correctly clip the scrolling contents layer we can // paint locally equivalent backgrounds into it. https://crbug.com/645957 @@ -119,8 +132,10 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation( // painting into the composited scrolling contents layer. // https://crbug.com/646464 if (StyleRef().BoxShadow()) { - if (reasons) - *reasons |= MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer; + if (main_thread_scrolling_reasons) { + *main_thread_scrolling_reasons |= + MainThreadScrollingReason::kHasBoxShadowFromNonRootLayer; + } return kBackgroundPaintInGraphicsLayer; } @@ -144,13 +159,17 @@ BackgroundPaintLocation LayoutBoxModelObject::GetBackgroundPaintLocation( if (clip == EFillBox::kBorder) { if (!has_custom_scrollbars && (StyleRef().BorderTopWidth() == 0 || - !ResolveColor(GetCSSPropertyBorderTopColor()).HasAlpha()) && + (!ResolveColor(GetCSSPropertyBorderTopColor()).HasAlpha() && + StyleRef().BorderTopStyle() == EBorderStyle::kSolid)) && (StyleRef().BorderLeftWidth() == 0 || - !ResolveColor(GetCSSPropertyBorderLeftColor()).HasAlpha()) && + (!ResolveColor(GetCSSPropertyBorderLeftColor()).HasAlpha() && + StyleRef().BorderLeftStyle() == EBorderStyle::kSolid)) && (StyleRef().BorderRightWidth() == 0 || - !ResolveColor(GetCSSPropertyBorderRightColor()).HasAlpha()) && + (!ResolveColor(GetCSSPropertyBorderRightColor()).HasAlpha() && + StyleRef().BorderRightStyle() == EBorderStyle::kSolid)) && (StyleRef().BorderBottomWidth() == 0 || - !ResolveColor(GetCSSPropertyBorderBottomColor()).HasAlpha())) { + (!ResolveColor(GetCSSPropertyBorderBottomColor()).HasAlpha() && + StyleRef().BorderBottomStyle() == EBorderStyle::kSolid))) { continue; } // If we have an opaque background color only, we can safely paint it @@ -268,7 +287,7 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff, (StyleRef().OriginalDisplay() == EDisplay::kInlineBlock)) && ((old_style->OriginalDisplay() == EDisplay::kBlock) || (old_style->OriginalDisplay() == EDisplay::kInlineBlock))) - Parent()->SetNeedsLayout(LayoutInvalidationReason::kChildChanged, + Parent()->SetNeedsLayout(layout_invalidation_reason::kChildChanged, kMarkContainerChain); PaintLayerType type = LayerTypeRequired(); @@ -298,7 +317,7 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff, SetChildNeedsLayout(); if (had_transform_related_property) { SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation( - LayoutInvalidationReason::kStyleChange); + layout_invalidation_reason::kStyleChange); } if (!NeedsLayout()) { // FIXME: We should call a specialized version of this function. @@ -349,22 +368,21 @@ void LayoutBoxModelObject::StyleDidChange(StyleDifference diff, } // The used style for body background may change due to computed style change - // on the document element because of background stealing. - // Refer to backgroundStolenForBeingBody() and - // http://www.w3.org/TR/css3-background/#body-background for more info. + // on the document element because of change of BackgroundTransfersToView() + // which depends on the document element style. if (IsDocumentElement()) { - HTMLBodyElement* body = GetDocument().FirstBodyElement(); - LayoutObject* body_layout = body ? body->GetLayoutObject() : nullptr; - if (body_layout && body_layout->IsBoxModelObject()) { - bool new_stole_body_background = - ToLayoutBoxModelObject(body_layout) - ->BackgroundStolenForBeingBody(Style()); - bool old_stole_body_background = - old_style && ToLayoutBoxModelObject(body_layout) - ->BackgroundStolenForBeingBody(old_style); - if (new_stole_body_background != old_stole_body_background && - body_layout->Style() && body_layout->StyleRef().HasBackground()) { - body_layout->SetShouldDoFullPaintInvalidation(); + if (HTMLBodyElement* body = GetDocument().FirstBodyElement()) { + if (auto* body_object = body->GetLayoutObject()) { + if (body_object->IsBoxModelObject()) { + auto* body_box_model = ToLayoutBoxModelObject(body_object); + bool new_body_background_transfers = + body_box_model->BackgroundTransfersToView(Style()); + bool old_body_background_transfers = + old_style && body_box_model->BackgroundTransfersToView(old_style); + if (new_body_background_transfers != old_body_background_transfers && + body_object->Style() && body_object->StyleRef().HasBackground()) + body_object->SetBackgroundNeedsFullPaintInvalidation(); + } } } } @@ -1453,22 +1471,28 @@ void LayoutBoxModelObject::MoveChildrenTo( } } -bool LayoutBoxModelObject::BackgroundStolenForBeingBody( - const ComputedStyle* root_element_style) const { +bool LayoutBoxModelObject::BackgroundTransfersToView( + const ComputedStyle* document_element_style) const { + // In our painter implementation, ViewPainter instead of the painter of the + // layout object of the document element paints the view background. + if (IsDocumentElement()) + return true; + // http://www.w3.org/TR/css3-background/#body-background - // If the root element is <html> with no background, and a <body> child - // element exists, the root element steals the first <body> child element's - // background. + // If the document element is <html> with no background, and a <body> child + // element exists, the <body> element's background transfers to the document + // element which in turn transfers to the view in our painter implementation. if (!IsBody()) return false; - Element* root_element = GetDocument().documentElement(); - if (!IsHTMLHtmlElement(root_element)) + Element* document_element = GetDocument().documentElement(); + if (!IsHTMLHtmlElement(document_element)) return false; - if (!root_element_style) - root_element_style = root_element->EnsureComputedStyle(); - if (root_element_style->HasBackground()) + if (!document_element_style) + document_element_style = document_element->GetComputedStyle(); + DCHECK(document_element_style); + if (document_element_style->HasBackground()) return false; if (GetNode() != GetDocument().FirstBodyElement()) |