summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/paint
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/paint')
-rw-r--r--chromium/third_party/blink/renderer/core/paint/README.md7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.cc47
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.h2
10 files changed, 100 insertions, 45 deletions
diff --git a/chromium/third_party/blink/renderer/core/paint/README.md b/chromium/third_party/blink/renderer/core/paint/README.md
index 641f09eb8ec..0a3e2ed55b7 100644
--- a/chromium/third_party/blink/renderer/core/paint/README.md
+++ b/chromium/third_party/blink/renderer/core/paint/README.md
@@ -26,6 +26,13 @@ are treated in different ways during painting:
* Stacking contexts: elements with non-auto z-indices or other properties
that affect stacking e.g. transform, opacity, blend-mode.
+ * Replaced normal-flow stacking elements: [replaced elements](https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements)
+ that do not have non-auto z-index but are stacking contexts for
+ elements below them. Right now the only example is SVG <foreignObject>.
+ The difference between these elements and regular stacking contexts is
+ that they paint in the foreground phase of the painting algorithm
+ (as opposed to the positioned descendants phase).
+
* Elements that are not real stacking contexts but are treated as stacking
contexts but don't manage other stacked elements. Their z-ordering are
managed by real stacking contexts. They are positioned elements with
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter.cc b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
index 77ba7b05a8e..79cfaa28616 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_table.h"
#include "third_party/blink/renderer/core/layout/layout_theme.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h"
#include "third_party/blink/renderer/core/paint/adjust_paint_offset_scope.h"
#include "third_party/blink/renderer/core/paint/background_image_geometry.h"
#include "third_party/blink/renderer/core/paint/box_decoration_data.h"
@@ -19,6 +20,7 @@
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/scroll_recorder.h"
+#include "third_party/blink/renderer/core/paint/svg_foreign_object_painter.h"
#include "third_party/blink/renderer/core/paint/theme_painter.h"
#include "third_party/blink/renderer/platform/geometry/layout_point.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
@@ -42,9 +44,13 @@ void BoxPainter::PaintChildren(const PaintInfo& paint_info,
PaintInfo child_info(paint_info);
for (LayoutObject* child = layout_box_.SlowFirstChild(); child;
child = child->NextSibling()) {
- if (!child->IsBoxModelObject() ||
- !ToLayoutBoxModelObject(child)->HasSelfPaintingLayer())
+ if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
+ child->IsSVGForeignObject()) {
+ SVGForeignObjectPainter(ToLayoutSVGForeignObject(*child))
+ .PaintLayer(paint_info);
+ } else {
child->Paint(child_info, paint_offset);
+ }
}
}
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 c3cc47a03f4..217062ed40f 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
@@ -3368,19 +3368,27 @@ IntRect CompositedLayerMapping::RecomputeInterestRect(
LayoutRect graphics_layer_bounds_in_root_view_space(
graphics_layer_bounds_in_object_space);
- // MapToVisualRectInAncestorSpace is exclusive of the scroll and clip on the
- // ancestor, so we map to nullptr instead of |root_view| to include these.
anchor_layout_object->MapToVisualRectInAncestorSpace(
- nullptr, graphics_layer_bounds_in_root_view_space);
+ root_view, graphics_layer_bounds_in_root_view_space);
+
+ // In RLS, the root_view is scrolled. However, MapToVisualRectInAncestorSpace
+ // doesn't account for this scroll, since it earlies out as soon as we reach
+ // this ancestor. That is, it only maps to the space of the root_view, not
+ // accounting for the fact that the root_view itself can be scrolled. If the
+ // root_view is our anchor_layout_object, then this extra offset is counted in
+ // offset_from_anchor_layout_object. In other cases, we need to account for it
+ // here. Otherwise, the paint clip below might clip the whole (visible) rect
+ // out.
+ if (RuntimeEnabledFeatures::RootLayerScrollingEnabled() &&
+ root_view != anchor_layout_object) {
+ if (auto* scrollable_area = root_view->GetScrollableArea()) {
+ graphics_layer_bounds_in_root_view_space.MoveBy(
+ -scrollable_area->VisibleContentRect().Location());
+ }
+ }
- // MapToVisualRectInAncestorSpace will not clip if the anchor is the root
- // view, because the rect is assumed to already be in the clipped space of
- // the root view. We need to manually apply the root view's clip in this case.
FloatRect visible_content_rect(graphics_layer_bounds_in_root_view_space);
- if (anchor_layout_object == root_view ||
- !RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
- root_view->GetFrameView()->ClipPaintRect(&visible_content_rect);
- }
+ root_view->GetFrameView()->ClipPaintRect(&visible_content_rect);
FloatRect enclosing_graphics_layer_bounds(
EnclosingIntRect(graphics_layer_bounds));
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
index 95b7ed761bf..e17ae8d3414 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc
@@ -967,7 +967,10 @@ bool PaintLayerCompositor::CanBeComposited(const PaintLayer* layer) const {
return has_accelerated_compositing_ &&
(has_compositor_animation || !layer->SubtreeIsInvisible()) &&
layer->IsSelfPaintingLayer() &&
- !layer->GetLayoutObject().IsLayoutFlowThread();
+ !layer->GetLayoutObject().IsLayoutFlowThread() &&
+ // Don't composite <foreignObject> for the moment, to reduce
+ // instances of the "fundamental compositing bug" breaking content.
+ !layer->GetLayoutObject().IsSVGForeignObject();
}
// Return true if the given layer is a stacking context and has compositing
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
index 79c2117f843..6c4a1ad30e0 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -1856,16 +1856,6 @@ scoped_refptr<HitTestingTransformState> PaintLayer::CreateLocalTransformState(
ConvertToLayerCoords(root_layer, offset);
}
offset.MoveBy(translation_offset);
- // The location of a foreignObject element is added *after* transform, not
- // before (all SVG child elements have this behavior). Therefore, remove
- // the offset here to avoid applying it before the transform. It will be
- // added later.
- // TODO(chrishtr): this ugliness can be removed if we change the code to
- // to be based on PaintOffset rather than PaintLayer offsets, like the
- // paint code does. This is a larger effort though, that involves using
- // property trees to drive hit testing coordinate spaces.
- if (GetLayoutObject().IsSVGForeignObject())
- offset.MoveBy(-LayoutBoxLocation());
LayoutObject* container_layout_object =
container_layer ? &container_layer->GetLayoutObject() : nullptr;
@@ -1943,11 +1933,11 @@ PaintLayer* PaintLayer::HitTestLayer(
if (result.GetHitTestRequest().IgnoreClipping())
clip_behavior = kIgnoreOverflowClip;
- // Always send foreignObject PaintLayers through the "transform" code path,
- // even if they have no transform. This is in order to collect any ancestor
- // SVG transforms, including the SVG root to border box transform, which
- // are represented outside of the PaintLayer tree.
- bool use_transform = Transform() || GetLayoutObject().IsSVGForeignObject();
+ // We can only reach an SVG foreign object's PaintLayer from
+ // LayoutSVGForeignObject::NodeAtFloatPoint (because
+ // IsReplacedNormalFlowStacking() true for LayoutSVGForeignObject),
+ // where the hit_test_rect has already been transformed to local coordinates.
+ bool use_transform = Transform() && !GetLayoutObject().IsSVGForeignObject();
// Apply a transform if we have one.
if (use_transform && !applied_transform) {
@@ -1979,17 +1969,6 @@ PaintLayer* PaintLayer::HitTestLayer(
if (HitTestClippedOutByClipPath(root_layer, hit_test_location))
return nullptr;
- // TODO(chrishtr): this can have incorrect results for rects that are not
- // unit-sized due to use of Center().
- if (GetLayoutObject().IsSVGForeignObject() &&
- !GeometryMapper::PointVisibleInAncestorSpace(
- GetLayoutObject().FirstFragment().LocalBorderBoxProperties(),
- container_layer->GetLayoutObject()
- .FirstFragment()
- .LocalBorderBoxProperties(),
- FloatPoint(hit_test_location.BoundingBox().Center())))
- return nullptr;
-
// The natural thing would be to keep HitTestingTransformState on the stack,
// but it's big, so we heap-allocate.
scoped_refptr<HitTestingTransformState> local_transform_state;
@@ -2098,10 +2077,6 @@ PaintLayer* PaintLayer::HitTestLayer(
}
LayoutPoint offset = -LayoutBoxLocation();
- // See comment in CreateLocalTransformState. The code here is
- // where we re-add the location.
- if (root_layer->GetLayoutObject().IsSVGForeignObject())
- offset.MoveBy(root_layer->LayoutBoxLocation());
// Next we want to see if the mouse pos is inside the child LayoutObjects of
// the layer. Check every fragment in reverse order.
@@ -2315,6 +2290,14 @@ bool PaintLayer::HitTestContents(HitTestResult& result,
return true;
}
+bool PaintLayer::IsReplacedNormalFlowStacking() {
+ if (!GetLayoutObject().IsSVGForeignObject())
+ return false;
+ if (!GetLayoutObject().StyleRef().HasAutoZIndex())
+ return false;
+ return true;
+}
+
PaintLayer* PaintLayer::HitTestChildren(
ChildrenIteration childrento_visit,
PaintLayer* root_layer,
@@ -2334,6 +2317,10 @@ PaintLayer* PaintLayer::HitTestChildren(
childrento_visit);
while (PaintLayerStackingNode* child = iterator.Next()) {
PaintLayer* child_layer = child->Layer();
+
+ if (child_layer->IsReplacedNormalFlowStacking())
+ continue;
+
PaintLayer* hit_layer = nullptr;
HitTestResult temp_result(result.GetHitTestRequest(),
result.GetHitTestLocation());
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer.h b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
index 24a1578f33f..4bd4db980ac 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
@@ -1030,6 +1030,11 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool ShouldFragmentCompositedBounds(
const PaintLayer* compositing_layer = nullptr) const;
+ // See
+ // https://chromium.googlesource.com/chromium/src.git/+/master/third_party/blink/renderer/core/paint/README.md
+ // for the definition of a replaced normal-flow stacking element.
+ bool IsReplacedNormalFlowStacking();
+
private:
void SetNeedsCompositingInputsUpdateInternal();
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc
index 5eb8f0c3223..5e50057e5e4 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -983,6 +983,9 @@ PaintResult PaintLayerPainter::PaintChildren(
painting_info.GetGlobalPaintFlags()))
continue;
+ if (child->Layer()->IsReplacedNormalFlowStacking())
+ continue;
+
PaintLayerPaintingInfo child_painting_info = painting_info;
child_painting_info.scroll_offset_accumulation =
scroll_offset_accumulation_for_children;
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc
index aad110b234a..529a5525b10 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_container_painter.cc
@@ -6,11 +6,13 @@
#include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_container.h"
+#include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h"
#include "third_party/blink/renderer/core/layout/svg/layout_svg_viewport_container.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
#include "third_party/blink/renderer/core/paint/float_clip_recorder.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/paint/svg_foreign_object_painter.h"
#include "third_party/blink/renderer/core/paint/svg_paint_context.h"
#include "third_party/blink/renderer/core/svg/svg_svg_element.h"
#include "third_party/blink/renderer/platform/wtf/optional.h"
@@ -83,8 +85,11 @@ void SVGContainerPainter::Paint(const PaintInfo& paint_info) {
if (continue_rendering) {
for (LayoutObject* child = layout_svg_container_.FirstChild(); child;
child = child->NextSibling()) {
- if (!child->IsBoxModelObject() ||
- !ToLayoutBoxModelObject(child)->HasSelfPaintingLayer()) {
+ if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
+ child->IsSVGForeignObject()) {
+ SVGForeignObjectPainter(ToLayoutSVGForeignObject(*child))
+ .PaintLayer(paint_context.GetPaintInfo());
+ } else {
child->Paint(paint_context.GetPaintInfo(), IntPoint());
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc
index 3e8cc8eb07b..d78a5fa6162 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.cc
@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
+#include "third_party/blink/renderer/core/paint/paint_layer_painter.h"
#include "third_party/blink/renderer/core/paint/svg_paint_context.h"
#include "third_party/blink/renderer/platform/wtf/optional.h"
@@ -34,6 +35,34 @@ class BlockPainterDelegate : public LayoutBlock {
} // namespace
+void SVGForeignObjectPainter::PaintLayer(const PaintInfo& paint_info) {
+ if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled())
+ return;
+ if (paint_info.phase != PaintPhase::kForeground &&
+ paint_info.phase != PaintPhase::kSelection)
+ return;
+
+ // Early out in the case of trying to paint an image filter before
+ // pre-paint has finished.
+ if (!layout_svg_foreign_object_.FirstFragment().HasLocalBorderBoxProperties())
+ return;
+
+ // <foreignObject> is a replaced normal-flow stacking element.
+ // See IsReplacedNormalFlowStacking in paint_layer_painter.cc.
+ PaintLayerPaintingInfo layer_painting_info(
+ layout_svg_foreign_object_.Layer(),
+ // Reset to an infinite cull rect, for simplicity. Otherwise
+ // an adjustment would be needed for ancestor scrolling, and any
+ // SVG transforms would have to be taken into account. Further,
+ // cull rects under transform are intentionally reset to infinity,
+ // to improve cache invalidation performance in the pre-paint tree
+ // walk (see https://http://crrev.com/482854).
+ LayoutRect(LayoutRect::InfiniteIntRect()),
+ paint_info.GetGlobalPaintFlags(), LayoutSize());
+ PaintLayerPainter(*layout_svg_foreign_object_.Layer())
+ .Paint(paint_info.context, layer_painting_info, paint_info.PaintFlags());
+}
+
void SVGForeignObjectPainter::Paint(const PaintInfo& paint_info) {
if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) {
if (paint_info.phase != PaintPhase::kForeground &&
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.h b/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.h
index c60e19da08d..095518a2849 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/svg_foreign_object_painter.h
@@ -21,6 +21,8 @@ class SVGForeignObjectPainter {
: layout_svg_foreign_object_(layout_svg_foreign_object) {}
void Paint(const PaintInfo&);
+ void PaintLayer(const PaintInfo& paint_info);
+
private:
const LayoutSVGForeignObject& layout_svg_foreign_object_;
};