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/BUILD.gn1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/DEPS4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/README.md20
-rw-r--r--chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc26
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/block_painter_test.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_border_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.cc60
-rw-r--r--chromium/third_party/blink/renderer/core/paint/box_painter_base.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.cc256
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc31
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc22
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc107
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h29
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc163
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/compositing_triggers.h39
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.cc64
-rw-r--r--chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc45
-rw-r--r--chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/paint/frame_painter.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/paint/frame_painter.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc68
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc165
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h62
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc81
-rw-r--r--chromium/third_party/blink/renderer/core/paint/image_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc178
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h48
-rw-r--r--chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc188
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc165
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc59
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_paint_properties.h7
-rw-r--r--chromium/third_party/blink/renderer/core/paint/object_painter.cc24
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc72
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc16
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_event.h1
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_info.h10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc155
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_invalidator.h6
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.cc323
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer.h64
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc121
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.cc52
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h3
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc130
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.cc23
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.h14
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc46
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc89
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc265
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc375
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc528
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc163
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.cc25
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing.h19
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc29
-rw-r--r--chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h5
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc49
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc12
-rw-r--r--chromium/third_party/blink/renderer/core/paint/replaced_painter.cc14
-rw-r--r--chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/stub_chrome_client_for_cap.h (renamed from chromium/third_party/blink/renderer/core/paint/stub_chrome_client_for_spv2.h)8
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc10
-rw-r--r--chromium/third_party/blink/renderer/core/paint/svg_object_painter.cc4
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc50
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_painter_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/core/paint/table_section_painter.cc11
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc41
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h9
-rw-r--r--chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc304
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter.cc17
-rw-r--r--chromium/third_party/blink/renderer/core/paint/video_painter_test.cc27
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter.cc2
-rw-r--r--chromium/third_party/blink/renderer/core/paint/view_painter_test.cc10
113 files changed, 3169 insertions, 2537 deletions
diff --git a/chromium/third_party/blink/renderer/core/paint/BUILD.gn b/chromium/third_party/blink/renderer/core/paint/BUILD.gn
index 4a8d0dfea01..f95d1ebb01d 100644
--- a/chromium/third_party/blink/renderer/core/paint/BUILD.gn
+++ b/chromium/third_party/blink/renderer/core/paint/BUILD.gn
@@ -52,7 +52,6 @@ blink_core_sources("paint") {
"compositing/compositing_requirements_updater.cc",
"compositing/compositing_requirements_updater.h",
"compositing/compositing_state.h",
- "compositing/compositing_triggers.h",
"compositing/graphics_layer_tree_as_text.cc",
"compositing/graphics_layer_tree_as_text.h",
"compositing/graphics_layer_tree_builder.cc",
diff --git a/chromium/third_party/blink/renderer/core/paint/DEPS b/chromium/third_party/blink/renderer/core/paint/DEPS
index bc2165384f9..2e6dc92680e 100644
--- a/chromium/third_party/blink/renderer/core/paint/DEPS
+++ b/chromium/third_party/blink/renderer/core/paint/DEPS
@@ -1,6 +1,6 @@
include_rules = [
- # This goes away after slimming paint v2. For now it violates strict onion
- # soup guidelines.
+ # This goes away after CompositeAfterPaint is enabled. For now it violates
+ # strict onion soup guidelines.
"+cc/layers/picture_layer.h",
# For DCHECK.
"+base/logging.h",
diff --git a/chromium/third_party/blink/renderer/core/paint/README.md b/chromium/third_party/blink/renderer/core/paint/README.md
index 714aa95842a..dbf3dc08122 100644
--- a/chromium/third_party/blink/renderer/core/paint/README.md
+++ b/chromium/third_party/blink/renderer/core/paint/README.md
@@ -98,7 +98,7 @@ are treated in different ways during painting:
container.
* Paint invalidation container: the nearest object on the compositing
- container chain which is composited. Slimming paint V2 doesn't have this
+ container chain which is composited. CompositeAfterPaint doesn't have this
concept.
* Visual rect: the bounding box of all pixels that will be painted by a
@@ -125,9 +125,9 @@ At the time of writing, there are three operation modes that are switched by
### SlimmingPaintV175 (a.k.a. SPv1.75)
-This mode is for incrementally shipping completed features from SPv2. SPv1.75
+This mode is for incrementally shipping completed features from CAP. SPv1.75
reuses layerization from SPv1, but will cherrypick property-tree-based paint
-from SPv2. Meta display items are abandoned in favor of property tree. Each
+from CAP. Meta display items are abandoned in favor of property tree. Each
drawable GraphicsLayer's layer state will be computed by the property tree
builder. During paint, each display item will be associated with a property
tree state. At the end of paint, meta display items will be generated from
@@ -251,10 +251,10 @@ lifecycle update.
### BlinkGenPropertyTrees
-This mode is for incrementally shipping completed features from SPv2. It is
+This mode is for incrementally shipping completed features from CAP. It is
based on SPv1.75 and starts sending a layer list and property trees directly to
the compositor. BlinkGenPropertyTrees still uses the GraphicsLayers from SPv1.75
-and plugs them in as foreign layers to the SPv2 compositor
+and plugs them in as foreign layers to the CAP compositor
(PaintArtifactCompositor).
```
@@ -308,7 +308,7 @@ from layout
v
```
-### SlimmingPaintV2 (a.k.a. SPv2)
+### CompositeAfterPaint (a.k.a. CAP)
This is a new mode under development. In this mode, layerization runs after
pre-paint and paint, and meta display items are abandoned in favor of property
@@ -370,10 +370,10 @@ from layout
### Comparison of the three modes
```
- | SPv175 | BlinkGenPropertyTrees | SPv2
+ | SPv175 | BlinkGenPropertyTrees | CompositeAfterPaint
---------------------------------+--------------------+-----------------------+-------
REF::BlinkGenPropertyTreesEnabled| false | true | false
-REF::SPv2Enabled | false | false | true
+REF::CompositeAfterPaintEnabled | false | false | true
Layerization | PLC/CLM | PLC/CLM | PAC
cc property tree builder | on | off | off
```
@@ -574,7 +574,7 @@ If the first line contains any `LayoutInline`, we compute the style from the
`::first-line` style and the style of the `LayoutInline` and apply the computed
style to the first line part of the `LayoutInline`. In Blink's style
implementation, the combined first line style of `LayoutInline` is identified
-with `FIRST_LINE_INHERITED` pseudo ID.
+with `kPseudoIdFirstLineInherited`.
The normal paint invalidation of texts doesn't work for first line because
* `ComputedStyle::VisualInvalidationDiff()` can't detect first line style
@@ -637,7 +637,7 @@ from its containing self-painting layer to this layer, assuming that this layer
needs all paint phases that its container self-painting layer needs.
We could update the `NeedsPaintPhaseXXX` flags in a separate tree walk, but that
-would regress performance of the first paint. For slimming paint v2, we can
+would regress performance of the first paint. For CompositeAfterPaint, we can
update the flags during the pre-painting tree walk to simplify the logics.
### Hit test painting
diff --git a/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc b/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc
index 7533c6b7600..330c43ea585 100644
--- a/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc
+++ b/chromium/third_party/blink/renderer/core/paint/background_image_geometry.cc
@@ -44,9 +44,9 @@ bool FixedBackgroundPaintsInLocalCoordinates(
const LayoutView& view = ToLayoutView(obj);
- // TODO(wangxianzhu): For SPv2, inline this function into
+ // TODO(wangxianzhu): For CAP, inline this function into
// FixedBackgroundPaintsInLocalCoordinates().
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
return view.GetBackgroundPaintLocation() !=
kBackgroundPaintInScrollingContents;
}
@@ -110,6 +110,8 @@ void BackgroundImageGeometry::SetNoRepeatX(LayoutUnit x_offset,
// Reduce the width of the dest rect to draw only the portion of the
// tile that remains visible after offsetting the image.
+ // TODO(schenney): This might grow the dest rect if the dest rect has
+ // been adjusted for opaque borders.
unsnapped_dest_rect_.SetWidth(tile_size_.Width() + x_offset);
snapped_dest_rect_.SetWidth(tile_size_.Width() + snapped_x_offset);
}
@@ -145,6 +147,8 @@ void BackgroundImageGeometry::SetNoRepeatY(LayoutUnit y_offset,
// Reduce the height of the dest rect to draw only the portion of the
// tile that remains visible after offsetting the image.
+ // TODO(schenney): This might grow the dest rect if the dest rect has
+ // been adjusted for opaque borders.
unsnapped_dest_rect_.SetHeight(tile_size_.Height() + y_offset);
snapped_dest_rect_.SetHeight(tile_size_.Height() + snapped_y_offset);
}
@@ -375,7 +379,7 @@ LayoutRect FixedAttachmentPositioningArea(const LayoutBoxModelObject& obj,
// The LayoutView is the only object that can paint a fixed background into
// its scrolling contents layer, so it gets a special adjustment here.
if (obj.IsLayoutView()) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
DCHECK_EQ(obj.GetBackgroundPaintLocation(),
kBackgroundPaintInScrollingContents);
rect.SetLocation(IntPoint(ToLayoutView(obj).ScrolledContentOffset()));
@@ -696,7 +700,6 @@ void BackgroundImageGeometry::ComputePositioningArea(
snapped_box_offset =
LayoutPoint(snapped_box_outset.Left() - snapped_dest_adjust.Left(),
snapped_box_outset.Top() - snapped_dest_adjust.Top());
-
// For view backgrounds, the input paint rect is specified in root element
// local coordinate (i.e. a transform is applied on the context for
// painting), and is expanded to cover the whole canvas. Since left/top is
@@ -796,14 +799,17 @@ void BackgroundImageGeometry::CalculateFillTileSize(
}
case EFillSizeType::kContain:
case EFillSizeType::kCover: {
+ // Always use the snapped positioning area size for this computation,
+ // so that we resize the image to completely fill the actual painted
+ // area.
float horizontal_scale_factor =
image_intrinsic_size.Width()
- ? positioning_area_size.Width().ToFloat() /
+ ? snapped_positioning_area_size.Width().ToFloat() /
image_intrinsic_size.Width()
: 1.0f;
float vertical_scale_factor =
image_intrinsic_size.Height()
- ? positioning_area_size.Height().ToFloat() /
+ ? snapped_positioning_area_size.Height().ToFloat() /
image_intrinsic_size.Height()
: 1.0f;
// Force the dimension that determines the size to exactly match the
@@ -815,27 +821,27 @@ void BackgroundImageGeometry::CalculateFillTileSize(
// at the edge of the image when we paint it.
if (horizontal_scale_factor < vertical_scale_factor) {
tile_size_ = LayoutSize(
- positioning_area_size.Width(),
+ snapped_positioning_area_size.Width(),
LayoutUnit(std::max(1.0f, roundf(image_intrinsic_size.Height() *
horizontal_scale_factor))));
} else {
tile_size_ = LayoutSize(
LayoutUnit(std::max(1.0f, roundf(image_intrinsic_size.Width() *
vertical_scale_factor))),
- positioning_area_size.Height());
+ snapped_positioning_area_size.Height());
}
return;
}
if (horizontal_scale_factor > vertical_scale_factor) {
tile_size_ =
- LayoutSize(positioning_area_size.Width(),
+ LayoutSize(snapped_positioning_area_size.Width(),
LayoutUnit(std::max(1.0f, image_intrinsic_size.Height() *
horizontal_scale_factor)));
} else {
tile_size_ =
LayoutSize(LayoutUnit(std::max(1.0f, image_intrinsic_size.Width() *
vertical_scale_factor)),
- positioning_area_size.Height());
+ snapped_positioning_area_size.Height());
}
return;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/block_painter.cc b/chromium/third_party/blink/renderer/core/paint/block_painter.cc
index 193441f7626..b49f1b9a6da 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter.cc
@@ -39,13 +39,13 @@ void BlockPainter::Paint(const PaintInfo& paint_info) {
local_paint_info.phase = PaintPhase::kDescendantOutlinesOnly;
} else if (ShouldPaintSelfBlockBackground(original_phase)) {
local_paint_info.phase = PaintPhase::kSelfBlockBackgroundOnly;
- // With SlimmingPaintV2 we need to call PaintObject twice: once for the
+ // With CompositeAfterPaint we need to call PaintObject twice: once for the
// background painting that does not scroll, and a second time for the
// background painting that scrolls.
- // Without SlimmingPaintV2, this happens as the main graphics layer
+ // Without CompositeAfterPaint, this happens as the main graphics layer
// paints the background, and then the scrolling contents graphics layer
// paints the background.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
auto paint_location = layout_block_.GetBackgroundPaintLocation();
if (!(paint_location & kBackgroundPaintInGraphicsLayer))
local_paint_info.SetSkipsBackground(true);
@@ -197,7 +197,7 @@ void BlockPainter::PaintInlineBox(const InlineBox& inline_box,
}
void BlockPainter::PaintScrollHitTestDisplayItem(const PaintInfo& paint_info) {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
// Scroll hit test display items are only needed for compositing. This flag is
// used for for printing and drag images which do not need hit testing.
@@ -348,46 +348,50 @@ void BlockPainter::PaintCarets(const PaintInfo& paint_info,
}
}
-DISABLE_CFI_PERF
-bool BlockPainter::ShouldPaint(const ScopedPaintState& paint_state) const {
- // If there is no fragment to paint for this block, we still need to continue
- // the paint tree walk in case there are overflowing children that exist in
- // the current painting fragment of the painting layer. In the case we can't
- // check the overflow rect against the cull rect in the case because we don't
- // know the paint offset.
- if (!paint_state.FragmentToPaint())
- return true;
-
+LayoutRect BlockPainter::OverflowRectForCullRectTesting(
+ bool is_printing) const {
LayoutRect overflow_rect;
- if (paint_state.GetPaintInfo().IsPrinting() &&
- layout_block_.IsAnonymousBlock() && layout_block_.ChildrenInline()) {
+ if (is_printing && layout_block_.IsAnonymousBlock() &&
+ layout_block_.ChildrenInline()) {
// For case <a href="..."><div>...</div></a>, when layout_block_ is the
// anonymous container of <a>, the anonymous container's visual overflow is
// empty, but we need to continue painting to output <a>'s PDF URL rect
// which covers the continuations, as if we included <a>'s PDF URL rect into
// layout_block_'s visual overflow.
- Vector<LayoutRect> rects;
- layout_block_.AddElementVisualOverflowRects(rects, LayoutPoint());
+ auto rects = layout_block_.PhysicalOutlineRects(
+ LayoutPoint(), NGOutlineType::kIncludeBlockVisualOverflow);
overflow_rect = UnionRect(rects);
}
overflow_rect.Unite(layout_block_.VisualOverflowRect());
- bool uses_composited_scrolling = layout_block_.HasOverflowModel() &&
- layout_block_.UsesCompositedScrolling();
+ bool include_layout_overflow =
+ layout_block_.ScrollsOverflow() &&
+ (layout_block_.UsesCompositedScrolling() ||
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
- if (uses_composited_scrolling) {
+ if (include_layout_overflow) {
LayoutRect layout_overflow_rect = layout_block_.LayoutOverflowRect();
overflow_rect.Unite(layout_overflow_rect);
- }
- layout_block_.FlipForWritingMode(overflow_rect);
-
- // Scrolling is applied in physical space, which is why it is after the flip
- // above.
- if (uses_composited_scrolling) {
+ layout_block_.FlipForWritingMode(overflow_rect);
overflow_rect.Move(-layout_block_.ScrolledContentOffset());
+ } else {
+ layout_block_.FlipForWritingMode(overflow_rect);
}
+ return overflow_rect;
+}
+
+DISABLE_CFI_PERF
+bool BlockPainter::ShouldPaint(const ScopedPaintState& paint_state) const {
+ // If there is no fragment to paint for this block, we still need to continue
+ // the paint tree walk in case there are overflowing children that exist in
+ // the current painting fragment of the painting layer. In the case we can't
+ // check the overflow rect against the cull rect in the case because we don't
+ // know the paint offset.
+ if (!paint_state.FragmentToPaint())
+ return true;
- return paint_state.LocalRectIntersectsCullRect(overflow_rect);
+ return paint_state.LocalRectIntersectsCullRect(
+ OverflowRectForCullRectTesting(paint_state.GetPaintInfo().IsPrinting()));
}
void BlockPainter::PaintContents(const PaintInfo& paint_info,
diff --git a/chromium/third_party/blink/renderer/core/paint/block_painter.h b/chromium/third_party/blink/renderer/core/paint/block_painter.h
index e16f0be0a7a..93966cb354a 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter.h
@@ -5,7 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BLOCK_PAINTER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_BLOCK_PAINTER_H_
+#include "base/gtest_prod_util.h"
+#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/layout/order_iterator.h"
+#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
namespace blink {
@@ -45,6 +48,11 @@ class BlockPainter {
bool ShouldPaint(const ScopedPaintState&) const;
+ CORE_EXPORT LayoutRect OverflowRectForCullRectTesting(bool is_printing) const;
+
+ FRIEND_TEST_ALL_PREFIXES(BlockPainterTest, OverflowRectForCullRectTesting);
+ FRIEND_TEST_ALL_PREFIXES(BlockPainterTest,
+ OverflowRectCompositedScrollingForCullRectTesting);
const LayoutBlock& layout_block_;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc
index 180c207955b..a4b5a3a9fae 100644
--- a/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/block_painter_test.cc
@@ -6,7 +6,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/dom/events/event_listener.h"
+#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
@@ -20,9 +20,11 @@ namespace blink {
using BlockPainterTest = PaintControllerPaintTest;
-INSTANTIATE_SPV2_TEST_CASE_P(BlockPainterTest);
+INSTANTIATE_PAINT_TEST_CASE_P(BlockPainterTest);
TEST_P(BlockPainterTest, ScrollHitTestProperties) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none; }
@@ -115,6 +117,8 @@ TEST_P(BlockPainterTest, ScrollHitTestProperties) {
}
TEST_P(BlockPainterTest, FrameScrollHitTestProperties) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none; }
@@ -182,6 +186,33 @@ TEST_P(BlockPainterTest, FrameScrollHitTestProperties) {
&scroll_hit_test_display_item.scroll_offset_node());
}
+TEST_P(BlockPainterTest, OverflowRectForCullRectTesting) {
+ SetBodyInnerHTML(R"HTML(
+ <div id='scroller' style='width: 50px; height: 50px; overflow: scroll'>
+ <div style='width: 50px; height: 5000px'></div>
+ </div>
+ )HTML");
+ auto* scroller = ToLayoutBlock(GetLayoutObjectByElementId("scroller"));
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(LayoutRect(0, 0, 50, 5000),
+ BlockPainter(*scroller).OverflowRectForCullRectTesting(false));
+ } else {
+ EXPECT_EQ(LayoutRect(0, 0, 50, 50),
+ BlockPainter(*scroller).OverflowRectForCullRectTesting(false));
+ }
+}
+
+TEST_P(BlockPainterTest, OverflowRectCompositedScrollingForCullRectTesting) {
+ SetBodyInnerHTML(R"HTML(
+ <div id='scroller' style='width: 50px; height: 50px; overflow: scroll; will-change: transform'>
+ <div style='width: 50px; height: 5000px'></div>
+ </div>
+ )HTML");
+ auto* scroller = ToLayoutBlock(GetLayoutObjectByElementId("scroller"));
+ EXPECT_EQ(LayoutRect(0, 0, 50, 5000),
+ BlockPainter(*scroller).OverflowRectForCullRectTesting(false));
+}
+
class BlockPainterTestWithPaintTouchAction
: public PaintControllerPaintTestBase,
private ScopedPaintTouchActionRectsForTest {
@@ -477,14 +508,8 @@ TEST_F(BlockPainterTestWithPaintTouchAction, TouchActionRectPaintChunkChanges) {
}
namespace {
-class BlockPainterMockEventListener final : public EventListener {
+class BlockPainterMockEventListener final : public NativeEventListener {
public:
- BlockPainterMockEventListener() : EventListener(kCPPEventListenerType) {}
-
- bool operator==(const EventListener& other) const final {
- return this == &other;
- }
-
void Invoke(ExecutionContext*, Event*) final {}
};
} // namespace
@@ -511,7 +536,8 @@ TEST_F(BlockPainterTestWithPaintTouchAction, TouchHandlerRectsWithoutPaint) {
// Add an event listener to parent and ensure that hit test display items are
// created for both the parent and child.
- BlockPainterMockEventListener* callback = new BlockPainterMockEventListener();
+ BlockPainterMockEventListener* callback =
+ MakeGarbageCollected<BlockPainterMockEventListener>();
auto* parent_element = GetElementById("parent");
parent_element->addEventListener(event_type_names::kTouchstart, callback);
UpdateAllLifecyclePhasesForTest();
diff --git a/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc b/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc
index 389a9702899..e3a41fcab38 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_border_painter.cc
@@ -5,6 +5,8 @@
#include "third_party/blink/renderer/core/paint/box_border_painter.h"
#include <algorithm>
+
+#include "base/stl_util.h"
#include "third_party/blink/renderer/core/paint/box_painter.h"
#include "third_party/blink/renderer/core/paint/object_painter.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
@@ -663,7 +665,7 @@ BoxBorderPainter::BoxBorderPainter(const ComputedStyle& style,
}
void BoxBorderPainter::ComputeBorderProperties() {
- for (unsigned i = 0; i < arraysize(edges_); ++i) {
+ for (unsigned i = 0; i < base::size(edges_); ++i) {
const BorderEdge& edge = edges_[i];
if (!edge.ShouldRender()) {
diff --git a/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc
index 7b320469781..b3c80241f5f 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_model_object_painter.cc
@@ -59,8 +59,8 @@ BoxModelObjectPainter::BoxModelObjectPainter(const LayoutBoxModelObject& box,
bool BoxModelObjectPainter::IsPaintingScrollingBackground(
const LayoutBoxModelObject* box_model_,
const PaintInfo& paint_info) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // TODO(wangxianzhu): For SPv2, remove this method and let callers use
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // TODO(wangxianzhu): For CAP, remove this method and let callers use
// PaintInfo::IsPaintScrollingBackground() directly.
return paint_info.IsPaintingScrollingBackground();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
index a9618ef19d3..af885a2fa52 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator.cc
@@ -186,7 +186,7 @@ bool BoxPaintInvalidator::BackgroundGeometryDependsOnLayoutOverflowRect() {
bool BoxPaintInvalidator::BackgroundPaintsOntoScrollingContentsLayer() {
if (!HasEffectiveBackground())
return false;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
return box_.GetBackgroundPaintLocation() &
kBackgroundPaintInScrollingContents;
}
@@ -200,7 +200,7 @@ bool BoxPaintInvalidator::BackgroundPaintsOntoScrollingContentsLayer() {
bool BoxPaintInvalidator::BackgroundPaintsOntoMainGraphicsLayer() {
if (!HasEffectiveBackground())
return false;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return box_.GetBackgroundPaintLocation() & kBackgroundPaintInGraphicsLayer;
if (!box_.HasLayer())
return true;
@@ -244,13 +244,8 @@ BoxPaintInvalidator::ComputeViewBackgroundInvalidation() {
new_background_rect.Size() != old_background_rect.Size();
if (background_location_changed || background_size_changed) {
for (auto* object :
- layout_view.GetFrameView()->BackgroundAttachmentFixedObjects()) {
- if (background_location_changed ||
- ShouldFullyInvalidateFillLayersOnSizeChange(
- object->StyleRef().BackgroundLayers(), old_background_rect.Size(),
- new_background_rect.Size()))
- object->SetBackgroundNeedsFullPaintInvalidation();
- }
+ layout_view.GetFrameView()->BackgroundAttachmentFixedObjects())
+ object->SetBackgroundNeedsFullPaintInvalidation();
}
if (background_location_changed ||
@@ -282,20 +277,20 @@ BoxPaintInvalidator::ComputeViewBackgroundInvalidation() {
BoxPaintInvalidator::BackgroundInvalidationType
BoxPaintInvalidator::ComputeBackgroundInvalidation(
bool& should_invalidate_all_layers) {
- should_invalidate_all_layers = false;
+ // Need to fully invalidate the background on all layers if background paint
+ // location changed.
+ auto new_background_location = box_.GetBackgroundPaintLocation();
+ if (new_background_location != box_.PreviousBackgroundPaintLocation()) {
+ should_invalidate_all_layers = true;
+ box_.GetMutableForPainting().SetPreviousBackgroundPaintLocation(
+ new_background_location);
+ return BackgroundInvalidationType::kFull;
+ }
// If background changed, we may paint the background on different graphics
// layer, so we need to fully invalidate the background on all layers.
if (box_.BackgroundNeedsFullPaintInvalidation()) {
- if (box_.HasLayer() && box_.Layer()->GetCompositedLayerMapping() &&
- box_.Layer()->GetCompositedLayerMapping()->ScrollingContentsLayer())
- should_invalidate_all_layers = true;
-
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
- box_.FirstFragment().PaintProperties() &&
- box_.FirstFragment().PaintProperties()->ScrollTranslation())
- should_invalidate_all_layers = true;
-
+ should_invalidate_all_layers = true;
return BackgroundInvalidationType::kFull;
}
@@ -336,7 +331,7 @@ BoxPaintInvalidator::ComputeBackgroundInvalidation(
}
void BoxPaintInvalidator::InvalidateBackground() {
- bool should_invalidate_all_layers;
+ bool should_invalidate_all_layers = false;
auto background_invalidation_type =
ComputeBackgroundInvalidation(should_invalidate_all_layers);
if (box_.IsLayoutView()) {
@@ -344,17 +339,19 @@ void BoxPaintInvalidator::InvalidateBackground() {
background_invalidation_type, ComputeViewBackgroundInvalidation());
}
- if (should_invalidate_all_layers ||
- (BackgroundPaintsOntoScrollingContentsLayer() &&
- background_invalidation_type != BackgroundInvalidationType::kNone)) {
- auto reason =
- background_invalidation_type == BackgroundInvalidationType::kFull
- ? PaintInvalidationReason::kBackground
- : PaintInvalidationReason::kIncremental;
- context_.painting_layer->SetNeedsRepaint();
- ObjectPaintInvalidator(box_).InvalidateDisplayItemClient(
- box_.GetScrollableArea()->GetScrollingBackgroundDisplayItemClient(),
- reason);
+ if (box_.GetScrollableArea()) {
+ if (should_invalidate_all_layers ||
+ (BackgroundPaintsOntoScrollingContentsLayer() &&
+ background_invalidation_type != BackgroundInvalidationType::kNone)) {
+ auto reason =
+ background_invalidation_type == BackgroundInvalidationType::kFull
+ ? PaintInvalidationReason::kBackground
+ : PaintInvalidationReason::kIncremental;
+ context_.painting_layer->SetNeedsRepaint();
+ ObjectPaintInvalidator(box_).InvalidateDisplayItemClient(
+ box_.GetScrollableArea()->GetScrollingBackgroundDisplayItemClient(),
+ reason);
+ }
}
if (should_invalidate_all_layers ||
diff --git a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
index e4296ac8448..1278853be59 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_paint_invalidator_test.cc
@@ -57,7 +57,7 @@ class BoxPaintInvalidatorTest : public PaintControllerPaintTest {
target.setAttribute(
html_names::kStyleAttr,
target.getAttribute(html_names::kStyleAttr) + "; width: 200px");
- GetDocument().View()->UpdateLifecycleToLayoutClean();
+ GetDocument().View()->UpdateLifecycleToCompositingInputsClean();
// Simulate that PaintInvalidator updates visual rect.
box.GetMutableForPainting().SetVisualRect(
LayoutRect(visual_rect.Location(), box.Size()));
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 7c6f1ce6709..251668fc0dc 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter.cc
@@ -95,6 +95,12 @@ void BoxPainter::PaintBoxDecorationBackground(const PaintInfo& paint_info,
}
bool BoxPainter::BackgroundIsKnownToBeOpaque(const PaintInfo& paint_info) {
+ // If the box has multiple fragments, its VisualRect is the bounding box of
+ // all fragments' visual rects, which is likely to cover areas that are not
+ // covered by painted background.
+ if (layout_box_.FirstFragment().NextFragment())
+ return false;
+
LayoutRect bounds = BoxModelObjectPainter::IsPaintingScrollingBackground(
&layout_box_, paint_info)
? layout_box_.LayoutOverflowRect()
@@ -134,7 +140,7 @@ void BoxPainter::PaintBoxDecorationBackgroundWithRect(
BoxDecorationData box_decoration_data(layout_box_);
GraphicsContextStateSaver state_saver(paint_info.context, false);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
LayoutRect(EnclosingIntRect(paint_rect)) == paint_rect &&
BackgroundIsKnownToBeOpaque(paint_info))
recorder.SetKnownToBeOpaque();
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc b/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc
index e0a47c38afa..f84f3cfca71 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -28,8 +28,7 @@ void BoxPainterBase::PaintFillLayers(const PaintInfo& paint_info,
const FillLayer& fill_layer,
const LayoutRect& rect,
BackgroundImageGeometry& geometry,
- BackgroundBleedAvoidance bleed,
- SkBlendMode op) {
+ BackgroundBleedAvoidance bleed) {
FillLayerOcclusionOutputList reversed_paint_list;
bool should_draw_background_in_separate_buffer =
CalculateFillLayerOcclusionCulling(reversed_paint_list, fill_layer);
@@ -43,7 +42,7 @@ void BoxPainterBase::PaintFillLayers(const PaintInfo& paint_info,
for (auto it = reversed_paint_list.rbegin(); it != reversed_paint_list.rend();
++it) {
- PaintFillLayer(paint_info, c, **it, rect, bleed, geometry, op);
+ PaintFillLayer(paint_info, c, **it, rect, bleed, geometry);
}
if (should_draw_background_in_separate_buffer)
@@ -92,10 +91,6 @@ void BoxPainterBase::PaintNormalBoxShadow(const PaintInfo& info,
if (fill_rect.IsEmpty())
continue;
- FloatRect shadow_rect(border.Rect());
- shadow_rect.Inflate(shadow_blur + shadow_spread);
- shadow_rect.Move(shadow_offset);
-
// Save the state and clip, if not already done.
// The clip does not depend on any shadow-specific properties.
if (!state_saver.Saved()) {
@@ -137,14 +132,6 @@ void BoxPainterBase::PaintNormalBoxShadow(const PaintInfo& info,
DrawLooperBuilder::kShadowIgnoresAlpha, kDrawShadowOnly);
if (has_border_radius) {
- FloatRoundedRect influence_rect(
- PixelSnappedIntRect(LayoutRect(shadow_rect)), border.GetRadii());
- float change_amount = 2 * shadow_blur + shadow_spread;
- if (change_amount >= 0)
- influence_rect.ExpandRadii(change_amount);
- else
- influence_rect.ShrinkRadii(-change_amount);
-
FloatRoundedRect rounded_fill_rect = border;
rounded_fill_rect.Inflate(shadow_spread);
@@ -347,7 +334,6 @@ inline bool PaintFastBottomLayer(Node* node,
FloatRoundedRect color_border =
info.is_rounded_fill ? border_rect
: FloatRoundedRect(PixelSnappedIntRect(rect));
-
// When the layer has an image, figure out whether it is covered by a single
// tile. The border for painting images may not be the same as the color due
// to optimizations for the image painting destination that avoid painting
@@ -415,14 +401,18 @@ inline bool PaintFastBottomLayer(Node* node,
// Generated images will be created at the desired tile size, so assume their
// intrinsic size is the requested tile size.
+ bool is_generated_image = image->HasRelativeSize();
const FloatSize intrinsic_tile_size =
- image->HasRelativeSize() ? image_tile.Size() : FloatSize(image->Size());
+ is_generated_image ? image_tile.Size() : FloatSize(image->Size());
// Subset computation needs the same location as was used with
// ComputePhaseForBackground above, but needs the unsnapped destination
- // size to correctly calculate sprite subsets in the presence of zoom.
+ // size to correctly calculate sprite subsets in the presence of zoom. But if
+ // this is a generated image sized according to the tile size (which is a
+ // snapped value), use the snapped dest rect instead.
FloatRect dest_rect_for_subset(
FloatPoint(geometry.SnappedDestRect().Location()),
- FloatSize(geometry.UnsnappedDestRect().Size()));
+ is_generated_image ? FloatSize(geometry.SnappedDestRect().Size())
+ : FloatSize(geometry.UnsnappedDestRect().Size()));
// Content providers almost always choose source pixels at integer locations,
// so snap to integers. This is particuarly important for sprite maps.
// Calculation up to this point, in LayoutUnits, can lead to small variations
@@ -576,6 +566,12 @@ LayoutRectOutsets AdjustOutsetsForEdgeInclusion(
return adjusted;
}
+bool ShouldApplyBlendOperation(const BoxPainterBase::FillLayerInfo& info,
+ const FillLayer& layer) {
+ // For a mask layer, don't use the operator if this is the bottom layer.
+ return !info.is_bottom_layer || layer.GetType() != EFillLayerType::kMask;
+}
+
} // anonymous namespace
LayoutRectOutsets BoxPainterBase::AdjustedBorderOutsets(
@@ -589,7 +585,6 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
const LayoutRect& rect,
BackgroundBleedAvoidance bleed_avoidance,
BackgroundImageGeometry& geometry,
- SkBlendMode op,
bool object_has_multiple_boxes,
const LayoutSize flow_box_size) {
GraphicsContext& context = paint_info.context;
@@ -608,7 +603,7 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
const auto did_adjust_paint_rect = scrolled_paint_rect != rect;
scoped_refptr<Image> image;
- SkBlendMode composite_op = op;
+ SkBlendMode composite_op = SkBlendMode::kSrcOver;
base::Optional<ScopedInterpolationQuality> interpolation_quality_context;
if (info.should_paint_image) {
geometry.Calculate(paint_info.PaintContainer(), paint_info.phase,
@@ -623,10 +618,10 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
if (bg_layer.MaskSourceType() == EMaskSourceType::kLuminance)
context.SetColorFilter(kColorFilterLuminanceToAlpha);
- // If op != SkBlendMode::kSrcOver, a mask is being painted.
- SkBlendMode bg_op = WebCoreCompositeToSkiaComposite(
- bg_layer.Composite(), bg_layer.GetBlendMode());
- composite_op = (op == SkBlendMode::kSrcOver) ? bg_op : op;
+ if (ShouldApplyBlendOperation(info, bg_layer)) {
+ composite_op = WebCoreCompositeToSkiaComposite(bg_layer.Composite(),
+ bg_layer.GetBlendMode());
+ }
}
LayoutRectOutsets border = ComputeBorders();
@@ -637,11 +632,16 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
bleed_avoidance, border_padding_insets);
// Fast path for drawing simple color backgrounds. Do not use the fast
- // path if the dest rect has been adjusted for scrolling backgrounds
- // because correcting the dest rect for this case reduces the accuracy of the
- // destinations rects.
- // TODO(schenney): Still use the fast path if not painting any images.
- if (!did_adjust_paint_rect &&
+ // path with images if the dest rect has been adjusted for scrolling
+ // backgrounds because correcting the dest rect for scrolling reduces the
+ // accuracy of the destination rects. Also disable the fast path for images
+ // if we are shrinking the background for bleed avoidance, because this
+ // adjusts the border rects in a way that breaks the optimization.
+ bool disable_fast_path =
+ info.should_paint_image &&
+ (bleed_avoidance == kBackgroundBleedShrinkBackground ||
+ did_adjust_paint_rect);
+ if (!disable_fast_path &&
PaintFastBottomLayer(node_, paint_info, info, rect, border_rect, geometry,
image.get(), composite_op)) {
return;
diff --git a/chromium/third_party/blink/renderer/core/paint/box_painter_base.h b/chromium/third_party/blink/renderer/core/paint/box_painter_base.h
index fb43c43caae..19558c4331d 100644
--- a/chromium/third_party/blink/renderer/core/paint/box_painter_base.h
+++ b/chromium/third_party/blink/renderer/core/paint/box_painter_base.h
@@ -43,8 +43,7 @@ class BoxPainterBase {
const FillLayer&,
const LayoutRect&,
BackgroundImageGeometry&,
- BackgroundBleedAvoidance = kBackgroundBleedNone,
- SkBlendMode = SkBlendMode::kSrcOver);
+ BackgroundBleedAvoidance = kBackgroundBleedNone);
void PaintFillLayer(const PaintInfo&,
const Color&,
@@ -52,7 +51,6 @@ class BoxPainterBase {
const LayoutRect&,
BackgroundBleedAvoidance,
BackgroundImageGeometry&,
- SkBlendMode = SkBlendMode::kSrcOver,
bool object_has_multiple_boxes = false,
const LayoutSize flow_box_size = LayoutSize());
diff --git a/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc b/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
index b765acdf4c4..0c18791cc09 100644
--- a/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/collapsed_border_painter.cc
@@ -48,7 +48,7 @@ void CollapsedBorderPainter::SetupBorders() {
}
// At first, let all borders paint the joints. This is to keep the current
- // behavior for layout tests e.g. css2.1/t170602-bdr-conflict-w-01-d.html.
+ // behavior for web tests e.g. css2.1/t170602-bdr-conflict-w-01-d.html.
// TODO(crbug.com/672216): Determine the best way to deal with this.
if (start_.value && before_.value) {
start_.begin_outset = before_.outer_width;
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 1806c4d07b5..2a182889169 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
@@ -51,6 +51,7 @@
#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/loader/resource/image_resource_content.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
@@ -74,6 +75,7 @@
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/transforms/transform_state.h"
@@ -198,22 +200,12 @@ CompositedLayerMapping::CompositedLayerMapping(PaintLayer& layer)
is_main_frame_layout_view_layer_ = true;
CreatePrimaryGraphicsLayer();
-
- // ImagePainter has a micro-optimization to embed object-fit and clip into
- // the drawing so the property nodes were omitted if not composited.
- if (GetLayoutObject().IsLayoutImage())
- GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
CompositedLayerMapping::~CompositedLayerMapping() {
// Hits in compositing/squashing/squash-onto-nephew.html.
DisableCompositingQueryAsserts disabler;
- // ImagePainter has a micro-optimization to embed object-fit and clip into
- // the drawing so the property nodes should be omitted if not composited.
- if (GetLayoutObject().IsLayoutImage())
- GetLayoutObject().SetNeedsPaintPropertyUpdate();
-
// Do not leave the destroyed pointer dangling on any Layers that painted to
// this mapping's squashing layer.
for (wtf_size_t i = 0; i < squashed_layers_.size(); ++i) {
@@ -245,8 +237,10 @@ std::unique_ptr<GraphicsLayer> CompositedLayerMapping::CreateGraphicsLayer(
graphics_layer->SetCompositingReasons(reasons);
graphics_layer->SetSquashingDisallowedReasons(squashing_disallowed_reasons);
- if (Node* owning_node = owning_layer_.GetLayoutObject().GetNode())
- graphics_layer->SetOwnerNodeId(DOMNodeIds::IdForNode(owning_node));
+ if (Node* owning_node = owning_layer_.GetLayoutObject().GetNode()) {
+ graphics_layer->SetOwnerNodeId(
+ static_cast<int>(DOMNodeIds::IdForNode(owning_node)));
+ }
return graphics_layer;
}
@@ -259,6 +253,8 @@ void CompositedLayerMapping::CreatePrimaryGraphicsLayer() {
UpdateHitTestableWithoutDrawsContent(true);
UpdateOpacity(GetLayoutObject().StyleRef());
UpdateTransform(GetLayoutObject().StyleRef());
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ OwningLayer().UpdateFilterReferenceBox();
UpdateFilters();
UpdateBackdropFilters();
UpdateLayerBlendMode(GetLayoutObject().StyleRef());
@@ -308,15 +304,22 @@ void CompositedLayerMapping::UpdateTransform(const ComputedStyle& style) {
}
void CompositedLayerMapping::UpdateFilters() {
+ // Filters will be handled by property tree
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
CompositorFilterOperations operations;
OwningLayer().UpdateCompositorFilterOperationsForFilter(operations);
-
graphics_layer_->SetFilters(std::move(operations));
}
void CompositedLayerMapping::UpdateBackdropFilters() {
- graphics_layer_->SetBackdropFilters(
- OwningLayer().CreateCompositorFilterOperationsForBackdropFilter());
+ // Filters will be handled by property tree
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ return;
+ CompositorFilterOperations backdrop_filters =
+ OwningLayer().CreateCompositorFilterOperationsForBackdropFilter();
+ gfx::RectF filter_bounds = OwningLayer().BackdropFilterBounds();
+ graphics_layer_->SetBackdropFilters(backdrop_filters, filter_bounds);
}
void CompositedLayerMapping::UpdateStickyConstraints(
@@ -650,7 +653,8 @@ void CompositedLayerMapping::
kIgnoreOverflowClip);
ClipRect clip_rect;
- owning_layer_.Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ owning_layer_
+ .Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(clip_rects_context, clip_rect);
if (clip_rect.Rect() == LayoutRect(LayoutRect::InfiniteIntRect()))
return;
@@ -805,7 +809,7 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
bool has_clip_path =
ClipPathClipper::LocalClipPathBoundingBox(GetLayoutObject()).has_value();
if (UpdateMaskLayer(has_mask || has_clip_path)) {
- graphics_layer_->SetMaskLayer(mask_layer_.get(), false);
+ graphics_layer_->SetMaskLayer(mask_layer_.get());
layer_config_changed = true;
}
@@ -826,11 +830,11 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
// TODO(trchen): Verify if the 3 cases are mutually exclusive.
GraphicsLayer* first_come_first_served = child_clipping_mask_layer_.get();
if (HasClippingLayer()) {
- ClippingLayer()->SetMaskLayer(first_come_first_served, true);
+ ClippingLayer()->SetMaskLayer(first_come_first_served);
first_come_first_served = nullptr;
}
if (HasScrollingLayer()) {
- ScrollingLayer()->SetMaskLayer(first_come_first_served, true);
+ ScrollingLayer()->SetMaskLayer(first_come_first_served);
first_come_first_served = nullptr;
}
graphics_layer_->SetContentsClippingMaskLayer(first_come_first_served);
@@ -867,19 +871,11 @@ bool CompositedLayerMapping::UpdateGraphicsLayerConfiguration(
graphics_layer_->SetContentsToCcLayer(
media_element->CcLayer(),
/*prevent_contents_opaque_changes=*/true);
- } else if (IsSurfaceLayerCanvas(layout_object)) {
- HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode());
+ } else if (layout_object.IsCanvas()) {
graphics_layer_->SetContentsToCcLayer(
- canvas->SurfaceLayerBridge()->GetCcLayer(),
+ ToHTMLCanvasElement(layout_object.GetNode())->ContentsCcLayer(),
/*prevent_contents_opaque_changes=*/false);
layer_config_changed = true;
- } else if (IsTextureLayerCanvas(layout_object)) {
- HTMLCanvasElement* canvas = ToHTMLCanvasElement(layout_object.GetNode());
- if (CanvasRenderingContext* context = canvas->RenderingContext()) {
- graphics_layer_->SetContentsToCcLayer(
- context->CcLayer(), /*prevent_contents_opaque_changes=*/false);
- }
- layer_config_changed = true;
}
if (layout_object.IsLayoutEmbeddedContent()) {
if (PaintLayerCompositor::AttachFrameContentLayersToIframeLayer(
@@ -1172,6 +1168,9 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
if (!GetLayoutObject().StyleRef().IsRunningOpacityAnimationOnCompositor())
UpdateOpacity(GetLayoutObject().StyleRef());
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ OwningLayer().UpdateFilterReferenceBox();
+
if (!GetLayoutObject().StyleRef().IsRunningFilterAnimationOnCompositor())
UpdateFilters();
@@ -1242,9 +1241,10 @@ void CompositedLayerMapping::UpdateGraphicsLayerGeometry(
invalidate_graphics_layer, invalidate_scrolling_contents_layer);
// This depends on background_paints_onto_graphics_layer_.
- UpdateDrawsContent();
+ UpdateDrawsContentAndPaintsHitTest();
- // These invalidations need to happen after UpdateDrawsContent.
+ // These invalidations need to happen after
+ // |UpdateDrawsContentAndPaintsHitTest|.
if (invalidate_graphics_layer)
graphics_layer_->SetNeedsDisplay();
if (invalidate_scrolling_contents_layer)
@@ -1308,16 +1308,17 @@ void CompositedLayerMapping::UpdateMainGraphicsLayerGeometry(
FloatPoint new_position = FloatPoint(relative_compositing_bounds.Location() -
graphics_layer_parent_location);
IntSize new_size = relative_compositing_bounds.Size();
+ const LayoutObject& layout_object = GetLayoutObject();
// An iframe's main GraphicsLayer is positioned by the CLM for the <iframe>
// element in the parent frame's DOM.
- bool is_iframe_doc = GetLayoutObject().IsLayoutView() &&
- !GetLayoutObject().GetFrame()->IsLocalRoot();
+ bool is_iframe_doc =
+ layout_object.IsLayoutView() && !layout_object.GetFrame()->IsLocalRoot();
if (new_position != old_position && !is_iframe_doc) {
graphics_layer_->SetPosition(new_position);
- if (RuntimeEnabledFeatures::JankTrackingEnabled()) {
- LocalFrameView* frame_view = GetLayoutObject().View()->GetFrameView();
+ if (origin_trials::JankTrackingEnabled(&layout_object.GetDocument())) {
+ LocalFrameView* frame_view = layout_object.View()->GetFrameView();
frame_view->GetJankTracker().NotifyCompositedLayerMoved(
OwningLayer(), FloatRect(old_position, FloatSize(old_size)),
FloatRect(new_position, FloatSize(new_size)));
@@ -1337,9 +1338,14 @@ void CompositedLayerMapping::UpdateMainGraphicsLayerGeometry(
HasVisibleNonCompositingDescendant(&owning_layer_);
graphics_layer_->SetContentsVisible(contents_visible);
- graphics_layer_->SetBackfaceVisibility(
- GetLayoutObject().StyleRef().BackfaceVisibility() ==
- EBackfaceVisibility::kVisible);
+ // In BGPT mode, we do not need to update the backface visibility here, as it
+ // will already be set by PaintArtifactCompsitor based on
+ // TransformPaintPropertyNode::GetBackfaceVisibility.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ graphics_layer_->SetBackfaceVisibility(
+ GetLayoutObject().StyleRef().BackfaceVisibility() ==
+ EBackfaceVisibility::kVisible);
+ }
}
void CompositedLayerMapping::ComputeGraphicsLayerParentLocation(
@@ -1383,7 +1389,8 @@ void CompositedLayerMapping::UpdateAncestorClippingLayerGeometry(
kIgnorePlatformOverlayScrollbarSize, kIgnoreOverflowClipAndScroll);
ClipRect clip_rect;
- owning_layer_.Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ owning_layer_
+ .Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(clip_rects_context, clip_rect);
// Scroll offset is not included in the clip rect returned above
// (see kIgnoreOverflowClipAndScroll), so we need to add it in
@@ -1542,9 +1549,15 @@ void CompositedLayerMapping::UpdateOverflowControlsHostLayerGeometry(
owning_layer_.SubpixelAccumulation());
overflow_controls_host_layer_->SetSize(gfx::Size(border_box.Size()));
overflow_controls_host_layer_->SetMasksToBounds(true);
- overflow_controls_host_layer_->SetBackfaceVisibility(
- owning_layer_.GetLayoutObject().StyleRef().BackfaceVisibility() ==
- EBackfaceVisibility::kVisible);
+
+ // In BGPT mode, we do not need to update the backface visibility here, as it
+ // will already be set by PaintArtifactCompsitor based on
+ // TransformPaintPropertyNode::GetBackfaceVisibility.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ overflow_controls_host_layer_->SetBackfaceVisibility(
+ owning_layer_.GetLayoutObject().StyleRef().BackfaceVisibility() ==
+ EBackfaceVisibility::kVisible);
+ }
}
void CompositedLayerMapping::UpdateChildContainmentLayerGeometry() {
@@ -1833,7 +1846,7 @@ void CompositedLayerMapping::UpdateInternalHierarchy() {
// TODO(pdr): Ensure painting uses the correct GraphicsLayer when root layer
// scrolls is enabled. crbug.com/638719
if (is_main_frame_layout_view_layer_ &&
- !RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
bottom_layer = GetLayoutObject()
.GetFrame()
->GetPage()
@@ -1896,7 +1909,7 @@ void CompositedLayerMapping::UpdateContentsRect() {
graphics_layer_->SetContentsRect(PixelSnappedIntRect(ContentsBox()));
}
-void CompositedLayerMapping::UpdateDrawsContent() {
+void CompositedLayerMapping::UpdateDrawsContentAndPaintsHitTest() {
bool in_overlay_fullscreen_video = false;
if (GetLayoutObject().IsVideo()) {
HTMLVideoElement* video_element =
@@ -1909,6 +1922,16 @@ void CompositedLayerMapping::UpdateDrawsContent() {
in_overlay_fullscreen_video ? false : ContainsPaintedContent();
graphics_layer_->SetDrawsContent(has_painted_content);
+ // |has_painted_content| is conservative (e.g., will be true if any descendant
+ // paints content, regardless of whether the descendant content is a hit test)
+ // but an exhaustive check of descendants that paint hit tests would be too
+ // expensive.
+ bool paints_hit_test =
+ has_painted_content ||
+ (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled() &&
+ GetLayoutObject().HasEffectiveWhitelistedTouchAction());
+ graphics_layer_->SetPaintsHitTest(paints_hit_test);
+
if (scrolling_layer_) {
// m_scrollingLayer never has backing store.
// m_scrollingContentsLayer only needs backing store if the scrolled
@@ -1918,6 +1941,7 @@ void CompositedLayerMapping::UpdateDrawsContent() {
!(GetLayoutObject().StyleRef().HasBackground() ||
GetLayoutObject().HasBackdropFilter() || PaintsChildren());
scrolling_contents_layer_->SetDrawsContent(!scrolling_contents_are_empty_);
+ scrolling_contents_layer_->SetPaintsHitTest(paints_hit_test);
}
draws_background_onto_content_layer_ = false;
@@ -1939,8 +1963,10 @@ void CompositedLayerMapping::UpdateDrawsContent() {
// FIXME: we could refine this to only allocate backings for one of these
// layers if possible.
- if (foreground_layer_)
+ if (foreground_layer_) {
foreground_layer_->SetDrawsContent(has_painted_content);
+ foreground_layer_->SetPaintsHitTest(paints_hit_test);
+ }
if (decoration_outline_layer_)
decoration_outline_layer_->SetDrawsContent(true);
@@ -1998,13 +2024,13 @@ bool CompositedLayerMapping::UpdateClippingLayers(
ancestor_clipping_mask_layer_->SetPaintingPhase(
kGraphicsLayerPaintAncestorClippingMask);
ancestor_clipping_layer_->SetMaskLayer(
- ancestor_clipping_mask_layer_.get(), true);
+ ancestor_clipping_mask_layer_.get());
layers_changed = true;
}
} else if (ancestor_clipping_mask_layer_) {
ancestor_clipping_mask_layer_->RemoveFromParent();
ancestor_clipping_mask_layer_ = nullptr;
- ancestor_clipping_layer_->SetMaskLayer(nullptr, false);
+ ancestor_clipping_layer_->SetMaskLayer(nullptr);
layers_changed = true;
}
@@ -2441,7 +2467,11 @@ bool CompositedLayerMapping::UpdateScrollingLayers(
bool layer_changed = false;
if (needs_scrolling_layers) {
if (scrolling_layer_) {
- if (scrolling_coordinator) {
+ // When blink generates property trees, the user input scrollable bits are
+ // stored on scroll nodes instead of layers so there is no need to update
+ // them here.
+ if (scrolling_coordinator &&
+ !RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
scrolling_coordinator->UpdateUserInputScrollable(
owning_layer_.GetScrollableArea());
}
@@ -2811,6 +2841,8 @@ bool CompositedLayerMapping::IsDirectlyCompositedImage() const {
if (!image->IsBitmapImage())
return false;
+ UseCounter::Count(GetLayoutObject().GetDocument(),
+ WebFeature::kDirectlyCompositedImage);
return true;
}
@@ -2862,7 +2894,7 @@ void CompositedLayerMapping::UpdateImageContents() {
: kLow_SkFilterQuality);
// Prevent double-drawing: https://bugs.webkit.org/show_bug.cgi?id=58632
- UpdateDrawsContent();
+ UpdateDrawsContentAndPaintsHitTest();
// Image animation is "lazy", in that it automatically stops unless someone is
// drawing the image. So we have to kick the animation each time; this has the
@@ -2977,7 +3009,7 @@ GraphicsLayerUpdater::UpdateType CompositedLayerMapping::UpdateTypeForChildren(
struct SetContentsNeedsDisplayFunctor {
void operator()(GraphicsLayer* layer) const {
- if (layer->DrawsContent())
+ if (layer->PaintsContentOrHitTest())
layer->SetNeedsDisplay();
}
};
@@ -3054,7 +3086,8 @@ void CompositedLayerMapping::LocalClipRectForSquashedLayer(
&ancestor_paint_info->paint_layer->GetLayoutObject().FirstFragment(),
kUncachedClipRects);
ClipRect parent_clip_rect;
- paint_info.paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ paint_info.paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(clip_rects_context, parent_clip_rect);
// Convert from ancestor to local coordinates.
@@ -3146,87 +3179,50 @@ IntRect CompositedLayerMapping::RecomputeInterestRect(
const GraphicsLayer* graphics_layer) const {
IntRect graphics_layer_bounds(IntPoint(), IntSize(graphics_layer->Size()));
- FloatSize offset_from_anchor_layout_object;
- const LayoutBoxModelObject* anchor_layout_object;
- bool should_apply_anchor_overflow_clip = false;
- if (graphics_layer == squashing_layer_.get()) {
- // All squashed layers have the same clip and transform space, so we can use
- // the first squashed layer's layoutObject to map the squashing layer's
- // bounds into viewport space, with offsetFromAnchorLayoutObject to
- // translate squashing layer's bounds into the first squashed layer's space.
- anchor_layout_object =
- &owning_layer_.TransformAncestorOrRoot().GetLayoutObject();
- offset_from_anchor_layout_object =
- ToFloatSize(FloatPoint(SquashingOffsetFromTransformedAncestor()));
-
- // SquashingOffsetFromTransformedAncestor does not include scroll
- // offset.
- if (anchor_layout_object->UsesCompositedScrolling()) {
- offset_from_anchor_layout_object -=
- FloatSize(ToLayoutBox(anchor_layout_object)->ScrolledContentOffset());
- }
- } else {
- DCHECK(graphics_layer == graphics_layer_.get() ||
- graphics_layer == scrolling_contents_layer_.get());
- anchor_layout_object = &owning_layer_.GetLayoutObject();
- IntSize offset = graphics_layer->OffsetFromLayoutObject();
- should_apply_anchor_overflow_clip =
- AdjustForCompositedScrolling(graphics_layer, offset);
- offset_from_anchor_layout_object = FloatSize(offset);
- }
+ FloatClipRect mapping_rect((FloatRect(graphics_layer_bounds)));
- LayoutView* root_view = anchor_layout_object->View();
+ PropertyTreeState source_state = graphics_layer->GetPropertyTreeState();
+
+ LayoutView* root_view = owning_layer_.GetLayoutObject().View();
while (root_view->GetFrame()->OwnerLayoutObject())
root_view = root_view->GetFrame()->OwnerLayoutObject()->View();
- // Start with the bounds of the graphics layer in the space of the anchor
- // LayoutObject.
- FloatRect graphics_layer_bounds_in_object_space(graphics_layer_bounds);
- graphics_layer_bounds_in_object_space.Move(offset_from_anchor_layout_object);
- if (should_apply_anchor_overflow_clip && anchor_layout_object != root_view) {
- FloatRect clip_rect(
- ToLayoutBox(anchor_layout_object)->OverflowClipRect(LayoutPoint()));
- graphics_layer_bounds_in_object_space.Intersect(clip_rect);
- }
-
- // Now map the bounds to its visible content rect in root view space,
- // including applying clips along the way.
- LayoutRect graphics_layer_bounds_in_root_view_space(
- graphics_layer_bounds_in_object_space);
-
- anchor_layout_object->MapToVisualRectInAncestorSpace(
- root_view, graphics_layer_bounds_in_root_view_space, kUseGeometryMapper);
-
- // MapToVisualRectInAncestorSpace doesn't account for the root scroll because
- // 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 (root_view != anchor_layout_object) {
- if (auto* scrollable_area = root_view->GetScrollableArea()) {
- graphics_layer_bounds_in_root_view_space.MoveBy(
- -scrollable_area->VisibleContentRect().Location());
- }
- }
+ PropertyTreeState root_view_contents_state =
+ root_view->FirstFragment().ContentsProperties();
+ PropertyTreeState root_view_border_box_state =
+ root_view->FirstFragment().LocalBorderBoxProperties();
+
+ // 1. Move into local transform space.
+ mapping_rect.MoveBy(FloatPoint(graphics_layer->GetOffsetFromTransformNode()));
+ // 2. Map into contents space of the root LayoutView.
+ GeometryMapper::LocalToAncestorVisualRect(
+ source_state, root_view_contents_state, mapping_rect);
+
+ FloatRect visible_content_rect = mapping_rect.Rect();
- FloatRect visible_content_rect(graphics_layer_bounds_in_root_view_space);
+ // 3. Move into local border box transform space of the root LayoutView.
+ // Note that the overflow clip has *not* been applied.
+ GeometryMapper::SourceToDestinationRect(
+ root_view_contents_state.Transform(),
+ root_view_border_box_state.Transform(), visible_content_rect);
+
+ // 4. Apply overflow clip, or adjusted version if necessary.
root_view->GetFrameView()->ClipPaintRect(&visible_content_rect);
- // Map the visible content rect from root view space to local graphics layer
- // space.
FloatRect local_interest_rect;
// If the visible content rect is empty, then it makes no sense to map it back
// since there is nothing to map.
if (!visible_content_rect.IsEmpty()) {
- local_interest_rect = FloatRect(
- anchor_layout_object
- ->AbsoluteToLocalQuad(visible_content_rect,
- kUseTransforms | kTraverseDocumentBoundaries)
- .EnclosingBoundingBox());
- local_interest_rect.Move(-offset_from_anchor_layout_object);
- // TODO(chrishtr): the code below is a heuristic, instead we should detect
+ local_interest_rect = visible_content_rect;
+ // 5. Map the visible content rect from root view space to local graphics
+ // layer space.
+ GeometryMapper::SourceToDestinationRect(
+ root_view_border_box_state.Transform(), source_state.Transform(),
+ local_interest_rect);
+ local_interest_rect.MoveBy(
+ -FloatPoint(graphics_layer->GetOffsetFromTransformNode()));
+
+ // TODO(chrishtr): the code below is a heuristic. Instead we should detect
// and return whether the mapping failed. In some cases,
// absoluteToLocalQuad can fail to map back to the local space, due to
// passing through non-invertible transforms or floating-point accuracy
@@ -3430,8 +3426,9 @@ void CompositedLayerMapping::PaintContents(
} else if (IsScrollableAreaLayer(graphics_layer)) {
PaintScrollableArea(graphics_layer, context, interest_rect);
}
- probe::didPaint(owning_layer_.GetLayoutObject().GetFrame(), graphics_layer,
- context, LayoutRect(interest_rect));
+ probe::didPaint(owning_layer_.GetLayoutObject().GetFrame(),
+ graphics_layer->CcLayer(), context,
+ LayoutRect(interest_rect));
#if DCHECK_IS_ON()
if (Page* page = GetLayoutObject().GetFrame()->GetPage())
page->SetIsPainting(false);
@@ -3468,14 +3465,11 @@ bool CompositedLayerMapping::IsScrollableAreaLayer(
}
bool CompositedLayerMapping::ShouldThrottleRendering() const {
- return GetLayoutObject().View()->GetFrame()->ShouldThrottleRendering();
+ return GetLayoutObject().GetFrame()->ShouldThrottleRendering();
}
bool CompositedLayerMapping::IsTrackingRasterInvalidations() const {
- return GetLayoutObject()
- .View()
- ->GetFrameView()
- ->IsTrackingPaintInvalidations();
+ return GetLayoutObject().GetFrameView()->IsTrackingPaintInvalidations();
}
void CompositedLayerMapping::SetOverlayScrollbarsHidden(bool hidden) {
@@ -3483,6 +3477,12 @@ void CompositedLayerMapping::SetOverlayScrollbarsHidden(bool hidden) {
scrollable_area->SetScrollbarsHiddenIfOverlay(hidden);
}
+void CompositedLayerMapping::SetPaintArtifactCompositorNeedsUpdate() const {
+ LocalFrameView* frame_view = GetLayoutObject().GetFrameView();
+ DCHECK(frame_view);
+ frame_view->SetPaintArtifactCompositorNeedsUpdate();
+}
+
#if DCHECK_IS_ON()
void CompositedLayerMapping::VerifyNotPainting() {
DCHECK(!GetLayoutObject().GetFrame()->GetPage() ||
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
index c83e8cc41ff..9deb283702e 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h
@@ -215,6 +215,7 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
bool ShouldThrottleRendering() const override;
bool IsTrackingRasterInvalidations() const override;
void SetOverlayScrollbarsHidden(bool) override;
+ void SetPaintArtifactCompositorNeedsUpdate() const override;
#if DCHECK_IS_ON()
void VerifyNotPainting() override;
@@ -421,7 +422,7 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
void UpdateScrollParent(const PaintLayer*);
void UpdateClipParent(const PaintLayer* scroll_parent);
bool UpdateSquashingLayers(bool needs_squashing_layers);
- void UpdateDrawsContent();
+ void UpdateDrawsContentAndPaintsHitTest();
void UpdateChildrenTransform();
void UpdateCompositedBounds();
void UpdateOverscrollBehavior();
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
index 7d2b078394a..662a396c049 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/composited_layer_mapping_test.cc
@@ -477,7 +477,7 @@ TEST_F(CompositedLayerMappingTest, ClippedBigLayer) {
}
TEST_F(CompositedLayerMappingTestWithoutBGPT, ClippingMaskLayer) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
const AtomicString style_without_clipping =
@@ -2238,20 +2238,8 @@ TEST_F(CompositedLayerMappingTest, StickyPositionNotSquashed) {
ToLayoutBlock(GetLayoutObjectByElementId("sticky2"))->Layer();
PaintLayer* sticky3 =
ToLayoutBlock(GetLayoutObjectByElementId("sticky3"))->Layer();
- EXPECT_EQ(kPaintsIntoOwnBacking, sticky1->GetCompositingState());
- EXPECT_EQ(kNotComposited, sticky2->GetCompositingState());
- EXPECT_EQ(kNotComposited, sticky3->GetCompositingState());
-
- PaintLayer* scroller =
- ToLayoutBlock(GetLayoutObjectByElementId("scroller"))->Layer();
- PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
- scrollable_area->ScrollToAbsolutePosition(
- FloatPoint(scrollable_area->ScrollPosition().Y(), 100));
- UpdateAllLifecyclePhasesForTest();
-
- // Now that sticky2 and sticky3 overlap sticky1 they will be promoted, but
- // they should not be squashed into the same layer because they scroll with
- // respect to each other.
+ // All three sticky-pos elements are composited, because we composite
+ // all sticky elements which stick to scrollers.
EXPECT_EQ(kPaintsIntoOwnBacking, sticky1->GetCompositingState());
EXPECT_EQ(kPaintsIntoOwnBacking, sticky2->GetCompositingState());
EXPECT_EQ(kPaintsIntoOwnBacking, sticky3->GetCompositingState());
@@ -2628,7 +2616,7 @@ TEST_F(CompositedLayerMappingTest, ScrollLayerSizingSubpixelAccumulation) {
}
TEST_F(CompositedLayerMappingTest, SquashingScroll) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
@@ -2658,7 +2646,7 @@ TEST_F(CompositedLayerMappingTest, SquashingScroll) {
}
TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
@@ -2684,7 +2672,7 @@ TEST_F(CompositedLayerMappingTest, SquashingScrollInterestRect) {
TEST_F(CompositedLayerMappingTest,
SquashingBoundsUnderCompositedScrollingWithTransform) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
@@ -2720,7 +2708,7 @@ transform'></div>
}
TEST_F(CompositedLayerMappingTest, ContentsNotOpaqueWithForegroundLayer) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
@@ -2744,8 +2732,30 @@ TEST_F(CompositedLayerMappingTest, ContentsNotOpaqueWithForegroundLayer) {
EXPECT_FALSE(mapping->MainGraphicsLayer()->ContentsOpaque());
}
+TEST_F(CompositedLayerMappingTest, TouchActionRectsWithoutContent) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
+ SetBodyInnerHTML(
+ "<div id='target' style='will-change: transform; width: 100px;"
+ " height: 100px; touch-action: none;'></div>");
+ auto* box = ToLayoutBoxModelObject(GetLayoutObjectByElementId("target"));
+ auto* mapping = box->Layer()->GetCompositedLayerMapping();
+
+ const auto* layer = mapping->MainGraphicsLayer()->CcLayer();
+ auto expected = gfx::Rect(0, 0, 100, 100);
+ EXPECT_EQ(layer->touch_action_region().region().bounds(), expected);
+
+ EXPECT_TRUE(mapping->MainGraphicsLayer()->PaintsHitTest());
+
+ // The only painted content for the main graphics layer is the touch-action
+ // rect which is not sent to cc, so the cc::layer should not draw content.
+ EXPECT_FALSE(layer->DrawsContent());
+ EXPECT_FALSE(mapping->MainGraphicsLayer()->DrawsContent());
+}
+
TEST_F(CompositedLayerMappingTest, ContentsOpaque) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
index 0c7bdf68294..48bf5a3e2b3 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.cc
@@ -24,12 +24,8 @@ static const LayoutBoxModelObject* ClippingContainerFromClipChainParent(
: clip_chain_parent->ClippingContainer();
}
-CompositingInputsUpdater::CompositingInputsUpdater(
- PaintLayer* root_layer,
- CompositingReasonFinder& compositing_reason_finder)
- : geometry_map_(kUseTransforms),
- root_layer_(root_layer),
- compositing_reason_finder_(compositing_reason_finder) {}
+CompositingInputsUpdater::CompositingInputsUpdater(PaintLayer* root_layer)
+ : geometry_map_(kUseTransforms), root_layer_(root_layer) {}
CompositingInputsUpdater::~CompositingInputsUpdater() = default;
@@ -80,14 +76,16 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
geometry_map_.PushMappingsToAncestor(layer, layer->Parent());
- PaintLayer* enclosing_composited_layer = info.enclosing_composited_layer;
+ PaintLayer* enclosing_stacking_composited_layer =
+ info.enclosing_stacking_composited_layer;
PaintLayer* enclosing_squashing_composited_layer =
info.enclosing_squashing_composited_layer;
switch (layer->GetCompositingState()) {
case kNotComposited:
break;
case kPaintsIntoOwnBacking:
- enclosing_composited_layer = layer;
+ if (layer->GetLayoutObject().StyleRef().IsStackingContext())
+ enclosing_stacking_composited_layer = layer;
break;
case kPaintsIntoGroupedBacking:
enclosing_squashing_composited_layer =
@@ -96,8 +94,8 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
}
if (layer->NeedsCompositingInputsUpdate()) {
- if (enclosing_composited_layer) {
- enclosing_composited_layer->GetCompositedLayerMapping()
+ if (enclosing_stacking_composited_layer) {
+ enclosing_stacking_composited_layer->GetCompositedLayerMapping()
->SetNeedsGraphicsLayerUpdate(kGraphicsLayerUpdateSubtree);
}
if (enclosing_squashing_composited_layer) {
@@ -121,7 +119,8 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
if (update_type == kForceUpdate)
UpdateAncestorDependentCompositingInputs(layer, info);
- info.enclosing_composited_layer = enclosing_composited_layer;
+ info.enclosing_stacking_composited_layer =
+ enclosing_stacking_composited_layer;
info.enclosing_squashing_composited_layer =
enclosing_squashing_composited_layer;
@@ -223,14 +222,8 @@ void CompositingInputsUpdater::UpdateRecursive(PaintLayer* layer,
// child.
// 6. If |layer| is the root, composite if
// DescendantHasDirectCompositingReason is true for |layer|.
- bool ignore_lcd_text =
- (layer->AncestorScrollingLayer() &&
- !layer->AncestorScrollingLayer()->IsRootLayer() &&
- layer->AncestorScrollingLayer()->NeedsCompositedScrolling());
-
layer->SetPotentialCompositingReasonsFromNonStyle(
- compositing_reason_finder_.NonStyleDeterminedDirectReasons(
- layer, ignore_lcd_text));
+ CompositingReasonFinder::NonStyleDeterminedDirectReasons(*layer));
if (layer->GetScrollableArea()) {
layer->GetScrollableArea()->UpdateNeedsCompositedScrolling(
@@ -309,7 +302,7 @@ void CompositingInputsUpdater::UpdateAncestorDependentCompositingInputs(
}
ClipRect clip_rect;
- layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ layer->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(root_layer_,
&root_layer_->GetLayoutObject().FirstFragment(),
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
index 823f1569c12..04fbc010961 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_inputs_updater.h
@@ -11,15 +11,12 @@
namespace blink {
class PaintLayer;
-class CompositingReasonFinder;
class CompositingInputsUpdater {
STACK_ALLOCATED();
public:
- explicit CompositingInputsUpdater(
- PaintLayer* root_layer,
- CompositingReasonFinder& compositing_reason_finder);
+ explicit CompositingInputsUpdater(PaintLayer* root_layer);
~CompositingInputsUpdater();
void Update();
@@ -35,7 +32,8 @@ class CompositingInputsUpdater {
};
struct AncestorInfo {
- PaintLayer* enclosing_composited_layer = nullptr;
+ // The ancestor composited PaintLayer which is also a stacking context.
+ PaintLayer* enclosing_stacking_composited_layer = nullptr;
// A "squashing composited layer" is a PaintLayer that owns a squashing
// layer. This variable stores the squashing composited layer for the
// nearest PaintLayer ancestor which is squashed.
@@ -71,7 +69,6 @@ class CompositingInputsUpdater {
LayoutGeometryMap geometry_map_;
PaintLayer* root_layer_;
- CompositingReasonFinder& compositing_reason_finder_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
index d8f7858836e..587f66555f4 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.cc
@@ -24,7 +24,7 @@ enum class ScrollbarOrCorner {
namespace blink {
void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
if (!object.HasLayer())
@@ -69,7 +69,7 @@ void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
// Before BlinkGenPropertyTrees, CSS clip could not be composited so
// we should avoid setting it on the layer itself.
if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() &&
- !RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (const auto* properties = fragment_data.PaintProperties()) {
if (const auto* css_clip = properties->CssClip()) {
container_layer_state->SetClip(css_clip->Parent());
@@ -152,27 +152,25 @@ void CompositingLayerPropertyUpdater::Update(const LayoutObject& object) {
// reason of adding ScrollOrigin().
auto contents_paint_offset =
snapped_paint_offset + ToLayoutBox(object).ScrollOrigin();
- auto SetContentsLayerState = [&fragment_data, &contents_paint_offset](
- GraphicsLayer* graphics_layer) {
+ auto SetScrollingContentsLayerState = [&fragment_data,
+ &contents_paint_offset](
+ GraphicsLayer* graphics_layer) {
if (graphics_layer) {
graphics_layer->SetLayerState(
fragment_data.ContentsProperties(),
contents_paint_offset + graphics_layer->OffsetFromLayoutObject());
}
};
- SetContentsLayerState(mapping->ScrollingContentsLayer());
- SetContentsLayerState(mapping->ForegroundLayer());
+ SetScrollingContentsLayerState(mapping->ScrollingContentsLayer());
+ SetScrollingContentsLayerState(mapping->ForegroundLayer());
} else {
SetContainerLayerState(mapping->ForegroundLayer());
}
auto* main_graphics_layer = mapping->MainGraphicsLayer();
- if (const auto* contents_layer = main_graphics_layer->ContentsLayer()) {
- auto position = contents_layer->position();
- main_graphics_layer->SetContentsLayerState(
- fragment_data.ContentsProperties(),
- snapped_paint_offset + main_graphics_layer->OffsetFromLayoutObject() +
- IntSize(position.x(), position.y()));
+ if (main_graphics_layer->ContentsLayer()) {
+ main_graphics_layer->SetContentsPropertyTreeState(
+ fragment_data.ContentsProperties());
}
if (auto* squashing_layer = mapping->SquashingLayer()) {
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
index bc5808dac28..b5ec928673c 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -19,63 +19,42 @@
namespace blink {
-CompositingReasonFinder::CompositingReasonFinder(LayoutView& layout_view)
- : layout_view_(layout_view),
- compositing_triggers_(
- static_cast<CompositingTriggerFlags>(kAllCompositingTriggers)) {
- UpdateTriggers();
-}
-
-void CompositingReasonFinder::UpdateTriggers() {
- compositing_triggers_ = 0;
-
- Settings& settings = layout_view_.GetDocument().GetPage()->GetSettings();
- if (settings.GetPreferCompositingToLCDTextEnabled()) {
- compositing_triggers_ |= kScrollableInnerFrameTrigger;
- compositing_triggers_ |= kOverflowScrollTrigger;
- compositing_triggers_ |= kViewportConstrainedPositionedTrigger;
- }
-}
-
-bool CompositingReasonFinder::IsMainFrame() const {
- return layout_view_.GetDocument().IsInMainFrame();
-}
-
CompositingReasons CompositingReasonFinder::DirectReasons(
- const PaintLayer* layer,
- bool ignore_lcd_text) const {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ const PaintLayer& layer) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return CompositingReason::kNone;
- DCHECK_EQ(PotentialCompositingReasonsFromStyle(layer->GetLayoutObject()),
- layer->PotentialCompositingReasonsFromStyle());
+ DCHECK_EQ(PotentialCompositingReasonsFromStyle(layer.GetLayoutObject()),
+ layer.PotentialCompositingReasonsFromStyle());
CompositingReasons style_determined_direct_compositing_reasons =
- layer->PotentialCompositingReasonsFromStyle() &
+ layer.PotentialCompositingReasonsFromStyle() &
CompositingReason::kComboAllDirectStyleDeterminedReasons;
return style_determined_direct_compositing_reasons |
- NonStyleDeterminedDirectReasons(layer, ignore_lcd_text);
+ NonStyleDeterminedDirectReasons(layer);
}
-bool CompositingReasonFinder::RequiresCompositingForScrollableFrame() const {
+bool CompositingReasonFinder::RequiresCompositingForScrollableFrame(
+ const LayoutView& layout_view) {
// Need this done first to determine overflow.
- DCHECK(!layout_view_.NeedsLayout());
- if (IsMainFrame())
+ DCHECK(!layout_view.NeedsLayout());
+ if (layout_view.GetDocument().IsInMainFrame())
return false;
- if (!(compositing_triggers_ & kScrollableInnerFrameTrigger))
+ const auto& settings = *layout_view.GetDocument().GetSettings();
+ if (!settings.GetPreferCompositingToLCDTextEnabled())
return false;
- if (layout_view_.GetFrameView()->Size().IsEmpty())
+ if (layout_view.GetFrameView()->Size().IsEmpty())
return false;
- return layout_view_.GetFrameView()->LayoutViewport()->ScrollsOverflow();
+ return layout_view.GetFrameView()->LayoutViewport()->ScrollsOverflow();
}
CompositingReasons
CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
- LayoutObject& layout_object) const {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ const LayoutObject& layout_object) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return CompositingReason::kNone;
CompositingReasons reasons = CompositingReason::kNone;
@@ -151,35 +130,34 @@ bool CompositingReasonFinder::RequiresCompositingForTransform(
}
CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
- const PaintLayer* layer,
- bool ignore_lcd_text) const {
+ const PaintLayer& layer) {
CompositingReasons direct_reasons = CompositingReason::kNone;
- LayoutObject& layout_object = layer->GetLayoutObject();
+ LayoutObject& layout_object = layer.GetLayoutObject();
// TODO(chrishtr): remove this hammer in favor of something more targeted.
// See crbug.com/749349.
- if (layer->ClipParent() && layer->GetLayoutObject().IsOutOfFlowPositioned())
+ if (layer.ClipParent() && layer.GetLayoutObject().IsOutOfFlowPositioned())
direct_reasons |= CompositingReason::kOutOfFlowClipping;
- if (RequiresCompositingForRootScroller(*layer))
+ if (RequiresCompositingForRootScroller(layer))
direct_reasons |= CompositingReason::kRootScroller;
// Composite |layer| if it is inside of an ancestor scrolling layer, but that
// scrolling layer is not on the stacking context ancestor chain of |layer|.
// See the definition of the scrollParent property in Layer for more detail.
- if (const PaintLayer* scrolling_ancestor = layer->AncestorScrollingLayer()) {
- if (scrolling_ancestor->NeedsCompositedScrolling() && layer->ScrollParent())
+ if (const PaintLayer* scrolling_ancestor = layer.AncestorScrollingLayer()) {
+ if (scrolling_ancestor->NeedsCompositedScrolling() && layer.ScrollParent())
direct_reasons |= CompositingReason::kOverflowScrollingParent;
}
- if (RequiresCompositingForScrollDependentPosition(layer, ignore_lcd_text))
+ if (RequiresCompositingForScrollDependentPosition(layer))
direct_reasons |= CompositingReason::kScrollDependentPosition;
// TODO(crbug.com/839341): Remove once we support main-thread AnimationWorklet
// and don't need to promote the scroll-source.
- if (layer->GetScrollableArea() && layer->GetLayoutObject().GetNode() &&
+ if (layer.GetScrollableArea() && layer.GetLayoutObject().GetNode() &&
ScrollTimeline::HasActiveScrollTimeline(
- layer->GetLayoutObject().GetNode())) {
+ layer.GetLayoutObject().GetNode())) {
direct_reasons |= CompositingReason::kScrollTimelineTarget;
}
@@ -187,12 +165,13 @@ CompositingReasons CompositingReasonFinder::NonStyleDeterminedDirectReasons(
// PaintLayer children and whose children can't use its backing to render
// into. These children (the controls) always need to be promoted into their
// own layers to draw on top of the accelerated video.
- if (layer->CompositingContainer() &&
- layer->CompositingContainer()->GetLayoutObject().IsVideo())
+ if (layer.CompositingContainer() &&
+ layer.CompositingContainer()->GetLayoutObject().IsVideo())
direct_reasons |= CompositingReason::kVideoOverlay;
- if (layer->IsRootLayer() && (RequiresCompositingForScrollableFrame() ||
- layout_view_.GetFrame()->IsLocalRoot())) {
+ if (layer.IsRootLayer() &&
+ (RequiresCompositingForScrollableFrame(*layout_object.View()) ||
+ layout_object.GetFrame()->IsLocalRoot())) {
direct_reasons |= CompositingReason::kRoot;
}
@@ -259,34 +238,26 @@ bool CompositingReasonFinder::RequiresCompositingForRootScroller(
}
bool CompositingReasonFinder::RequiresCompositingForScrollDependentPosition(
- const PaintLayer* layer,
- bool ignore_lcd_text) const {
- if (!layer->GetLayoutObject().StyleRef().HasViewportConstrainedPosition() &&
- !layer->GetLayoutObject().StyleRef().HasStickyConstrainedPosition())
+ const PaintLayer& layer) {
+ const auto& layout_object = layer.GetLayoutObject();
+ if (!layout_object.StyleRef().HasViewportConstrainedPosition() &&
+ !layout_object.StyleRef().HasStickyConstrainedPosition())
return false;
- if (!(ignore_lcd_text ||
- (compositing_triggers_ & kViewportConstrainedPositionedTrigger)) &&
- (!RuntimeEnabledFeatures::CompositeOpaqueFixedPositionEnabled() ||
- !layer->BackgroundIsKnownToBeOpaqueInRect(
- LayoutRect(layer->BoundingBoxForCompositing()), true) ||
- layer->CompositesWithTransform() || layer->CompositesWithOpacity())) {
- return false;
- }
// Don't promote fixed position elements that are descendants of a non-view
// container, e.g. transformed elements. They will stay fixed wrt the
// container rather than the enclosing frame.
- EPosition position = layer->GetLayoutObject().StyleRef().GetPosition();
+ EPosition position = layout_object.StyleRef().GetPosition();
if (position == EPosition::kFixed) {
- return layer->FixedToViewport() &&
- layout_view_.GetFrameView()->LayoutViewport()->ScrollsOverflow();
+ return layer.FixedToViewport() &&
+ layout_object.GetFrameView()->LayoutViewport()->ScrollsOverflow();
}
DCHECK_EQ(position, EPosition::kSticky);
// Don't promote sticky position elements that cannot move with scrolls.
- if (!layer->SticksToScroller())
+ if (!layer.SticksToScroller())
return false;
- return layer->AncestorOverflowLayer()->ScrollsOverflow();
+ return layer.AncestorOverflowLayer()->ScrollsOverflow();
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
index 0bf467bf6cb..0eca51b5dfe 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.h
@@ -7,7 +7,6 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/paint/compositing/compositing_triggers.h"
#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
@@ -22,26 +21,17 @@ class CORE_EXPORT CompositingReasonFinder {
DISALLOW_NEW();
public:
- explicit CompositingReasonFinder(LayoutView&);
+ static CompositingReasons PotentialCompositingReasonsFromStyle(
+ const LayoutObject&);
- CompositingReasons PotentialCompositingReasonsFromStyle(LayoutObject&) const;
+ static CompositingReasons NonStyleDeterminedDirectReasons(const PaintLayer&);
- CompositingReasons NonStyleDeterminedDirectReasons(
- const PaintLayer*,
- bool ignore_lcd_text) const;
- LayoutView& layout_view_;
- CompositingTriggerFlags compositing_triggers_;
DISALLOW_COPY_AND_ASSIGN(CompositingReasonFinder);
- // Returns the direct reasons for compositing the given layer. If
- // |ignoreLCDText| is true promotion will not try to preserve subpixel text
- // rendering (i.e. partially transparent layers will be promoted).
- CompositingReasons DirectReasons(const PaintLayer*,
- bool ignore_lcd_text) const;
+ // Returns the direct reasons for compositing the given layer.
+ static CompositingReasons DirectReasons(const PaintLayer&);
- void UpdateTriggers();
-
- bool RequiresCompositingForScrollableFrame() const;
+ static bool RequiresCompositingForScrollableFrame(const LayoutView&);
static CompositingReasons CompositingReasonsForAnimation(
const ComputedStyle&);
static bool RequiresCompositingForOpacityAnimation(const ComputedStyle&);
@@ -52,12 +42,7 @@ class CORE_EXPORT CompositingReasonFinder {
static bool RequiresCompositingForTransform(const LayoutObject&);
static bool RequiresCompositingForRootScroller(const PaintLayer&);
- bool RequiresCompositingForScrollDependentPosition(
- const PaintLayer*,
- bool ignore_lcd_text) const;
-
- private:
- bool IsMainFrame() const;
+ static bool RequiresCompositingForScrollDependentPosition(const PaintLayer&);
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
index 3dd6e2789a9..263f277230b 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder_test.cc
@@ -94,40 +94,6 @@ TEST_F(CompositingReasonFinderTest, PromoteNonTrivial3DByDefault) {
EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState());
}
-TEST_F(CompositingReasonFinderTest, PromoteOpaqueFixedPosition) {
- ScopedCompositeOpaqueFixedPositionForTest composite_fixed_position(true);
-
- SetBodyInnerHTML(R"HTML(
- <div id='translucent' style='width: 20px; height: 20px; position:
- fixed; top: 100px; left: 100px;'></div>
- <div id='opaque' style='width: 20px; height: 20px; position: fixed;
- top: 100px; left: 200px; background: white;'></div>
- <div id='opaque-with-shadow' style='width: 20px; height: 20px;
- position: fixed; top: 100px; left: 300px; background: white;
- box-shadow: 10px 10px 5px #888888;'></div>
- <div id='spacer' style='height: 2000px'></div>
- )HTML");
-
- // The translucent fixed box should not be promoted.
- Element* element = GetDocument().getElementById("translucent");
- PaintLayer* paint_layer =
- ToLayoutBoxModelObject(element->GetLayoutObject())->Layer();
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-
- // The opaque fixed box should be promoted and be opaque so that text will be
- // drawn with subpixel anti-aliasing.
- element = GetDocument().getElementById("opaque");
- paint_layer = ToLayoutBoxModelObject(element->GetLayoutObject())->Layer();
- EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState());
- EXPECT_TRUE(paint_layer->GraphicsLayerBacking()->ContentsOpaque());
-
- // The opaque fixed box with shadow should not be promoted because the layer
- // will include the shadow which is not opaque.
- element = GetDocument().getElementById("opaque-with-shadow");
- paint_layer = ToLayoutBoxModelObject(element->GetLayoutObject())->Layer();
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-}
-
TEST_F(CompositingReasonFinderTest, OnlyAnchoredStickyPositionPromoted) {
SetBodyInnerHTML(R"HTML(
<style>
@@ -178,103 +144,6 @@ TEST_F(CompositingReasonFinderTest, OnlyScrollingStickyPositionPromoted) {
->GetCompositingState());
}
-// Tests that a transform on the fixed or an ancestor will prevent promotion
-// TODO(flackr): Allow integer transforms as long as all of the ancestor
-// transforms are also integer.
-TEST_F(CompositingReasonFinderTest, OnlyNonTransformedFixedLayersPromoted) {
- ScopedCompositeOpaqueFixedPositionForTest composite_fixed_position(true);
-
- SetBodyInnerHTML(R"HTML(
- <style>
- #fixed { position: fixed; height: 200px; width: 200px; background:
- white; top: 0; }
- #spacer { height: 3000px; }
- </style>
- <div id="parent">
- <div id="fixed"></div>
- <div id="spacer"></div>
- </div>
- )HTML");
-
- Element* parent = GetDocument().getElementById("parent");
- Element* fixed = GetDocument().getElementById("fixed");
- PaintLayer* paint_layer =
- ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState());
- EXPECT_TRUE(paint_layer->GraphicsLayerBacking()->ContentsOpaque());
-
- // Change the parent to have a transform.
- parent->setAttribute(html_names::kStyleAttr, "transform: translate(1px, 0);");
- UpdateAllLifecyclePhasesForTest();
- paint_layer = ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-
- // Change the parent to have no transform again.
- parent->removeAttribute(html_names::kStyleAttr);
- UpdateAllLifecyclePhasesForTest();
- paint_layer = ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState());
- EXPECT_TRUE(paint_layer->GraphicsLayerBacking()->ContentsOpaque());
-
- // Apply a transform to the fixed directly.
- fixed->setAttribute(html_names::kStyleAttr, "transform: translate(1px, 0);");
- UpdateAllLifecyclePhasesForTest();
- paint_layer = ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-}
-
-// Test that opacity applied to the fixed or an ancestor will cause the
-// scrolling contents layer to not be promoted.
-TEST_F(CompositingReasonFinderTest, OnlyOpaqueFixedLayersPromoted) {
- ScopedCompositeOpaqueFixedPositionForTest composite_fixed_position(true);
-
- SetBodyInnerHTML(R"HTML(
- <style>
- #fixed { position: fixed; height: 200px; width: 200px; background:
- white; top: 0}
- #spacer { height: 3000px; }
- </style>
- <div id="parent">
- <div id="fixed"></div>
- <div id="spacer"></div>
- </div>
- )HTML");
-
- Element* parent = GetDocument().getElementById("parent");
- Element* fixed = GetDocument().getElementById("fixed");
- PaintLayer* paint_layer =
- ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState());
- EXPECT_TRUE(paint_layer->GraphicsLayerBacking()->ContentsOpaque());
-
- // Change the parent to be partially translucent.
- parent->setAttribute(html_names::kStyleAttr, "opacity: 0.5;");
- UpdateAllLifecyclePhasesForTest();
- paint_layer = ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-
- // Change the parent to be opaque again.
- parent->setAttribute(html_names::kStyleAttr, "opacity: 1;");
- UpdateAllLifecyclePhasesForTest();
- paint_layer = ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kPaintsIntoOwnBacking, paint_layer->GetCompositingState());
- EXPECT_TRUE(paint_layer->GraphicsLayerBacking()->ContentsOpaque());
-
- // Make the fixed translucent.
- fixed->setAttribute(html_names::kStyleAttr, "opacity: 0.5");
- UpdateAllLifecyclePhasesForTest();
- paint_layer = ToLayoutBoxModelObject(fixed->GetLayoutObject())->Layer();
- ASSERT_TRUE(paint_layer);
- EXPECT_EQ(kNotComposited, paint_layer->GetCompositingState());
-}
-
TEST_F(CompositingReasonFinderTest, RequiresCompositingForTransformAnimation) {
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
style->SetSubtreeWillChangeContents(false);
@@ -362,38 +231,6 @@ TEST_F(CompositingReasonFinderTest, CompositingReasonsForAnimation) {
CompositingReasonFinder::CompositingReasonsForAnimation(*style));
}
-TEST_F(CompositingReasonFinderTest, CompositeNestedSticky) {
- ScopedCompositeOpaqueFixedPositionForTest composite_fixed_position(true);
-
- SetBodyInnerHTML(R"HTML(
- <style>.scroller { overflow: scroll; height: 200px; width: 100px; }
- .container { height: 500px; }
- .opaque { background-color: white; contain: paint; }
- #outerSticky { height: 50px; position: sticky; top: 0px; }
- #innerSticky { height: 20px; position: sticky; top: 25px; }</style>
- <div class='scroller'>
- <div class='container'>
- <div id='outerSticky' class='opaque'>
- <div id='innerSticky' class='opaque'></div>
- </div>
- </div>
- </div>
- )HTML");
-
- Element* outer_sticky = GetDocument().getElementById("outerSticky");
- PaintLayer* outer_sticky_layer =
- ToLayoutBoxModelObject(outer_sticky->GetLayoutObject())->Layer();
- ASSERT_TRUE(outer_sticky_layer);
-
- Element* inner_sticky = GetDocument().getElementById("innerSticky");
- PaintLayer* inner_sticky_layer =
- ToLayoutBoxModelObject(inner_sticky->GetLayoutObject())->Layer();
- ASSERT_TRUE(inner_sticky_layer);
-
- EXPECT_EQ(kPaintsIntoOwnBacking, outer_sticky_layer->GetCompositingState());
- EXPECT_EQ(kPaintsIntoOwnBacking, inner_sticky_layer->GetCompositingState());
-}
-
TEST_F(CompositingReasonFinderTest, DontPromoteEmptyIframe) {
GetDocument().GetFrame()->GetSettings()->SetPreferCompositingToLCDTextEnabled(
true);
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
index 1fa0a141872..12aa542fa4a 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.cc
@@ -167,7 +167,6 @@ static bool RequiresCompositingOrSquashing(CompositingReasons reasons) {
}
static CompositingReasons SubtreeReasonsForCompositing(
- const CompositingReasonFinder& compositing_reason_finder,
PaintLayer* layer,
bool has_composited_descendants,
bool has3d_transformed_descendants) {
@@ -186,19 +185,6 @@ static CompositingReasons SubtreeReasonsForCompositing(
subtree_reasons |= CompositingReason::kIsolateCompositedDescendants;
}
- // We ignore LCD text here because we are required to composite
- // scroll-dependant fixed position elements with composited descendants for
- // correctness - even if we lose LCD.
- //
- // TODO(smcgruer): Only composite fixed if needed (http://crbug.com/742213)
- const bool ignore_lcd_text = true;
- if (layer->GetLayoutObject().StyleRef().GetPosition() == EPosition::kFixed ||
- compositing_reason_finder.RequiresCompositingForScrollDependentPosition(
- layer, ignore_lcd_text)) {
- subtree_reasons |=
- CompositingReason::kPositionFixedOrStickyWithCompositedDescendants;
- }
-
// A layer with preserve-3d or perspective only needs to be composited if
// there are descendant layers that will be affected by the preserve-3d or
// perspective.
@@ -211,10 +197,8 @@ static CompositingReasons SubtreeReasonsForCompositing(
}
CompositingRequirementsUpdater::CompositingRequirementsUpdater(
- LayoutView& layout_view,
- CompositingReasonFinder& compositing_reason_finder)
- : layout_view_(layout_view),
- compositing_reason_finder_(compositing_reason_finder) {}
+ LayoutView& layout_view)
+ : layout_view_(layout_view) {}
CompositingRequirementsUpdater::~CompositingRequirementsUpdater() = default;
@@ -287,38 +271,19 @@ void CompositingRequirementsUpdater::UpdateRecursive(
bool use_clipped_bounding_rect = !has_non_root_composited_scrolling_ancestor;
- // We have to promote the sticky element to work around the bug
- // (https://crbug.com/698358) of not being able to invalidate the ancestor
- // after updating the sticky layer position.
- // TODO(yigu): We should check if we have already lost lcd text. This
- // would require tracking if we think the current compositing ancestor
- // layer meets the requirements (i.e. opaque, integer transform, etc).
- const bool moves_with_respect_to_compositing_ancestor =
- layer->SticksToScroller() &&
- !current_recursion_data.compositing_ancestor_->IsRootLayer();
- const bool ignore_lcd_text = has_non_root_composited_scrolling_ancestor;
-
const bool layer_can_be_composited = compositor->CanBeComposited(layer);
CompositingReasons direct_from_paint_layer = 0;
if (layer_can_be_composited)
direct_from_paint_layer = layer->DirectCompositingReasons();
- if (compositing_reason_finder_.RequiresCompositingForScrollDependentPosition(
- layer,
- ignore_lcd_text || moves_with_respect_to_compositing_ancestor)) {
- direct_from_paint_layer |= CompositingReason::kScrollDependentPosition;
- }
-
#if DCHECK_IS_ON()
if (layer_can_be_composited) {
DCHECK(direct_from_paint_layer ==
- compositing_reason_finder_.DirectReasons(
- layer,
- ignore_lcd_text || moves_with_respect_to_compositing_ancestor))
+ CompositingReasonFinder::DirectReasons(*layer))
<< " Expected: "
<< CompositingReason::ToString(
- compositing_reason_finder_.DirectReasons(layer, ignore_lcd_text))
+ CompositingReasonFinder::DirectReasons(*layer))
<< " Actual: " << CompositingReason::ToString(direct_from_paint_layer);
}
#endif
@@ -591,8 +556,7 @@ void CompositingRequirementsUpdater::UpdateRecursive(
// descendant layers.
CompositingReasons subtree_compositing_reasons =
SubtreeReasonsForCompositing(
- compositing_reason_finder_, layer,
- child_recursion_data.subtree_is_compositing_,
+ layer, child_recursion_data.subtree_is_compositing_,
any_descendant_has3d_transform);
if (layer_can_be_composited)
reasons_to_composite |= subtree_compositing_reasons;
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
index 9419f90c76e..81b6e8580a8 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater.h
@@ -34,7 +34,6 @@
namespace blink {
-class CompositingReasonFinder;
class PaintLayer;
class LayoutView;
@@ -42,7 +41,7 @@ class CompositingRequirementsUpdater {
STACK_ALLOCATED();
public:
- CompositingRequirementsUpdater(LayoutView&, CompositingReasonFinder&);
+ CompositingRequirementsUpdater(LayoutView&);
~CompositingRequirementsUpdater();
// Recurse through the layers in z-index and overflow order (which is
@@ -72,7 +71,6 @@ class CompositingRequirementsUpdater {
CompositingReasonsStats&);
LayoutView& layout_view_;
- CompositingReasonFinder& compositing_reason_finder_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
index 5d3bedb33f0..fb10734686d 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_requirements_updater_test.cc
@@ -24,30 +24,6 @@ void CompositingRequirementsUpdaterTest::SetUp() {
EnableCompositing();
}
-TEST_F(CompositingRequirementsUpdaterTest, FixedPosOverlap) {
- SetBodyInnerHTML(R"HTML(
- <div style="position: relative; width: 500px; height: 300px;
- will-change: transform"></div>
- <div id=fixed style="position: fixed; width: 500px; height: 300px;
- top: 300px"></div>
- <div style="width: 200px; height: 3000px"></div>
- )HTML");
-
- LayoutBoxModelObject* fixed =
- ToLayoutBoxModelObject(GetLayoutObjectByElementId("fixed"));
-
- EXPECT_EQ(
- CompositingReason::kOverlap | CompositingReason::kSquashingDisallowed,
- fixed->Layer()->GetCompositingReasons());
-
- GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 100),
- kUserScroll);
- UpdateAllLifecyclePhasesForTest();
-
- // No longer overlaps the first div.
- EXPECT_EQ(CompositingReason::kNone, fixed->Layer()->GetCompositingReasons());
-}
-
TEST_F(CompositingRequirementsUpdaterTest,
NoOverlapReasonForNonSelfPaintingLayer) {
SetBodyInnerHTML(R"HTML(
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_triggers.h b/chromium/third_party/blink/renderer/core/paint/compositing/compositing_triggers.h
deleted file mode 100644
index 4e2d3786cda..00000000000
--- a/chromium/third_party/blink/renderer/core/paint/compositing/compositing_triggers.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple, Inc. All rights
- * reserved.
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
- * Copyright (C) 2012 Samsung Electronics. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_TRIGGERS_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_COMPOSITING_COMPOSITING_TRIGGERS_H_
-
-namespace blink {
-
-enum CompositingTrigger {
- kScrollableInnerFrameTrigger = 1 << 1,
- kOverflowScrollTrigger = 1 << 2,
- kViewportConstrainedPositionedTrigger = 1 << 3,
- kAllCompositingTriggers = 0xFFFFFFFF,
-};
-
-typedef unsigned CompositingTriggerFlags;
-
-} // namespace blink
-
-#endif
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 9b5cc2e6066..6111fe693fb 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
@@ -68,7 +68,6 @@ namespace blink {
PaintLayerCompositor::PaintLayerCompositor(LayoutView& layout_view)
: layout_view_(layout_view),
- compositing_reason_finder_(layout_view),
pending_update_type_(kCompositingUpdateNone),
has_accelerated_compositing_(true),
compositing_(false),
@@ -132,11 +131,11 @@ bool PaintLayerCompositor::RootShouldAlwaysComposite() const {
if (!has_accelerated_compositing_)
return false;
return layout_view_.GetFrame()->IsLocalRoot() ||
- compositing_reason_finder_.RequiresCompositingForScrollableFrame();
+ CompositingReasonFinder::RequiresCompositingForScrollableFrame(
+ layout_view_);
}
void PaintLayerCompositor::UpdateAcceleratedCompositingSettings() {
- compositing_reason_finder_.UpdateTriggers();
has_accelerated_compositing_ = layout_view_.GetDocument()
.GetSettings()
->GetAcceleratedCompositingEnabled();
@@ -182,10 +181,10 @@ void PaintLayerCompositor::UpdateIfNeededRecursive(
compositing_reasons_stats.active_animation_layers, 1, 100, 5);
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Blink.Compositing.LayerPromotionCount.AssumedOverlap",
- compositing_reasons_stats.assumed_overlap_layers, 1, 100, 5);
+ compositing_reasons_stats.assumed_overlap_layers, 1, 1000, 5);
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Blink.Compositing.LayerPromotionCount.IndirectComposited",
- compositing_reasons_stats.indirect_composited_layers, 1, 100, 5);
+ compositing_reasons_stats.indirect_composited_layers, 1, 1000, 5);
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Blink.Compositing.LayerPromotionCount.TotalComposited",
compositing_reasons_stats.total_composited_layers, 1, 1000, 10);
@@ -233,7 +232,13 @@ void PaintLayerCompositor::UpdateIfNeededRecursiveInternal(
// InCompositingUpdate.
EnableCompositingModeIfNeeded();
+#if DCHECK_IS_ON()
+ view->SetIsUpdatingDescendantDependentFlags(true);
+#endif
RootLayer()->UpdateDescendantDependentFlags();
+#if DCHECK_IS_ON()
+ view->SetIsUpdatingDescendantDependentFlags(false);
+#endif
layout_view_.CommitPendingSelection();
@@ -252,9 +257,9 @@ void PaintLayerCompositor::UpdateIfNeededRecursiveInternal(
if (!layout_view_.GetDocument().Printing() ||
RuntimeEnabledFeatures::PrintBrowserEnabled()) {
// Although BlinkGenPropertyTreesEnabled still uses PaintLayerCompositor to
- // generate the composited layer tree/list, it also has the SPv2 behavior of
+ // generate the composited layer tree/list, it also has the CAP behavior of
// removing layers that do not draw content. As such, we use the same path
- // as SPv2 for updating composited animations once we know the final set of
+ // as CAP for updating composited animations once we know the final set of
// composited elements (see LocalFrameView::UpdateLifecyclePhasesInternal,
// during kPaintClean).
if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
@@ -301,6 +306,10 @@ void PaintLayerCompositor::SetNeedsCompositingUpdate(
pending_update_type_ = std::max(pending_update_type_, update_type);
if (Page* page = GetPage())
page->Animator().ScheduleVisualUpdate(layout_view_.GetFrame());
+
+ if (layout_view_.DocumentBeingDestroyed())
+ return;
+
Lifecycle().EnsureStateAtMost(DocumentLifecycle::kLayoutClean);
}
@@ -367,7 +376,7 @@ void PaintLayerCompositor::UpdateWithoutAcceleratedCompositing(
DCHECK(!HasAcceleratedCompositing());
if (update_type >= kCompositingUpdateAfterCompositingInputChange)
- CompositingInputsUpdater(RootLayer(), compositing_reason_finder_).Update();
+ CompositingInputsUpdater(RootLayer()).Update();
#if DCHECK_IS_ON()
CompositingInputsUpdater::AssertNeedsCompositingInputsUpdateBitsCleared(
@@ -453,7 +462,7 @@ void PaintLayerCompositor::UpdateIfNeeded(
Vector<PaintLayer*> layers_needing_paint_invalidation;
if (update_type >= kCompositingUpdateAfterCompositingInputChange) {
- CompositingInputsUpdater(update_root, compositing_reason_finder_).Update();
+ CompositingInputsUpdater(update_root).Update();
#if DCHECK_IS_ON()
// FIXME: Move this check to the end of the compositing update.
@@ -471,7 +480,7 @@ void PaintLayerCompositor::UpdateIfNeeded(
return;
}
- CompositingRequirementsUpdater(layout_view_, compositing_reason_finder_)
+ CompositingRequirementsUpdater(layout_view_)
.Update(update_root, compositing_reasons_stats);
CompositingLayerAssigner layer_assigner(this);
@@ -545,13 +554,10 @@ void PaintLayerCompositor::UpdateIfNeeded(
layers_needing_paint_invalidation[i]->GetLayoutObject());
}
- if (root_layer_attachment_ == kRootLayerPendingAttachViaChromeClient) {
- if (Page* page = layout_view_.GetFrame()->GetPage()) {
- page->GetChromeClient().AttachRootGraphicsLayer(RootGraphicsLayer(),
- layout_view_.GetFrame());
- root_layer_attachment_ = kRootLayerAttachedViaChromeClient;
- }
- }
+ // When BlinkGenPropertyTrees is enabled, layer attachment, including the root
+ // layer, must occur in the paint lifecycle step.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ AttachRootLayerViaChromeClient();
// Inform the inspector that the layer tree has changed.
if (IsMainFrame())
@@ -560,6 +566,16 @@ void PaintLayerCompositor::UpdateIfNeeded(
Lifecycle().AdvanceTo(DocumentLifecycle::kCompositingClean);
}
+void PaintLayerCompositor::AttachRootLayerViaChromeClient() {
+ if (root_layer_attachment_ == kRootLayerPendingAttachViaChromeClient) {
+ if (Page* page = layout_view_.GetFrame()->GetPage()) {
+ page->GetChromeClient().AttachRootGraphicsLayer(RootGraphicsLayer(),
+ layout_view_.GetFrame());
+ }
+ root_layer_attachment_ = kRootLayerAttachedViaChromeClient;
+ }
+}
+
static void RestartAnimationOnCompositor(const LayoutObject& layout_object) {
Node* node = layout_object.GetNode();
ElementAnimations* element_animations =
@@ -783,9 +799,9 @@ void PaintLayerCompositor::SetIsInWindow(bool is_in_window) {
void PaintLayerCompositor::UpdatePotentialCompositingReasonsFromStyle(
PaintLayer& layer) {
- layer.SetPotentialCompositingReasonsFromStyle(
- compositing_reason_finder_.PotentialCompositingReasonsFromStyle(
- layer.GetLayoutObject()));
+ auto reasons = CompositingReasonFinder::PotentialCompositingReasonsFromStyle(
+ layer.GetLayoutObject());
+ layer.SetPotentialCompositingReasonsFromStyle(reasons);
}
bool PaintLayerCompositor::CanBeComposited(const PaintLayer* layer) const {
@@ -796,7 +812,7 @@ bool PaintLayerCompositor::CanBeComposited(const PaintLayer* layer) const {
return false;
const bool has_compositor_animation =
- compositing_reason_finder_.CompositingReasonsForAnimation(
+ CompositingReasonFinder::CompositingReasonsForAnimation(
*layer->GetLayoutObject().Style()) != CompositingReason::kNone;
return has_accelerated_compositing_ &&
(has_compositor_animation || !layer->SubtreeIsInvisible()) &&
@@ -877,9 +893,9 @@ void PaintLayerCompositor::DestroyRootLayer() {
}
void PaintLayerCompositor::AttachRootLayer() {
- // In Slimming Paint v2, PaintArtifactCompositor is responsible for the root
- // layer.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ // With CompositeAfterPaint, PaintArtifactCompositor is responsible for the
+ // root layer.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
if (layout_view_.GetFrame()->IsLocalRoot()) {
diff --git a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
index 7cf3856bd75..9a6efefd298 100644
--- a/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
+++ b/chromium/third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h
@@ -65,7 +65,7 @@ enum CompositingStateTransitionType {
// decides for each PaintLayer whether it should get a CompositedLayerMapping,
// and asks each CLM to set up its GraphicsLayers.
//
-// In Slimming Paint v2, PaintLayerCompositor will be eventually replaced by
+// With CompositeAfterPaint, PaintLayerCompositor will be eventually replaced by
// PaintArtifactCompositor.
class CORE_EXPORT PaintLayerCompositor {
@@ -156,6 +156,8 @@ class CORE_EXPORT PaintLayerCompositor {
bool IsRootScrollerAncestor() const;
+ void AttachRootLayerViaChromeClient();
+
private:
#if DCHECK_IS_ON()
void AssertNoUnresolvedDirtyBits();
@@ -200,8 +202,6 @@ class CORE_EXPORT PaintLayerCompositor {
LayoutView& layout_view_;
- CompositingReasonFinder compositing_reason_finder_;
-
CompositingUpdateType pending_update_type_;
bool has_accelerated_compositing_;
diff --git a/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc b/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc
index 40063a379c1..4c4954f8941 100644
--- a/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/document_marker_painter.cc
@@ -60,6 +60,8 @@ sk_sp<PaintRecord> RecordMarker(Color blink_color) {
static const float kMarkerWidth = 4;
static const float kMarkerHeight = 3;
+// Spacing between two dots.
+static const float kMarkerSpacing = 1;
sk_sp<PaintRecord> RecordMarker(Color blink_color) {
const SkColor color = blink_color.Rgb();
@@ -116,10 +118,8 @@ void DrawDocumentMarker(GraphicsContext& context,
#if defined(OS_MACOSX)
// Make sure to draw only complete dots, and finish inside the marked text.
- width -= fmodf(width, kMarkerWidth * zoom);
-#else
- // Offset it vertically by 1 so that there's some space under the text.
- origin_y += 1;
+ float spacing = kMarkerSpacing * zoom;
+ width -= fmodf(width + spacing, kMarkerWidth * zoom) - spacing;
#endif
const auto rect = SkRect::MakeWH(width, kMarkerHeight * zoom);
@@ -164,19 +164,20 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
start += 1;
width -= 2;
- // Thick marked text underlines are 2px thick as long as there is room for the
- // 2px line under the baseline. All other marked text underlines are 1px
- // thick. If there's not enough space the underline will touch or overlap
- // characters.
- int line_thickness = 1;
+ // Thick marked text underlines are 2px (before zoom) thick as long as there
+ // is room for the 2px line under the baseline. All other marked text
+ // underlines are 1px (before zoom) thick. If there's not enough space the
+ // underline will touch or overlap characters. Line thickness should change
+ // with zoom.
+ int line_thickness = 1 * style.EffectiveZoom();
const SimpleFontData* font_data = style.GetFont().PrimaryFont();
DCHECK(font_data);
int baseline = font_data ? font_data->GetFontMetrics().Ascent() : 0;
- if (marker.HasThicknessThick() && logical_height.ToInt() - baseline >= 2)
- line_thickness = 2;
-
- // Line thickness should change with zoom.
- line_thickness *= style.EffectiveZoom();
+ if (marker.HasThicknessThick()) {
+ int thick_line_thickness = 2 * style.EffectiveZoom();
+ if (logical_height.ToInt() - baseline >= thick_line_thickness)
+ line_thickness = thick_line_thickness;
+ }
Color marker_color =
marker.UseTextColor()
@@ -192,8 +193,6 @@ void DocumentMarkerPainter::PaintStyleableMarkerUnderline(
width);
}
-static const int kMisspellingLineThickness = 3;
-
void DocumentMarkerPainter::PaintDocumentMarker(
GraphicsContext& context,
const LayoutPoint& box_origin,
@@ -208,26 +207,28 @@ void DocumentMarkerPainter::PaintDocumentMarker(
// actually the most useful, and matches what AppKit does. So, we generally
// place the underline at the bottom of the text, but in larger fonts that's
// not so good so we pin to two pixels under the baseline.
- int line_thickness = kMisspellingLineThickness;
+ float zoom = style.EffectiveZoom();
+ int line_thickness = kMarkerHeight * zoom;
const SimpleFontData* font_data = style.GetFont().PrimaryFont();
DCHECK(font_data);
int baseline = font_data->GetFontMetrics().Ascent();
- int descent = (local_rect.Height() - baseline).ToInt();
+ int available_height = (local_rect.Height() - baseline).ToInt();
int underline_offset;
- if (descent <= (line_thickness + 2)) {
+ if (available_height <= line_thickness + 2 * zoom) {
// Place the underline at the very bottom of the text in small/medium fonts.
+ // The underline will overlap with the bottom of the text if
+ // available_height is smaller than line_thickness.
underline_offset = (local_rect.Height() - line_thickness).ToInt();
} else {
// In larger fonts, though, place the underline up near the baseline to
// prevent a big gap.
- underline_offset = baseline + 2;
+ underline_offset = baseline + 2 * zoom;
}
DrawDocumentMarker(context,
FloatPoint((box_origin.X() + local_rect.X()).ToFloat(),
(box_origin.Y() + underline_offset).ToFloat()),
- local_rect.Width().ToFloat(), marker_type,
- style.EffectiveZoom());
+ local_rect.Width().ToFloat(), marker_type, zoom);
}
TextPaintStyle DocumentMarkerPainter::ComputeTextPaintStyleFrom(
diff --git a/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc
index 8af38dfac51..e506970c225 100644
--- a/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/embedded_object_painter.cc
@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/platform/fonts/font.h"
#include "third_party/blink/renderer/platform/fonts/font_selector.h"
#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h"
-#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
#include "third_party/blink/renderer/platform/text/text_run.h"
@@ -55,8 +54,6 @@ void EmbeddedObjectPainter::PaintReplaced(const PaintInfo& paint_info,
LayoutRect content_rect(layout_embedded_object_.PhysicalContentBoxRect());
content_rect.MoveBy(paint_offset);
DrawingRecorder recorder(context, layout_embedded_object_, paint_info.phase);
- GraphicsContextStateSaver state_saver(context);
- context.Clip(PixelSnappedIntRect(content_rect));
Font font = ReplacementTextFont();
const SimpleFontData* font_data = font.PrimaryFont();
diff --git a/chromium/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h b/chromium/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h
index ae53517b4b4..f916c83c352 100644
--- a/chromium/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h
+++ b/chromium/third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h
@@ -108,7 +108,7 @@ class FindVisualRectNeedingUpdateScopeBase {
// while we need neither paint invalidation nor raster invalidation
// for the change. This may miss some real subpixel changes of visual
// rects. TODO(wangxianzhu): Look into whether we can tighten this
- // for SPv2.
+ // for CAP.
(InflatedRect(old_visual_rect_).Contains(new_visual_rect) &&
InflatedRect(new_visual_rect).Contains(old_visual_rect_)))
<< "Visual rect changed without needing update"
diff --git a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
index 6f5f27e01ec..4218e90351d 100644
--- a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.cc
@@ -152,8 +152,7 @@ void FirstMeaningfulPaintDetector::OnNetwork2Quiet() {
if (defer_first_meaningful_paint_ == kDoNotDefer) {
// Report FirstMeaningfulPaint when the page reached network 2-quiet if
// we aren't waiting for a swap timestamp.
- SetFirstMeaningfulPaint(first_meaningful_paint2_quiet_,
- first_meaningful_paint2_quiet_swap);
+ SetFirstMeaningfulPaint(first_meaningful_paint2_quiet_swap);
}
}
ReportHistograms();
@@ -248,8 +247,7 @@ void FirstMeaningfulPaintDetector::ReportSwapTime(
if (defer_first_meaningful_paint_ == kDeferOutstandingSwapPromises &&
outstanding_swap_promise_count_ == 0) {
DCHECK(!first_meaningful_paint2_quiet_.is_null());
- SetFirstMeaningfulPaint(first_meaningful_paint2_quiet_,
- provisional_first_meaningful_paint_swap_);
+ SetFirstMeaningfulPaint(provisional_first_meaningful_paint_swap_);
}
}
@@ -257,11 +255,10 @@ void FirstMeaningfulPaintDetector::NotifyFirstContentfulPaint(
TimeTicks swap_stamp) {
if (defer_first_meaningful_paint_ != kDeferFirstContentfulPaintNotSet)
return;
- SetFirstMeaningfulPaint(first_meaningful_paint2_quiet_, swap_stamp);
+ SetFirstMeaningfulPaint(swap_stamp);
}
void FirstMeaningfulPaintDetector::SetFirstMeaningfulPaint(
- TimeTicks stamp,
TimeTicks swap_stamp) {
DCHECK(paint_timing_->FirstMeaningfulPaint().is_null());
DCHECK(!swap_stamp.is_null());
@@ -276,8 +273,7 @@ void FirstMeaningfulPaintDetector::SetFirstMeaningfulPaint(
paint_timing_->SetFirstMeaningfulPaintCandidate(swap_stamp);
paint_timing_->SetFirstMeaningfulPaint(
- stamp, swap_stamp,
- had_user_input_before_provisional_first_meaningful_paint_);
+ swap_stamp, had_user_input_before_provisional_first_meaningful_paint_);
}
void FirstMeaningfulPaintDetector::Trace(blink::Visitor* visitor) {
diff --git a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
index 43af42982ac..27310dcf94b 100644
--- a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector.h
@@ -61,7 +61,7 @@ class CORE_EXPORT FirstMeaningfulPaintDetector
int ActiveConnections();
void ReportHistograms();
void RegisterNotifySwapTime(PaintEvent);
- void SetFirstMeaningfulPaint(TimeTicks stamp, TimeTicks swap_stamp);
+ void SetFirstMeaningfulPaint(TimeTicks swap_stamp);
bool next_paint_is_meaningful_ = false;
HadUserInput had_user_input_ = kNoUserInput;
diff --git a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
index 888ceb29575..5a0f42e3e1d 100644
--- a/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/first_meaningful_paint_detector_test.cc
@@ -109,7 +109,6 @@ TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) {
SimulateLayoutAndPaint(1);
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U);
SimulateNetworkStable();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
}
@@ -119,14 +118,8 @@ TEST_F(FirstMeaningfulPaintDetectorTest, OneLayout) {
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
ClearProvisionalFirstMeaningfulPaintSwapPromise();
TimeTicks after_paint = AdvanceClockAndGetTime();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
SimulateNetworkStable();
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(),
- GetPaintTiming().FirstPaintRendered());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
- EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_paint);
EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_paint);
}
@@ -141,12 +134,8 @@ TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantSecond) {
ClearProvisionalFirstMeaningfulPaintSwapPromise();
TimeTicks after_layout2 = AdvanceClockAndGetTime();
SimulateNetworkStable();
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_layout1);
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_layout1);
- EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_layout2);
EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_layout2);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantFirst) {
@@ -158,11 +147,8 @@ TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantFirst) {
SimulateLayoutAndPaint(1);
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U);
SimulateNetworkStable();
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(),
- GetPaintTiming().FirstPaintRendered());
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
GetPaintTiming().FirstPaintRendered());
- EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_layout1);
EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_layout1);
}
@@ -215,14 +201,10 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
ClearProvisionalFirstMeaningfulPaintSwapPromise();
SimulateNetworkStable();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
MarkFirstContentfulPaintAndClearSwapPromise();
SimulateNetworkStable();
- EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_NE(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest,
@@ -234,12 +216,8 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
MarkFirstContentfulPaintAndClearSwapPromise();
SimulateNetworkStable();
- EXPECT_GE(GetPaintTiming().FirstMeaningfulPaintRendered(),
- GetPaintTiming().FirstContentfulPaintRendered());
EXPECT_GE(GetPaintTiming().FirstMeaningfulPaint(),
GetPaintTiming().FirstContentfulPaint());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietThen0Quiet) {
@@ -257,13 +235,9 @@ TEST_F(FirstMeaningfulPaintDetectorTest, Network2QuietThen0Quiet) {
SimulateNetwork0Quiet();
// The first paint is FirstMeaningfulPaint.
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
- EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_first_paint);
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint);
EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint_swap);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) {
@@ -282,15 +256,8 @@ TEST_F(FirstMeaningfulPaintDetectorTest, Network0QuietThen2Quiet) {
SimulateNetwork2Quiet();
// The second paint is FirstMeaningfulPaint.
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), after_first_paint);
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_first_paint);
- EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(),
- after_second_paint);
EXPECT_LT(GetPaintTiming().FirstMeaningfulPaint(), after_second_paint);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest,
@@ -301,7 +268,6 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
ClearProvisionalFirstMeaningfulPaintSwapPromise();
SimulateNetworkStable();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
}
@@ -312,10 +278,7 @@ TEST_F(FirstMeaningfulPaintDetectorTest, UserInteractionBeforeFirstPaint) {
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
ClearProvisionalFirstMeaningfulPaintSwapPromise();
SimulateNetworkStable();
- EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_NE(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest,
@@ -324,13 +287,9 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
SimulateLayoutAndPaint(10);
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
SimulateNetworkStable();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
ClearProvisionalFirstMeaningfulPaintSwapPromise();
- EXPECT_NE(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_NE(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest,
@@ -343,22 +302,17 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 2U);
// Having outstanding swap promises should defer setting FMP.
SimulateNetworkStable();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
// Clearing the first swap promise should have no effect on FMP.
ClearProvisionalFirstMeaningfulPaintSwapPromise();
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
TimeTicks after_first_swap = AdvanceClockAndGetTime();
// Clearing the last outstanding swap promise should set FMP.
ClearProvisionalFirstMeaningfulPaintSwapPromise();
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), after_first_swap);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest,
@@ -367,25 +321,16 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
SimulateLayoutAndPaint(10);
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 1U);
ClearProvisionalFirstMeaningfulPaintSwapPromise();
- TimeTicks after_first_meaningful_paint_candidate = AdvanceClockAndGetTime();
platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
GetPaintTiming().MarkFirstContentfulPaint();
// FCP > FMP candidate, but still waiting for FCP swap.
SimulateNetworkStable();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
// Trigger notifying the detector about the FCP swap.
ClearFirstContentfulPaintSwapPromise();
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(),
- GetPaintTiming().FirstContentfulPaintRendered());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(),
GetPaintTiming().FirstContentfulPaint());
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(),
- after_first_meaningful_paint_candidate);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(),
- GetPaintTiming().FirstMeaningfulPaintRendered());
}
TEST_F(FirstMeaningfulPaintDetectorTest,
@@ -399,7 +344,6 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
TimeTicks pre_stable_timestamp = AdvanceClockAndGetTime();
platform_->AdvanceClock(TimeDelta::FromMilliseconds(1));
SimulateNetwork2Quiet();
- EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
// Force another FMP candidate while there is a pending swap promise and the
@@ -413,11 +357,8 @@ TEST_F(FirstMeaningfulPaintDetectorTest,
// non-swap timestamp is used.
ClearProvisionalFirstMeaningfulPaintSwapPromise(pre_stable_timestamp);
EXPECT_EQ(OutstandingDetectorSwapPromiseCount(), 0U);
- EXPECT_GT(GetPaintTiming().FirstMeaningfulPaintRendered(), TimeTicks());
EXPECT_GT(GetPaintTiming().FirstMeaningfulPaint(), TimeTicks());
EXPECT_EQ(GetPaintTiming().FirstMeaningfulPaint(), pre_stable_timestamp);
- EXPECT_LT(GetPaintTiming().FirstMeaningfulPaintRendered(),
- pre_stable_timestamp);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/frame_painter.cc b/chromium/third_party/blink/renderer/core/paint/frame_painter.cc
index 52e06dff7a7..38b39e3dc6c 100644
--- a/chromium/third_party/blink/renderer/core/paint/frame_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -25,25 +25,25 @@ bool FramePainter::in_paint_contents_ = false;
void FramePainter::Paint(GraphicsContext& context,
const GlobalPaintFlags global_paint_flags,
- const CullRect& rect) {
+ const CullRect& cull_rect) {
if (GetFrameView().ShouldThrottleRendering())
return;
GetFrameView().NotifyPageThatContentAreaWillPaint();
- IntRect document_dirty_rect(rect.Rect());
- document_dirty_rect.Intersect(GetFrameView().FrameRect());
- document_dirty_rect.MoveBy(-GetFrameView().Location());
+ CullRect document_cull_rect(
+ Intersection(cull_rect.Rect(), GetFrameView().FrameRect()));
+ document_cull_rect.MoveBy(-GetFrameView().Location());
- if (document_dirty_rect.IsEmpty())
+ if (document_cull_rect.Rect().IsEmpty())
return;
- PaintContents(context, global_paint_flags, document_dirty_rect);
+ PaintContents(context, global_paint_flags, document_cull_rect);
}
void FramePainter::PaintContents(GraphicsContext& context,
const GlobalPaintFlags global_paint_flags,
- const IntRect& rect) {
+ const CullRect& cull_rect) {
Document* document = GetFrameView().GetFrame().GetDocument();
if (GetFrameView().ShouldThrottleRendering() || !document->IsActive())
@@ -66,9 +66,9 @@ void FramePainter::PaintContents(GraphicsContext& context,
DocumentLifecycle::kCompositingClean);
FramePaintTiming frame_paint_timing(context, &GetFrameView().GetFrame());
- TRACE_EVENT1(
- "devtools.timeline,rail", "Paint", "data",
- inspector_paint_event::Data(layout_view, LayoutRect(rect), nullptr));
+ TRACE_EVENT1("devtools.timeline,rail", "Paint", "data",
+ inspector_paint_event::Data(
+ layout_view, LayoutRect(cull_rect.Rect()), nullptr));
bool is_top_level_painter = !in_paint_contents_;
in_paint_contents_ = true;
@@ -101,11 +101,11 @@ void FramePainter::PaintContents(GraphicsContext& context,
root_layer->GetLayoutObject().GetFrame());
context.SetDeviceScaleFactor(device_scale_factor);
- layer_painter.Paint(context, CullRect(rect), updated_global_paint_flags,
+ layer_painter.Paint(context, cull_rect, updated_global_paint_flags,
root_layer_paint_flags);
if (root_layer->ContainsDirtyOverlayScrollbars()) {
- layer_painter.PaintOverlayScrollbars(context, CullRect(rect),
+ layer_painter.PaintOverlayScrollbars(context, cull_rect,
updated_global_paint_flags);
}
@@ -121,7 +121,8 @@ void FramePainter::PaintContents(GraphicsContext& context,
in_paint_contents_ = false;
}
- probe::didPaint(layout_view->GetFrame(), nullptr, context, LayoutRect(rect));
+ probe::didPaint(layout_view->GetFrame(), nullptr, context,
+ LayoutRect(cull_rect.Rect()));
}
const LocalFrameView& FramePainter::GetFrameView() {
diff --git a/chromium/third_party/blink/renderer/core/paint/frame_painter.h b/chromium/third_party/blink/renderer/core/paint/frame_painter.h
index cf756c96740..05c33f8fba5 100644
--- a/chromium/third_party/blink/renderer/core/paint/frame_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/frame_painter.h
@@ -13,7 +13,6 @@ namespace blink {
class CullRect;
class GraphicsContext;
-class IntRect;
class LocalFrameView;
class FramePainter {
@@ -24,7 +23,7 @@ class FramePainter {
: frame_view_(&frame_view) {}
void Paint(GraphicsContext&, const GlobalPaintFlags, const CullRect&);
- void PaintContents(GraphicsContext&, const GlobalPaintFlags, const IntRect&);
+ void PaintContents(GraphicsContext&, const GlobalPaintFlags, const CullRect&);
private:
const LocalFrameView& GetFrameView();
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
index a9443b1220c..83786fabdeb 100644
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter.cc
@@ -39,16 +39,18 @@ void HTMLCanvasPainter::PaintReplaced(const PaintInfo& paint_info,
HTMLCanvasElement* canvas =
ToHTMLCanvasElement(layout_html_canvas_.GetNode());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
- canvas->RenderingContext() &&
- canvas->RenderingContext()->IsComposited()) {
- if (cc::Layer* layer = canvas->RenderingContext()->CcLayer()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ if (auto* layer = canvas->ContentsCcLayer()) {
IntRect pixel_snapped_rect = PixelSnappedIntRect(paint_rect);
layer->SetOffsetToTransformParent(
gfx::Vector2dF(pixel_snapped_rect.X(), pixel_snapped_rect.Y()));
layer->SetBounds(gfx::Size(pixel_snapped_rect.Size()));
layer->SetIsDrawable(true);
RecordForeignLayer(context, DisplayItem::kForeignLayerCanvas, layer);
+ if (layout_html_canvas_.GetFrameView()) {
+ layout_html_canvas_.GetFrameView()
+ ->SetPaintArtifactCompositorNeedsUpdate();
+ }
return;
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
index 0e4681dfc81..f32026eb0f5 100644
--- a/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
@@ -14,7 +14,7 @@
#include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h"
#include "third_party/blink/renderer/core/html/canvas/html_canvas_element.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
-#include "third_party/blink/renderer/core/paint/stub_chrome_client_for_spv2.h"
+#include "third_party/blink/renderer/core/paint/stub_chrome_client_for_cap.h"
#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
#include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
#include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h"
@@ -24,14 +24,14 @@
#include "third_party/blink/renderer/core/scroll/scrollbar_theme.h"
-// Integration tests of canvas painting code (in SPv2 mode).
+// Integration tests of canvas painting code (in CAP mode).
namespace blink {
-class HTMLCanvasPainterTestForSPv2 : public PaintControllerPaintTest {
+class HTMLCanvasPainterTestForCAP : public PaintControllerPaintTest {
public:
- HTMLCanvasPainterTestForSPv2()
- : chrome_client_(new StubChromeClientForSPv2) {}
+ HTMLCanvasPainterTestForCAP()
+ : chrome_client_(MakeGarbageCollected<StubChromeClientForCAP>()) {}
protected:
void SetUp() override {
@@ -72,13 +72,13 @@ class HTMLCanvasPainterTestForSPv2 : public PaintControllerPaintTest {
}
private:
- Persistent<StubChromeClientForSPv2> chrome_client_;
+ Persistent<StubChromeClientForCAP> chrome_client_;
FakeGLES2Interface gl_;
};
-INSTANTIATE_SPV2_TEST_CASE_P(HTMLCanvasPainterTestForSPv2);
+INSTANTIATE_CAP_TEST_CASE_P(HTMLCanvasPainterTestForCAP);
-TEST_P(HTMLCanvasPainterTestForSPv2, Canvas2DLayerAppearsInLayerTree) {
+TEST_P(HTMLCanvasPainterTestForCAP, Canvas2DLayerAppearsInLayerTree) {
// Insert a <canvas> and force it into accelerated mode.
// Not using SetBodyInnerHTML() because we need to test before document
// lifecyle update.
diff --git a/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc b/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc
index 346e103cf35..5d57b6d05f5 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_element_timing.cc
@@ -9,6 +9,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/paint/paint_layer.h"
#include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h"
@@ -32,7 +33,7 @@ ImageElementTiming& ImageElementTiming::From(LocalDOMWindow& window) {
ImageElementTiming* timing =
Supplement<LocalDOMWindow>::From<ImageElementTiming>(window);
if (!timing) {
- timing = new ImageElementTiming(window);
+ timing = MakeGarbageCollected<ImageElementTiming>(window);
ProvideTo(window, timing);
}
return *timing;
@@ -40,7 +41,7 @@ ImageElementTiming& ImageElementTiming::From(LocalDOMWindow& window) {
ImageElementTiming::ImageElementTiming(LocalDOMWindow& window)
: Supplement<LocalDOMWindow>(window) {
- DCHECK(RuntimeEnabledFeatures::ElementTimingEnabled());
+ DCHECK(origin_trials::ElementTimingEnabled(GetSupplementable()->document()));
}
void ImageElementTiming::NotifyImagePainted(const HTMLImageElement* element,
@@ -60,10 +61,12 @@ void ImageElementTiming::NotifyImagePainted(const HTMLImageElement* element,
if (!layout_image->CachedImage())
return;
- const KURL& url = layout_image->CachedImage()->Url();
DCHECK(GetSupplementable()->document() == &layout_image->GetDocument());
- if (!SecurityOrigin::AreSameSchemeHostPort(layout_image->GetDocument().Url(),
- url))
+ DCHECK(layout_image->GetDocument().GetSecurityOrigin());
+ if (!Performance::PassesTimingAllowCheck(
+ layout_image->CachedImage()->GetResponse(),
+ *layout_image->GetDocument().GetSecurityOrigin(), AtomicString(),
+ &layout_image->GetDocument()))
return;
// Compute the viewport rect.
@@ -121,29 +124,15 @@ void ImageElementTiming::NotifyImagePainted(const HTMLImageElement* element,
void ImageElementTiming::ReportImagePaintSwapTime(WebLayerTreeView::SwapResult,
base::TimeTicks timestamp) {
- Document* document = GetSupplementable()->document();
- DCHECK(document);
- const SecurityOrigin* current_origin = document->GetSecurityOrigin();
- // It suffices to check the current origin against the parent origin since all
- // origins stored in |element_timings_| have been checked against the current
- // origin.
- while (document &&
- current_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())) {
- DCHECK(document->domWindow());
- WindowPerformance* performance =
- DOMWindowPerformance::performance(*document->domWindow());
- if (performance &&
- performance->HasObserverFor(PerformanceEntry::kElement)) {
- for (const auto& element_timing : element_timings_) {
- performance->AddElementTiming(element_timing.name, element_timing.rect,
- timestamp);
- }
+ WindowPerformance* performance =
+ DOMWindowPerformance::performance(*GetSupplementable());
+ if (performance && (performance->HasObserverFor(PerformanceEntry::kElement) ||
+ performance->ShouldBufferEntries())) {
+ for (const auto& element_timing : element_timings_) {
+ performance->AddElementTiming(element_timing.name, element_timing.rect,
+ timestamp);
}
- // Provide the entry to the parent documents for as long as the origin check
- // still holds.
- document = document->ParentDocument();
}
-
element_timings_.clear();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/image_element_timing.h b/chromium/third_party/blink/renderer/core/paint/image_element_timing.h
index 03ec8b1a990..5c24ca16a1b 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_element_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/image_element_timing.h
@@ -28,6 +28,7 @@ class CORE_EXPORT ImageElementTiming final
public:
static const char kSupplementName[];
+ explicit ImageElementTiming(LocalDOMWindow&);
virtual ~ImageElementTiming() = default;
static ImageElementTiming& From(LocalDOMWindow&);
@@ -44,8 +45,7 @@ class CORE_EXPORT ImageElementTiming final
void Trace(blink::Visitor*) override;
private:
- explicit ImageElementTiming(LocalDOMWindow&);
-
+ FRIEND_TEST_ALL_PREFIXES(ImageElementTimingTest, ImageInsideSVG);
// Callback for the swap promise. Reports paint timestamps.
void ReportImagePaintSwapTime(WebLayerTreeView::SwapResult,
base::TimeTicks timestamp);
diff --git a/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc b/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc
new file mode 100644
index 00000000000..69660fda0dc
--- /dev/null
+++ b/chromium/third_party/blink/renderer/core/paint/image_element_timing_test.cc
@@ -0,0 +1,68 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/paint/image_element_timing.h"
+
+#include "third_party/blink/renderer/core/layout/layout_image.h"
+#include "third_party/blink/renderer/core/loader/resource/image_resource_content.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
+#include "third_party/skia/include/core/SkImage.h"
+#include "third_party/skia/include/core/SkSurface.h"
+
+namespace blink {
+
+class ImageElementTimingTest : public RenderingTest {
+ protected:
+ // Sets an image resource for the LayoutImage with the given |id| and return
+ // the LayoutImage.
+ LayoutImage* SetImageResource(const char* id, int width, int height) {
+ ImageResourceContent* content = CreateImageForTest(width, height);
+ auto* layout_image = ToLayoutImage(GetLayoutObjectByElementId(id));
+ layout_image->ImageResource()->SetImageResource(content);
+ return layout_image;
+ }
+
+ const ImageElementTiming& GetImageElementTiming() {
+ return ImageElementTiming::From(*GetDocument().domWindow());
+ }
+
+ private:
+ ImageResourceContent* CreateImageForTest(int width, int height) {
+ sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
+ SkImageInfo raster_image_info =
+ SkImageInfo::MakeN32Premul(width, height, src_rgb_color_space);
+ sk_sp<SkSurface> surface(SkSurface::MakeRaster(raster_image_info));
+ sk_sp<SkImage> image = surface->makeImageSnapshot();
+ ImageResourceContent* original_image_resource =
+ ImageResourceContent::CreateLoaded(
+ StaticBitmapImage::Create(image).get());
+ return original_image_resource;
+ }
+};
+
+TEST_F(ImageElementTimingTest, ImageInsideSVG) {
+ GetDocument().SetBaseURLOverride(KURL("http://test.com"));
+ SetBodyInnerHTML(R"HTML(
+ <svg mask="url(#mask)">
+ <mask id="mask">
+ <foreignObject width="100" height="100">
+ <img id="target" style='width: 100px; height: 100px;'/>
+ </foreignObject>
+ </mask>
+ <rect width="100" height="100" fill="green"/>
+ </svg>
+ )HTML");
+ LayoutImage* layout_image = SetImageResource("target", 5, 5);
+ ASSERT_TRUE(layout_image);
+ // Enable compositing and also update document lifecycle.
+ EnableCompositing();
+
+ const ImageElementTiming& timing = GetImageElementTiming();
+ // |layout_image| should have had its paint notified to ImageElementTiming.
+ EXPECT_TRUE(timing.images_notified_.find(layout_image) !=
+ timing.images_notified_.end());
+}
+
+} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
index f0b454af11e..abaec5e887f 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.cc
@@ -24,6 +24,7 @@
namespace blink {
namespace {
+#ifndef NDEBUG
String GetImageUrl(const LayoutObject& object) {
if (object.IsImage()) {
const ImageResourceContent* cached_image =
@@ -55,6 +56,7 @@ String GetImageUrl(const LayoutObject& object) {
}
return concatenated_result.ToString();
}
+#endif
bool AttachedBackgroundImagesAllLoaded(const LayoutObject& object) {
DCHECK(ImagePaintTimingDetector::HasContentfulBackgroundImage(object));
@@ -96,66 +98,67 @@ bool IsLoaded(const LayoutObject& object) {
} // namespace
// Set a big enough limit for the number of nodes to ensure memory usage is
-// capped. Exceeding such limit will deactivate the algorithm.
+// capped. Exceeding such limit will make the detactor stops recording entries.
constexpr size_t kImageNodeNumberLimit = 5000;
-static bool LargeImageOnTop(const base::WeakPtr<ImageRecord>& a,
+static bool LargeImageFirst(const base::WeakPtr<ImageRecord>& a,
const base::WeakPtr<ImageRecord>& b) {
- // null value should be at the bottom of the priority queue, so:
- // * When a == null && b!=null, we treat b as larger, return true.
- // * When a != null && b==null, we treat b as no larger than a, return false.
- // * When a == null && b==null, we treat b as no larger than a, return false.
- return (a && b) ? (a->first_size < b->first_size) : bool(b);
+ DCHECK(a);
+ DCHECK(b);
+ return a->first_size > b->first_size;
}
-static bool LateImageOnTop(const base::WeakPtr<ImageRecord>& a,
+static bool LateImageFirst(const base::WeakPtr<ImageRecord>& a,
const base::WeakPtr<ImageRecord>& b) {
- // null value should be at the bottom of the priority queue, so:
- // * When a == null && b!=null, we treat b as larger, return true.
- // * When a != null && b==null, we treat b as no larger than a, return false.
- // * When a == null && b==null, we treat b as no larger than a, return false.
- return (a && b) ? (a->first_paint_index < b->first_paint_index) : bool(b);
+ DCHECK(a);
+ DCHECK(b);
+ return a->first_paint_index > b->first_paint_index;
}
ImagePaintTimingDetector::ImagePaintTimingDetector(LocalFrameView* frame_view)
- : largest_image_heap_(&LargeImageOnTop),
- latest_image_heap_(&LateImageOnTop),
+ : size_ordered_set_(&LargeImageFirst),
+ time_ordered_set_(&LateImageFirst),
frame_view_(frame_view) {}
void ImagePaintTimingDetector::PopulateTraceValue(
TracedValue& value,
const ImageRecord& first_image_paint,
unsigned candidate_index) const {
- value.SetInteger("DOMNodeId", first_image_paint.node_id);
+ value.SetInteger("DOMNodeId", static_cast<int>(first_image_paint.node_id));
+#ifndef NDEBUG
value.SetString("imageUrl", first_image_paint.image_url);
- value.SetInteger("size", first_image_paint.first_size);
+#endif
+ value.SetInteger("size", static_cast<int>(first_image_paint.first_size));
value.SetInteger("candidateIndex", candidate_index);
value.SetString("frame",
IdentifiersFactory::FrameId(&frame_view_->GetFrame()));
}
void ImagePaintTimingDetector::OnLargestImagePaintDetected(
- const ImageRecord& largest_image_record) {
- largest_image_paint_ = largest_image_record.first_paint_time_after_loaded;
+ ImageRecord* largest_image_record) {
+ DCHECK(largest_image_record);
+ DCHECK(!largest_image_record->first_paint_time_after_loaded.is_null());
+ largest_image_paint_ = largest_image_record;
std::unique_ptr<TracedValue> value = TracedValue::Create();
- PopulateTraceValue(*value, largest_image_record,
+ PopulateTraceValue(*value, *largest_image_record,
++largest_image_candidate_index_max_);
TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(
"loading", "LargestImagePaint::Candidate", TRACE_EVENT_SCOPE_THREAD,
- largest_image_record.first_paint_time_after_loaded, "data",
+ largest_image_record->first_paint_time_after_loaded, "data",
std::move(value));
- frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
}
void ImagePaintTimingDetector::OnLastImagePaintDetected(
- const ImageRecord& last_image_record) {
- last_image_paint_ = last_image_record.first_paint_time_after_loaded;
+ ImageRecord* last_image_record) {
+ DCHECK(last_image_record);
+ DCHECK(!last_image_record->first_paint_time_after_loaded.is_null());
+ last_image_paint_ = last_image_record;
std::unique_ptr<TracedValue> value = TracedValue::Create();
- PopulateTraceValue(*value, last_image_record,
+ PopulateTraceValue(*value, *last_image_record,
++last_image_candidate_index_max_);
TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(
"loading", "LastImagePaint::Candidate", TRACE_EVENT_SCOPE_THREAD,
- last_image_record.first_paint_time_after_loaded, "data",
+ last_image_record->first_paint_time_after_loaded, "data",
std::move(value));
frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
}
@@ -171,17 +174,16 @@ void ImagePaintTimingDetector::Analyze() {
bool new_candidate_detected = false;
if (largest_image_record &&
!largest_image_record->first_paint_time_after_loaded.is_null() &&
- largest_image_record->first_paint_time_after_loaded !=
- largest_image_paint_) {
+ largest_image_record != largest_image_paint_) {
new_candidate_detected = true;
- OnLargestImagePaintDetected(*largest_image_record);
+ OnLargestImagePaintDetected(largest_image_record);
}
ImageRecord* last_image_record = FindLastPaintCandidate();
if (last_image_record &&
!last_image_record->first_paint_time_after_loaded.is_null() &&
- last_image_record->first_paint_time_after_loaded != last_image_paint_) {
+ last_image_record != last_image_paint_) {
new_candidate_detected = true;
- OnLastImagePaintDetected(*last_image_record);
+ OnLastImagePaintDetected(last_image_record);
}
if (new_candidate_detected) {
frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
@@ -195,8 +197,9 @@ void ImagePaintTimingDetector::OnPrePaintFinished() {
// If the last frame index of queue has changed, it means there are new
// records pending timing.
DOMNodeId node_id = records_pending_timing_.back();
- if (!id_record_map_.Contains(node_id))
- return;
+ // As we never remove nodes from |id_record_map_|, all of |id_record_map_|
+ // must exist.
+ DCHECK(id_record_map_.Contains(node_id));
unsigned last_frame_index = id_record_map_.at(node_id)->frame_index;
if (last_frame_index_queued_for_timing_ >= last_frame_index)
return;
@@ -208,24 +211,22 @@ void ImagePaintTimingDetector::OnPrePaintFinished() {
}
void ImagePaintTimingDetector::NotifyNodeRemoved(DOMNodeId node_id) {
+ if (!is_recording_)
+ return;
if (id_record_map_.Contains(node_id)) {
// We assume that the removed node's id wouldn't be recycled, so we don't
- // bother to remove these records from largest_image_heap_ or
- // latest_image_heap_, to reduce computation.
- id_record_map_.erase(node_id);
+ // bother to remove these records from size_ordered_set_ or
+ // time_ordered_set_, to reduce computation.
+ detached_ids_.insert(node_id);
- if (id_record_map_.size() == 0) {
- const bool largest_image_paint_invalidated =
- largest_image_paint_ != base::TimeTicks();
- const bool last_image_paint_invalidated =
- last_image_paint_ != base::TimeTicks();
- if (largest_image_paint_invalidated)
- largest_image_paint_ = base::TimeTicks();
- if (last_image_paint_invalidated)
- last_image_paint_ = base::TimeTicks();
- if (largest_image_paint_invalidated || last_image_paint_invalidated) {
- frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
- }
+ if (id_record_map_.size() - detached_ids_.size() == 0) {
+ // If either largest_image_paint_ or last_image_paint_ will change to
+ // nullptr, update performance timing.
+ if (!largest_image_paint_ && !last_image_paint_)
+ return;
+ largest_image_paint_ = nullptr;
+ last_image_paint_ = nullptr;
+ frame_view_->GetPaintTimingDetector().DidChangePerformanceTiming();
}
}
}
@@ -325,6 +326,9 @@ void ImagePaintTimingDetector::RecordImage(const LayoutObject& object,
DOMNodeId node_id = DOMNodeIds::IdForNode(node);
if (size_zero_ids_.Contains(node_id))
return;
+ // The node is reattached.
+ if (id_record_map_.Contains(node_id) && detached_ids_.Contains(node_id))
+ detached_ids_.erase(node_id);
if (!id_record_map_.Contains(node_id) && is_recording_) {
LayoutRect invalidated_rect = object.FirstFragment().VisualRect();
@@ -346,14 +350,21 @@ void ImagePaintTimingDetector::RecordImage(const LayoutObject& object,
// Non-trivial image is found.
std::unique_ptr<ImageRecord> record = std::make_unique<ImageRecord>();
record->node_id = node_id;
+#ifndef NDEBUG
record->image_url = GetImageUrl(object);
+#endif
// Mind that first_size has to be assigned at the push of
- // largest_image_heap_ since it's the sorting key.
+ // size_ordered_set_ since it's the sorting key.
record->first_size = rect_size;
- largest_image_heap_.push(record->AsWeakPtr());
+ size_ordered_set_.insert(record->AsWeakPtr());
id_record_map_.insert(node_id, std::move(record));
- if (id_record_map_.size() + size_zero_ids_.size() > kImageNodeNumberLimit)
- Deactivate();
+ if (id_record_map_.size() + size_zero_ids_.size() > kImageNodeNumberLimit) {
+ TRACE_EVENT_INSTANT2("loading", "ImagePaintTimingDetector::OverNodeLimit",
+ TRACE_EVENT_SCOPE_THREAD, "recorded_node_count",
+ id_record_map_.size(), "size_zero_node_count",
+ size_zero_ids_.size());
+ StopRecordEntries();
+ }
}
if (id_record_map_.Contains(node_id) && !id_record_map_.at(node_id)->loaded &&
@@ -368,46 +379,38 @@ void ImagePaintTimingDetector::RecordImage(const LayoutObject& object,
// image is attached to DOM. This causes last image paint to base its order
// on load time other than attachment time.
// Mind that first_paint_index has to be assigned at the push of
- // latest_image_heap_ since it's the sorting key.
+ // time_ordered_set_ since it's the sorting key.
record->first_paint_index = ++first_paint_index_max_;
- latest_image_heap_.push(record->AsWeakPtr());
+ time_ordered_set_.insert(record->AsWeakPtr());
}
}
-void ImagePaintTimingDetector::Deactivate() {
- TRACE_EVENT_INSTANT2("loading", "ImagePaintTimingDetector::OverNodeLimit",
- TRACE_EVENT_SCOPE_THREAD, "recorded_node_count",
- id_record_map_.size(), "size_zero_node_count",
- size_zero_ids_.size());
+void ImagePaintTimingDetector::StopRecordEntries() {
is_recording_ = false;
}
ImageRecord* ImagePaintTimingDetector::FindLargestPaintCandidate() {
- while (!largest_image_heap_.empty() && !largest_image_heap_.top()) {
- // Discard the elements that have been removed from |id_record_map_|.
- largest_image_heap_.pop();
- }
- // We report the result as the first paint after the largest image finishes
- // loading. If the largest image is still loading, we report nothing and come
- // back later to see if the largest image by then has finished loading.
- if (!largest_image_heap_.empty() && largest_image_heap_.top()->loaded) {
- DCHECK(id_record_map_.Contains(largest_image_heap_.top()->node_id));
- return largest_image_heap_.top().get();
- }
- return nullptr;
+ return FindCandidate(size_ordered_set_);
}
ImageRecord* ImagePaintTimingDetector::FindLastPaintCandidate() {
- while (!latest_image_heap_.empty() && !latest_image_heap_.top()) {
- // Discard the elements that have been removed from |id_record_map_|.
- latest_image_heap_.pop();
- }
- // We report the result as the first paint after the latest image finishes
- // loading. If the latest image is still loading, we report nothing and come
- // back later to see if the latest image at that time has finished loading.
- if (!latest_image_heap_.empty() && latest_image_heap_.top()->loaded) {
- DCHECK(id_record_map_.Contains(latest_image_heap_.top()->node_id));
- return latest_image_heap_.top().get();
+ return FindCandidate(time_ordered_set_);
+}
+
+ImageRecord* ImagePaintTimingDetector::FindCandidate(
+ std::set<base::WeakPtr<ImageRecord>,
+ bool (*)(const base::WeakPtr<ImageRecord>&,
+ const base::WeakPtr<ImageRecord>&)>& ordered_set) {
+ for (auto it = ordered_set.begin(); it != ordered_set.end(); ++it) {
+ if (detached_ids_.Contains((*it)->node_id))
+ continue;
+ DCHECK(id_record_map_.Contains((*it)->node_id));
+ // If the largest/latest image is still loading, we report nothing and come
+ // back later to see if the largest/latest image at that time has finished
+ // loading.
+ if (!(*it)->loaded)
+ return nullptr;
+ return (*it).get();
}
return nullptr;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
index 9bcfd63aa45..52da64837ff 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector.h
@@ -31,7 +31,9 @@ class ImageRecord : public base::SupportsWeakPtr<ImageRecord> {
unsigned frame_index = 0;
base::TimeTicks first_paint_time_after_loaded = base::TimeTicks();
bool loaded = false;
+#ifndef NDEBUG
String image_url = "";
+#endif
};
// ImagePaintTimingDetector contains Largest Image Paint and Last Image Paint.
@@ -67,13 +69,38 @@ class CORE_EXPORT ImagePaintTimingDetector final
static bool HasContentfulBackgroundImage(const LayoutObject& object);
void OnPrePaintFinished();
void NotifyNodeRemoved(DOMNodeId);
- base::TimeTicks LargestImagePaint() const { return largest_image_paint_; }
- base::TimeTicks LastImagePaint() const { return last_image_paint_; }
+ base::TimeTicks LargestImagePaint() const {
+ return !largest_image_paint_
+ ? base::TimeTicks()
+ : largest_image_paint_->first_paint_time_after_loaded;
+ }
+ uint64_t LargestImagePaintSize() const {
+ return !largest_image_paint_ ? 0 : largest_image_paint_->first_size;
+ }
+ base::TimeTicks LastImagePaint() const {
+ return !last_image_paint_
+ ? base::TimeTicks()
+ : last_image_paint_->first_paint_time_after_loaded;
+ }
+ uint64_t LastImagePaintSize() const {
+ return !last_image_paint_ ? 0 : last_image_paint_->first_size;
+ }
+ // After the method being called, the detector stops to record new entries and
+ // node removal. But it still observe the loading status. In other words, if
+ // an image is recorded before stopping recording, and finish loading after
+ // stopping recording, the detector can still observe the loading being
+ // finished.
+ void StopRecordEntries();
+ bool IsRecording() const { return is_recording_; }
void Trace(blink::Visitor*);
private:
ImageRecord* FindLargestPaintCandidate();
ImageRecord* FindLastPaintCandidate();
+ ImageRecord* FindCandidate(
+ std::set<base::WeakPtr<ImageRecord>,
+ bool (*)(const base::WeakPtr<ImageRecord>&,
+ const base::WeakPtr<ImageRecord>&)>& heap);
void PopulateTraceValue(TracedValue&,
const ImageRecord& first_image_paint,
unsigned report_count) const;
@@ -82,8 +109,8 @@ class CORE_EXPORT ImagePaintTimingDetector final
WebLayerTreeView::SwapResult,
base::TimeTicks);
void RegisterNotifySwapTime();
- void OnLargestImagePaintDetected(const ImageRecord&);
- void OnLastImagePaintDetected(const ImageRecord&);
+ void OnLargestImagePaintDetected(ImageRecord*);
+ void OnLastImagePaintDetected(ImageRecord*);
void Deactivate();
void Analyze();
@@ -92,17 +119,18 @@ class CORE_EXPORT ImagePaintTimingDetector final
notify_swap_time_override_for_testing_;
HashSet<DOMNodeId> size_zero_ids_;
+ // We will never destroy the pointers within |id_record_map_|. Once created
+ // they will exist for the whole life cycle of |id_record_map_|.
HashMap<DOMNodeId, std::unique_ptr<ImageRecord>> id_record_map_;
- std::priority_queue<base::WeakPtr<ImageRecord>,
- std::vector<base::WeakPtr<ImageRecord>>,
- bool (*)(const base::WeakPtr<ImageRecord>&,
- const base::WeakPtr<ImageRecord>&)>
- largest_image_heap_;
- std::priority_queue<base::WeakPtr<ImageRecord>,
- std::vector<base::WeakPtr<ImageRecord>>,
- bool (*)(const base::WeakPtr<ImageRecord>&,
- const base::WeakPtr<ImageRecord>&)>
- latest_image_heap_;
+ std::set<base::WeakPtr<ImageRecord>,
+ bool (*)(const base::WeakPtr<ImageRecord>&,
+ const base::WeakPtr<ImageRecord>&)>
+ size_ordered_set_;
+ std::set<base::WeakPtr<ImageRecord>,
+ bool (*)(const base::WeakPtr<ImageRecord>&,
+ const base::WeakPtr<ImageRecord>&)>
+ time_ordered_set_;
+ HashSet<DOMNodeId> detached_ids_;
// Node-ids of records pending swap time are stored in this queue until they
// get a swap time.
@@ -119,10 +147,12 @@ class CORE_EXPORT ImagePaintTimingDetector final
unsigned frame_index_ = 1;
unsigned last_frame_index_queued_for_timing_ = 0;
+ // Used to control if we record new image entries and image removal, but has
+ // no effect on recording the loading status.
bool is_recording_ = true;
- base::TimeTicks largest_image_paint_;
- base::TimeTicks last_image_paint_;
+ ImageRecord* largest_image_paint_ = nullptr;
+ ImageRecord* last_image_paint_ = nullptr;
Member<LocalFrameView> frame_view_;
};
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
index 95ca64c2c98..bb93f8faa6d 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_paint_timing_detector_test.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
@@ -69,16 +70,22 @@ class ImagePaintTimingDetectorTest
.id_record_map_.size();
}
+ void Analyze() {
+ return GetPaintTimingDetector().GetImagePaintTimingDetector().Analyze();
+ }
+
TimeTicks LargestPaintStoredResult() {
- return GetPaintTimingDetector()
- .GetImagePaintTimingDetector()
- .largest_image_paint_;
+ ImageRecord* record = GetPaintTimingDetector()
+ .GetImagePaintTimingDetector()
+ .largest_image_paint_;
+ return !record ? base::TimeTicks() : record->first_paint_time_after_loaded;
}
TimeTicks LastPaintStoredResult() {
- return GetPaintTimingDetector()
- .GetImagePaintTimingDetector()
- .last_image_paint_;
+ ImageRecord* record = GetPaintTimingDetector()
+ .GetImagePaintTimingDetector()
+ .last_image_paint_;
+ return !record ? base::TimeTicks() : record->first_paint_time_after_loaded;
}
void UpdateAllLifecyclePhasesAndInvokeCallbackIfAny() {
@@ -122,6 +129,8 @@ class ImagePaintTimingDetectorTest
WebString::FromUTF8(file_name));
}
+ void SimulateScroll() { GetPaintTimingDetector().NotifyScroll(kUserScroll); }
+
private:
void FakeNotifySwapTime(WebLayerTreeView::ReportTimeCallback callback) {
callback_queue_.push(std::move(callback));
@@ -179,6 +188,7 @@ TEST_F(ImagePaintTimingDetectorTest,
TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_Largest) {
SetBodyInnerHTML(R"HTML(
+ <style>img { display:block }</style>
<img id="smaller"></img>
<img id="medium"></img>
<img id="larger"></img>
@@ -194,22 +204,14 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_Largest) {
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
-#if defined(OS_MACOSX)
- EXPECT_EQ(record->first_size, 90ul);
-#else
EXPECT_EQ(record->first_size, 81ul);
-#endif
EXPECT_TRUE(record->loaded);
SetImageAndPaint("medium", 7, 7);
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
-#if defined(OS_MACOSX)
- EXPECT_EQ(record->first_size, 90ul);
-#else
EXPECT_EQ(record->first_size, 81ul);
-#endif
EXPECT_TRUE(record->loaded);
}
@@ -271,7 +273,9 @@ TEST_F(ImagePaintTimingDetectorTest,
EXPECT_FALSE(record);
}
-TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_IgnoreReAttached) {
+TEST_F(ImagePaintTimingDetectorTest,
+ LargestImagePaint_ReattachedNodeUseFirstPaint) {
+ WTF::ScopedMockClock clock;
SetBodyInnerHTML(R"HTML(
<div id="parent">
</div>
@@ -280,21 +284,28 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_IgnoreReAttached) {
image->setAttribute("id", "target");
GetDocument().getElementById("parent")->AppendChild(image);
SetImageAndPaint("target", 5, 5);
+ clock.Advance(TimeDelta::FromSecondsD(1));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
ImageRecord* record;
record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
+ EXPECT_EQ(record->first_paint_time_after_loaded,
+ base::TimeTicks() + TimeDelta::FromSecondsD(1));
GetDocument().getElementById("parent")->RemoveChild(image);
+ clock.Advance(TimeDelta::FromSecondsD(1));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate();
EXPECT_FALSE(record);
GetDocument().getElementById("parent")->AppendChild(image);
SetImageAndPaint("target", 5, 5);
+ clock.Advance(TimeDelta::FromSecondsD(1));
UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
+ EXPECT_EQ(record->first_paint_time_after_loaded,
+ base::TimeTicks() + TimeDelta::FromSecondsD(1));
}
// This test dipicts a situation when a smaller image has loaded, but a larger
@@ -304,6 +315,7 @@ TEST_F(ImagePaintTimingDetectorTest, LargestImagePaint_IgnoreReAttached) {
// This bahavior is the same with Last Image Paint as well.
TEST_F(ImagePaintTimingDetectorTest, DiscardAnalysisWhenLargestIsLoading) {
SetBodyInnerHTML(R"HTML(
+ <style>img { display:block }</style>
<div id="parent">
<img height="5" width="5" id="1"></img>
<img height="9" width="9" id="2"></img>
@@ -321,11 +333,7 @@ TEST_F(ImagePaintTimingDetectorTest, DiscardAnalysisWhenLargestIsLoading) {
InvokeCallback();
record = FindLargestPaintCandidate();
EXPECT_TRUE(record);
-#if defined(OS_MACOSX)
- EXPECT_EQ(record->first_size, 90ul);
-#else
EXPECT_EQ(record->first_size, 81ul);
-#endif
EXPECT_FALSE(record->first_paint_time_after_loaded.is_null());
}
@@ -407,6 +415,7 @@ TEST_F(ImagePaintTimingDetectorTest, LastImagePaint_OneImage) {
TEST_F(ImagePaintTimingDetectorTest, LastImagePaint_Last) {
WTF::ScopedMockClock clock;
SetBodyInnerHTML(R"HTML(
+ <style>img { display:block }</style>
<div id="parent">
<img height="10" width="10" id="1"></img>
<img height="5" width="5" id="2"></img>
@@ -433,11 +442,7 @@ TEST_F(ImagePaintTimingDetectorTest, LastImagePaint_Last) {
record = FindLastPaintCandidate();
EXPECT_TRUE(record);
-#if defined(OS_MACOSX)
- EXPECT_EQ(record->first_size, 30ul);
-#else
EXPECT_EQ(record->first_size, 25ul);
-#endif
EXPECT_EQ(record->first_paint_time_after_loaded,
base::TimeTicks() + TimeDelta::FromSecondsD(2));
@@ -520,6 +525,7 @@ TEST_F(ImagePaintTimingDetectorTest,
TEST_F(ImagePaintTimingDetectorTest, LastImagePaint_OneSwapPromiseForOneFrame) {
SetBodyInnerHTML(R"HTML(
+ <style>img { display:block }</style>
<div id="parent">
<img id="1"></img>
<img id="2"></img>
@@ -535,21 +541,13 @@ TEST_F(ImagePaintTimingDetectorTest, LastImagePaint_OneSwapPromiseForOneFrame) {
ImageRecord* record;
record = FindLastPaintCandidate();
EXPECT_TRUE(record);
-#if defined(OS_MACOSX)
- EXPECT_EQ(record->first_size, 90ul);
-#else
EXPECT_EQ(record->first_size, 81ul);
-#endif
EXPECT_TRUE(record->first_paint_time_after_loaded.is_null());
InvokeCallback();
record = FindLastPaintCandidate();
EXPECT_TRUE(record);
-#if defined(OS_MACOSX)
- EXPECT_EQ(record->first_size, 90ul);
-#else
EXPECT_EQ(record->first_size, 81ul);
-#endif
EXPECT_FALSE(record->first_paint_time_after_loaded.is_null());
}
@@ -683,4 +681,25 @@ TEST_F(ImagePaintTimingDetectorTest, BackgroundImage_IgnoreGradient) {
EXPECT_EQ(CountRecords(), 0u);
}
+TEST_F(ImagePaintTimingDetectorTest, DeactivateAfterUserInput) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="parent">
+ <img id="target"></img>
+ </div>
+ )HTML");
+ SimulateScroll();
+ SetImageAndPaint("target", 5, 5);
+ UpdateAllLifecyclePhasesAndInvokeCallbackIfAny();
+ EXPECT_EQ(CountRecords(), 0u);
+}
+
+TEST_F(ImagePaintTimingDetectorTest, NullTimeNoCrash) {
+ SetBodyInnerHTML(R"HTML(
+ <img id="target"></img>
+ )HTML");
+ SetImageAndPaint("target", 5, 5);
+ UpdateAllLifecyclePhasesForTest();
+ Analyze();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/image_painter.cc b/chromium/third_party/blink/renderer/core/paint/image_painter.cc
index c8c341eac76..9f5ba5f4b73 100644
--- a/chromium/third_party/blink/renderer/core/paint/image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/image_painter.cc
@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/layout/layout_image.h"
#include "third_party/blink/renderer/core/layout/layout_replaced.h"
#include "third_party/blink/renderer/core/layout/text_run_constructor.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/image_element_timing.h"
@@ -155,8 +156,8 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
if (pixel_snapped_dest_rect.IsEmpty())
return;
- scoped_refptr<Image> image = layout_image_.ImageResource()->GetImage(
- LayoutSize(pixel_snapped_dest_rect.Size()));
+ scoped_refptr<Image> image =
+ layout_image_.ImageResource()->GetImage(pixel_snapped_dest_rect.Size());
if (!image || image->IsNull())
return;
@@ -202,8 +203,9 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
image.get(), decode_mode, FloatRect(pixel_snapped_dest_rect), &src_rect,
SkBlendMode::kSrcOver,
LayoutObject::ShouldRespectImageOrientation(&layout_image_));
- if (RuntimeEnabledFeatures::ElementTimingEnabled() &&
- IsHTMLImageElement(node) && !context.ContextDisabled()) {
+ if (origin_trials::ElementTimingEnabled(&layout_image_.GetDocument()) &&
+ IsHTMLImageElement(node) && !context.ContextDisabled() &&
+ layout_image_.CachedImage() && layout_image_.CachedImage()->IsLoaded()) {
LocalDOMWindow* window = layout_image_.GetDocument().domWindow();
DCHECK(window);
ImageElementTiming::From(*window).NotifyImagePainted(
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc
index 58427321f36..4483ed5ec2e 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc
+++ b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.cc
@@ -66,16 +66,15 @@ void InlineBoxPainterBase::PaintFillLayers(BoxPainterBase& box_painter,
const FillLayer& layer,
const LayoutRect& rect,
BackgroundImageGeometry& geometry,
- bool object_has_multiple_boxes,
- SkBlendMode op) {
+ bool object_has_multiple_boxes) {
// FIXME: This should be a for loop or similar. It's a little non-trivial to
// do so, however, since the layers need to be painted in reverse order.
if (layer.Next()) {
PaintFillLayers(box_painter, info, c, *layer.Next(), rect, geometry,
- object_has_multiple_boxes, op);
+ object_has_multiple_boxes);
}
PaintFillLayer(box_painter, info, c, layer, rect, geometry,
- object_has_multiple_boxes, op);
+ object_has_multiple_boxes);
}
void InlineBoxPainterBase::PaintFillLayer(BoxPainterBase& box_painter,
@@ -84,15 +83,14 @@ void InlineBoxPainterBase::PaintFillLayer(BoxPainterBase& box_painter,
const FillLayer& fill_layer,
const LayoutRect& paint_rect,
BackgroundImageGeometry& geometry,
- bool object_has_multiple_boxes,
- SkBlendMode op) {
+ bool object_has_multiple_boxes) {
StyleImage* img = fill_layer.GetImage();
bool has_fill_image = img && img->CanRender();
if (!object_has_multiple_boxes ||
(!has_fill_image && !style_.HasBorderRadius())) {
box_painter.PaintFillLayer(paint_info, c, fill_layer, paint_rect,
- kBackgroundBleedNone, geometry, op, false);
+ kBackgroundBleedNone, geometry, false);
return;
}
@@ -105,7 +103,7 @@ void InlineBoxPainterBase::PaintFillLayer(BoxPainterBase& box_painter,
GraphicsContextStateSaver state_saver(paint_info.context);
paint_info.context.Clip(PixelSnappedIntRect(paint_rect));
box_painter.PaintFillLayer(paint_info, c, fill_layer, rect,
- kBackgroundBleedNone, geometry, op, multi_line,
+ kBackgroundBleedNone, geometry, multi_line,
paint_rect.Size());
}
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
index 726ce1ea37c..84520814e46 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
+++ b/chromium/third_party/blink/renderer/core/paint/inline_box_painter_base.h
@@ -54,16 +54,14 @@ class InlineBoxPainterBase {
const FillLayer&,
const LayoutRect&,
BackgroundImageGeometry& geometry,
- bool object_has_multiple_boxes,
- SkBlendMode op = SkBlendMode::kSrcOver);
+ bool object_has_multiple_boxes);
void PaintFillLayer(BoxPainterBase&,
const PaintInfo&,
const Color&,
const FillLayer&,
const LayoutRect&,
BackgroundImageGeometry& geometry,
- bool object_has_multiple_boxes,
- SkBlendMode op);
+ bool object_has_multiple_boxes);
virtual void PaintNormalBoxShadow(const PaintInfo&,
const ComputedStyle&,
const LayoutRect& paint_rect) = 0;
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc
index bd82f77257b..4867221b856 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/inline_flow_box_painter.cc
@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/core/paint/inline_flow_box_painter.h"
+#include "third_party/blink/renderer/core/frame/use_counter.h"
+#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/api/line_layout_api_shim.h"
#include "third_party/blink/renderer/core/layout/line/inline_flow_box.h"
#include "third_party/blink/renderer/core/layout/line/root_inline_box.h"
@@ -169,8 +171,7 @@ InlineFlowBoxPainter::GetBorderPaintType(const LayoutRect& adjusted_frame_rect,
// The simple case is where we either have no border image or we are the
// only box for this object. In those cases only a single call to draw is
// required.
- if (!has_border_image || (!inline_flow_box_.PrevForSameLayoutObject() &&
- !inline_flow_box_.NextForSameLayoutObject()))
+ if (!has_border_image || !object_has_multiple_boxes)
return kPaintBordersWithoutClip;
// We have a border image that spans multiple lines.
@@ -267,8 +268,7 @@ void InlineFlowBoxPainter::PaintMask(const PaintInfo& paint_info,
// The simple case is where we are the only box for this object. In those
// cases only a single call to draw is required.
- if (!inline_flow_box_.PrevForSameLayoutObject() &&
- !inline_flow_box_.NextForSameLayoutObject()) {
+ if (!object_has_multiple_boxes) {
NinePieceImagePainter::Paint(paint_info.context, box_model,
box_model.GetDocument(), GetNode(&box_model),
paint_rect, box_model.StyleRef(),
@@ -318,6 +318,10 @@ LayoutRect InlineFlowBoxPainter::FrameRectClampedToLineTopAndBottomIfNeeded()
rect.SetX(logical_top);
rect.SetWidth(logical_height);
}
+ if (rect != inline_flow_box_.FrameRect()) {
+ UseCounter::Count(inline_flow_box_.GetLineLayoutItem().GetDocument(),
+ WebFeature::kQuirkyLineBoxBackgroundSize);
+ }
}
return rect;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc b/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
index d5abae00013..f948711353b 100644
--- a/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/inline_text_box_painter.cc
@@ -185,9 +185,10 @@ void InlineTextBoxPainter::Paint(const PaintInfo& paint_info,
// capitalizing letters can change the length of the backing string.
// That needs to be taken into account when computing the size of the box
// or its painting.
- length = std::min(length, first_line_string.length() -
- std::min(inline_text_box_.Start(),
- first_line_string.length()));
+ if (inline_text_box_.Start() >= first_line_string.length())
+ return;
+ length =
+ std::min(length, first_line_string.length() - inline_text_box_.Start());
// TODO(szager): Figure out why this CHECK sometimes fails, it shouldn't.
CHECK_LE(inline_text_box_.Start() + length, first_line_string.length());
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
index b09c84aa9cb..6ebd9fe82b6 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.cc
@@ -54,9 +54,8 @@
#include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h"
#include "third_party/blink/renderer/platform/animation/compositor_target_property.h"
#include "third_party/blink/renderer/platform/animation/timing_function.h"
-#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
-#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
+#include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h"
#include "third_party/blink/renderer/platform/web_test_support.h"
@@ -81,17 +80,12 @@ LinkHighlightImpl::LinkHighlightImpl(Node* node)
start_time_(CurrentTimeTicks()),
unique_id_(NewUniqueObjectId()) {
DCHECK(node_);
- content_layer_ = cc::PictureLayer::Create(this);
- content_layer_->SetTransformOrigin(FloatPoint3D());
+ fragments_.emplace_back(element_id());
compositor_animation_ = CompositorAnimation::Create();
DCHECK(compositor_animation_);
compositor_animation_->SetAnimationDelegate(this);
-
compositor_animation_->AttachElement(element_id());
- content_layer_->SetIsDrawable(true);
- content_layer_->SetOpacity(1);
- content_layer_->SetElementId(element_id());
geometry_needs_update_ = true;
}
@@ -111,11 +105,16 @@ void LinkHighlightImpl::ReleaseResources() {
if (auto* layout_object = node_->GetLayoutObject())
layout_object->SetNeedsPaintPropertyUpdate();
+ else
+ SetPaintArtifactCompositorNeedsUpdate();
+
node_.Clear();
}
void LinkHighlightImpl::AttachLinkHighlightToCompositingLayer(
const LayoutBoxModelObject& paint_invalidation_container) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
GraphicsLayer* new_graphics_layer =
paint_invalidation_container.Layer()->GraphicsLayerBacking(
node_->GetLayoutObject());
@@ -149,6 +148,8 @@ static void AddQuadToPath(const FloatQuad& quad, Path& path) {
void LinkHighlightImpl::ComputeQuads(const Node& node,
Vector<FloatQuad>& out_quads) const {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
if (!node.GetLayoutObject())
return;
@@ -172,6 +173,8 @@ void LinkHighlightImpl::ComputeQuads(const Node& node,
bool LinkHighlightImpl::ComputeHighlightLayerPathAndPosition(
const LayoutBoxModelObject& paint_invalidation_container) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
if (!node_ || !node_->GetLayoutObject() || !current_graphics_layer_)
return false;
@@ -185,7 +188,6 @@ bool LinkHighlightImpl::ComputeHighlightLayerPathAndPosition(
// Get quads for node in absolute coordinates.
Vector<FloatQuad> quads;
ComputeQuads(*node_, quads);
- DCHECK(quads.size());
Path new_path;
for (wtf_size_t quad_index = 0; quad_index < quads.size(); ++quad_index) {
@@ -237,37 +239,56 @@ bool LinkHighlightImpl::ComputeHighlightLayerPathAndPosition(
FloatRect bounding_rect = new_path.BoundingRect();
new_path.Translate(-ToFloatSize(bounding_rect.Location()));
- bool path_has_changed = !(new_path == path_);
+ DCHECK_EQ(1u, fragments_.size());
+ fragments_[0].SetColor(
+ node_->GetLayoutObject()->StyleRef().TapHighlightColor());
+ auto* layer = fragments_[0].Layer();
+
+ bool path_has_changed = new_path != fragments_[0].GetPath();
if (path_has_changed) {
- path_ = new_path;
- content_layer_->SetBounds(
+ fragments_[0].SetPath(new_path);
+ layer->SetBounds(
static_cast<gfx::Size>(EnclosingIntRect(bounding_rect).Size()));
}
- content_layer_->SetPosition(bounding_rect.Location());
+ layer->SetPosition(bounding_rect.Location());
if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
FloatPoint offset(current_graphics_layer_->GetOffsetFromTransformNode());
offset.MoveBy(bounding_rect.Location());
- content_layer_->SetOffsetToTransformParent(
- gfx::Vector2dF(offset.X(), offset.Y()));
+ layer->SetOffsetToTransformParent(gfx::Vector2dF(offset.X(), offset.Y()));
+ SetPaintArtifactCompositorNeedsUpdate();
}
return path_has_changed;
}
-gfx::Rect LinkHighlightImpl::PaintableRegion() {
- return gfx::Rect(content_layer_->bounds());
+LinkHighlightImpl::LinkHighlightFragment::LinkHighlightFragment(
+ CompositorElementId element_id) {
+ layer_ = cc::PictureLayer::Create(this);
+ layer_->SetTransformOrigin(FloatPoint3D());
+ layer_->SetIsDrawable(true);
+ layer_->SetOpacity(1);
+
+ // The element id is required for animating layers in layer trees but not
+ // required when using layer lists.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() &&
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ layer_->SetElementId(element_id);
+}
+
+LinkHighlightImpl::LinkHighlightFragment::~LinkHighlightFragment() {
+ layer_->ClearClient();
+}
+
+gfx::Rect LinkHighlightImpl::LinkHighlightFragment::PaintableRegion() {
+ return gfx::Rect(layer_->bounds());
}
scoped_refptr<cc::DisplayItemList>
-LinkHighlightImpl::PaintContentsToDisplayList(
+LinkHighlightImpl::LinkHighlightFragment::PaintContentsToDisplayList(
PaintingControlSetting painting_control) {
auto display_list = base::MakeRefCounted<cc::DisplayItemList>();
- if (!node_ || !node_->GetLayoutObject()) {
- display_list->Finalize();
- return display_list;
- }
PaintRecorder recorder;
gfx::Rect record_bounds = PaintableRegion();
@@ -277,8 +298,7 @@ LinkHighlightImpl::PaintContentsToDisplayList(
PaintFlags flags;
flags.setStyle(PaintFlags::kFill_Style);
flags.setAntiAlias(true);
- flags.setColor(
- node_->GetLayoutObject()->StyleRef().TapHighlightColor().Rgb());
+ flags.setColor(color_.Rgb());
canvas->drawPath(path_.GetSkPath(), flags);
display_list->StartPaint();
@@ -299,7 +319,8 @@ void LinkHighlightImpl::StartHighlightAnimationIfNeeded() {
constexpr auto kFadeDuration = TimeDelta::FromMilliseconds(100);
constexpr auto kMinPreFadeDuration = TimeDelta::FromMilliseconds(100);
- content_layer_->SetOpacity(kStartOpacity);
+ for (auto& fragment : fragments_)
+ fragment.Layer()->SetOpacity(kStartOpacity);
std::unique_ptr<CompositorFloatAnimationCurve> curve =
CompositorFloatAnimationCurve::Create();
@@ -326,7 +347,6 @@ void LinkHighlightImpl::StartHighlightAnimationIfNeeded() {
CompositorKeyframeModel::Create(
*curve, compositor_target_property::OPACITY, 0, 0);
- content_layer_->SetIsDrawable(true);
compositor_animation_->AddKeyframeModel(std::move(keyframe_model));
Invalidate();
@@ -348,12 +368,9 @@ void LinkHighlightImpl::NotifyAnimationFinished(double, int) {
ReleaseResources();
}
-class LinkHighlightDisplayItemClientForTracking : public DisplayItemClient {
- String DebugName() const final { return "LinkHighlight"; }
- LayoutRect VisualRect() const final { return LayoutRect(); }
-};
-
void LinkHighlightImpl::UpdateGeometry() {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
if (!node_ || !node_->GetLayoutObject()) {
ClearGraphicsLayerLinkHighlightPointer();
ReleaseResources();
@@ -374,14 +391,12 @@ void LinkHighlightImpl::UpdateGeometry() {
// We only need to invalidate the layer if the highlight size has changed,
// otherwise we can just re-position the layer without needing to
// repaint.
- content_layer_->SetNeedsDisplay();
+ Layer()->SetNeedsDisplay();
if (current_graphics_layer_) {
- gfx::Rect rect = gfx::ToEnclosingRect(
- gfx::RectF(Layer()->position(), gfx::SizeF(Layer()->bounds())));
+ IntRect rect = IntRect(IntPoint(), IntSize(Layer()->bounds()));
current_graphics_layer_->TrackRasterInvalidation(
- LinkHighlightDisplayItemClientForTracking(), IntRect(rect),
- PaintInvalidationReason::kFullLayer);
+ *this, rect, PaintInvalidationReason::kFullLayer);
}
}
}
@@ -398,18 +413,20 @@ void LinkHighlightImpl::Invalidate() {
}
cc::Layer* LinkHighlightImpl::Layer() {
- return content_layer_.get();
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ DCHECK_EQ(1u, fragments_.size());
+ return fragments_[0].Layer();
}
CompositorAnimation* LinkHighlightImpl::GetCompositorAnimation() const {
return compositor_animation_.get();
}
-CompositorElementId LinkHighlightImpl::element_id() {
+CompositorElementId LinkHighlightImpl::element_id() const {
return CompositorElementIdFromUniqueObjectId(unique_id_);
}
-const EffectPaintPropertyNode* LinkHighlightImpl::effect() {
+const EffectPaintPropertyNode* LinkHighlightImpl::effect() const {
if (!node_)
return nullptr;
@@ -421,4 +438,87 @@ const EffectPaintPropertyNode* LinkHighlightImpl::effect() {
return nullptr;
}
+void LinkHighlightImpl::Paint(GraphicsContext& context) {
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+ if (!node_ || !node_->GetLayoutObject()) {
+ ReleaseResources();
+ return;
+ }
+
+ const auto* object = node_->GetLayoutObject();
+ static const FloatSize rect_rounding_radii(3, 3);
+ auto color = node_->GetLayoutObject()->StyleRef().TapHighlightColor();
+
+ // For now, we'll only use rounded rects if we have a single rect because
+ // otherwise we may sometimes get a chain of adjacent boxes (e.g. for text
+ // nodes) which end up looking like sausage links: these should ideally be
+ // merged into a single rect before creating the path.
+ bool use_rounded_rects = !node_->GetDocument()
+ .GetSettings()
+ ->GetMockGestureTapHighlightsEnabled() &&
+ !object->FirstFragment().NextFragment();
+
+ size_t index = 0;
+ for (const auto* fragment = &object->FirstFragment(); fragment;
+ fragment = fragment->NextFragment(), ++index) {
+ auto rects = object->PhysicalOutlineRects(
+ fragment->PaintOffset(), NGOutlineType::kIncludeBlockVisualOverflow);
+ if (rects.size() > 1)
+ use_rounded_rects = false;
+
+ Path new_path;
+ for (auto& rect : rects) {
+ FloatRect snapped_rect(PixelSnappedIntRect(rect));
+ if (use_rounded_rects)
+ new_path.AddRoundedRect(snapped_rect, rect_rounding_radii);
+ else
+ new_path.AddRect(snapped_rect);
+ }
+
+ if (index == fragments_.size()) {
+ fragments_.emplace_back(element_id());
+ // PaintArtifactCompositor needs update for the new cc::PictureLayer we
+ // just created for the fragment.
+ SetPaintArtifactCompositorNeedsUpdate();
+ }
+
+ auto& link_highlight_fragment = fragments_[index];
+ link_highlight_fragment.SetColor(color);
+
+ auto bounding_rect = new_path.BoundingRect();
+ new_path.Translate(-ToFloatSize(bounding_rect.Location()));
+
+ auto* layer = link_highlight_fragment.Layer();
+ if (link_highlight_fragment.GetPath() != new_path) {
+ link_highlight_fragment.SetPath(new_path);
+ layer->SetBounds(gfx::Size(EnclosingIntRect(bounding_rect).Size()));
+ layer->SetNeedsDisplay();
+ }
+ // Always set offset because it is excluded from the above equality check.
+ layer->SetOffsetToTransformParent(
+ gfx::Vector2dF(bounding_rect.X(), bounding_rect.Y()));
+
+ auto property_tree_state = fragment->LocalBorderBoxProperties();
+ DCHECK(fragment->PaintProperties());
+ DCHECK(fragment->PaintProperties()->LinkHighlightEffect());
+ property_tree_state.SetEffect(
+ fragment->PaintProperties()->LinkHighlightEffect());
+ RecordForeignLayer(context, DisplayItem::kForeignLayerLinkHighlight, layer,
+ property_tree_state);
+ }
+
+ if (index < fragments_.size()) {
+ fragments_.Shrink(index);
+ // PaintArtifactCompositor needs update for the cc::PictureLayers we just
+ // removed for the extra fragments.
+ SetPaintArtifactCompositorNeedsUpdate();
+ }
+}
+
+void LinkHighlightImpl::SetPaintArtifactCompositorNeedsUpdate() {
+ DCHECK(node_);
+ if (auto* frame_view = node_->GetDocument().View())
+ frame_view->SetPaintArtifactCompositorNeedsUpdate();
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h
index 655d080aefc..8d0ff694063 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl.h
@@ -33,6 +33,7 @@
#include "third_party/blink/renderer/platform/animation/compositor_animation.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_client.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_delegate.h"
+#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/compositor_element_id.h"
#include "third_party/blink/renderer/platform/graphics/link_highlight.h"
#include "third_party/blink/renderer/platform/graphics/path.h"
@@ -47,12 +48,12 @@ class PictureLayer;
namespace blink {
+class GraphicsContext;
class GraphicsLayer;
class LayoutBoxModelObject;
class Node;
class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight,
- public cc::ContentLayerClient,
public CompositorAnimationDelegate,
public CompositorAnimationClient {
public:
@@ -67,13 +68,6 @@ class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight,
// invalidation of the owning graphics layer.
void UpdateGeometry();
- // cc::ContentLayerClient implementation.
- gfx::Rect PaintableRegion() override;
- scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting painting_control) override;
- bool FillsBoundsCompletely() const override { return false; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
-
// CompositorAnimationDelegate implementation.
void NotifyAnimationStarted(double monotonic_time, int group) override;
void NotifyAnimationFinished(double monotonic_time, int group) override;
@@ -93,9 +87,16 @@ class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight,
Node* GetNode() const { return node_; }
- CompositorElementId element_id();
+ CompositorElementId element_id() const;
+
+ const EffectPaintPropertyNode* effect() const override;
- const EffectPaintPropertyNode* effect() override;
+ void Paint(GraphicsContext&);
+
+ wtf_size_t FragmentCountForTesting() const { return fragments_.size(); }
+ cc::PictureLayer* LayerForTesting(size_t index) const {
+ return fragments_[index].Layer();
+ }
private:
LinkHighlightImpl(Node*);
@@ -110,8 +111,31 @@ class CORE_EXPORT LinkHighlightImpl final : public LinkHighlight,
// changed size since the last call to this function.
bool ComputeHighlightLayerPathAndPosition(const LayoutBoxModelObject&);
- scoped_refptr<cc::PictureLayer> content_layer_;
- Path path_;
+ void SetPaintArtifactCompositorNeedsUpdate();
+
+ class LinkHighlightFragment : private cc::ContentLayerClient {
+ public:
+ LinkHighlightFragment(CompositorElementId);
+ ~LinkHighlightFragment() override;
+
+ cc::PictureLayer* Layer() const { return layer_.get(); }
+ const Path& GetPath() const { return path_; }
+ void SetPath(const Path& path) { path_ = path; }
+ void SetColor(const Color& color) { color_ = color; }
+
+ private:
+ // cc::ContentLayerClient implementation.
+ gfx::Rect PaintableRegion() override;
+ scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(
+ PaintingControlSetting painting_control) override;
+ bool FillsBoundsCompletely() const override { return false; }
+ size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
+
+ scoped_refptr<cc::PictureLayer> layer_;
+ Path path_;
+ Color color_;
+ };
+ Vector<LinkHighlightFragment> fragments_;
Persistent<Node> node_;
GraphicsLayer* current_graphics_layer_;
diff --git a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
index 313cc562e8f..d3da48068f3 100644
--- a/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/link_highlight_impl_test.cc
@@ -27,6 +27,7 @@
#include <memory>
+#include "cc/layers/picture_layer.h"
#include "cc/trees/layer_tree_host.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/platform.h"
@@ -45,23 +46,21 @@
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/core/input/event_handler.h"
+#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.h"
#include "third_party/blink/renderer/platform/graphics/graphics_layer.h"
+#include "third_party/blink/renderer/platform/testing/paint_test_configurations.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
namespace blink {
class LinkHighlightImplTest : public testing::Test,
- public testing::WithParamInterface<bool>,
- private ScopedBlinkGenPropertyTreesForTest {
- public:
- LinkHighlightImplTest() : ScopedBlinkGenPropertyTreesForTest(GetParam()) {}
-
+ public PaintTestConfigurations {
protected:
GestureEventWithHitTestResults GetTargetedEvent(
WebGestureEvent& touch_event) {
@@ -116,13 +115,13 @@ class LinkHighlightImplTest : public testing::Test,
frame_test_helpers::WebViewHelper web_view_helper_;
};
-INSTANTIATE_TEST_CASE_P(All, LinkHighlightImplTest, testing::Bool());
+INSTANTIATE_PAINT_TEST_CASE_P(LinkHighlightImplTest);
TEST_P(LinkHighlightImplTest, verifyWebViewImplIntegration) {
WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
int page_width = 640;
int page_height = 480;
- web_view_impl->Resize(WebSize(page_width, page_height));
+ web_view_impl->MainFrameWidget()->Resize(WebSize(page_width, page_height));
UpdateAllLifecyclePhases();
WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
@@ -146,7 +145,8 @@ TEST_P(LinkHighlightImplTest, verifyWebViewImplIntegration) {
const auto& highlights =
web_view_impl->GetPage()->GetLinkHighlights().link_highlights_;
EXPECT_TRUE(highlights.at(0));
- EXPECT_TRUE(highlights.at(0)->Layer());
+ EXPECT_EQ(1u, highlights.at(0)->FragmentCountForTesting());
+ EXPECT_TRUE(highlights.at(0)->LayerForTesting(0));
// Find a target inside a scrollable div
touch_event.SetPositionInWidget(WebFloatPoint(20, 100));
@@ -175,7 +175,7 @@ TEST_P(LinkHighlightImplTest, resetDuringNodeRemoval) {
int page_width = 640;
int page_height = 480;
- web_view_impl->Resize(WebSize(page_width, page_height));
+ web_view_impl->MainFrameWidget()->Resize(WebSize(page_width, page_height));
UpdateAllLifecyclePhases();
WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
@@ -190,16 +190,30 @@ TEST_P(LinkHighlightImplTest, resetDuringNodeRemoval) {
web_view_impl->EnableTapHighlightAtPoint(targeted_event);
const auto& highlights = web_view_impl->GetPage()->GetLinkHighlights();
+ ASSERT_EQ(1u, highlights.link_highlights_.size());
ASSERT_TRUE(highlights.link_highlights_.at(0));
-
- GraphicsLayer* highlight_layer =
- highlights.link_highlights_.at(0)->CurrentGraphicsLayerForTesting();
- ASSERT_TRUE(highlight_layer);
- EXPECT_TRUE(highlight_layer->GetLinkHighlights().at(0));
+ EXPECT_EQ(touch_node, highlights.link_highlights_.at(0)->GetNode());
+
+ GraphicsLayer* highlight_layer;
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ highlight_layer =
+ highlights.link_highlights_.at(0)->CurrentGraphicsLayerForTesting();
+ ASSERT_TRUE(highlight_layer);
+ EXPECT_TRUE(highlight_layer->GetLinkHighlights().at(0));
+ }
touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING);
UpdateAllLifecyclePhases();
- EXPECT_EQ(0U, highlight_layer->GetLinkHighlights().size());
+
+ ASSERT_EQ(1u, highlights.link_highlights_.size());
+ ASSERT_TRUE(highlights.link_highlights_.at(0));
+ EXPECT_FALSE(highlights.link_highlights_.at(0)->GetNode());
+
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(0U, highlight_layer->GetLinkHighlights().size());
+ EXPECT_FALSE(
+ highlights.link_highlights_.at(0)->CurrentGraphicsLayerForTesting());
+ }
}
// A lifetime test: delete LayerTreeView while running LinkHighlights.
@@ -208,7 +222,7 @@ TEST_P(LinkHighlightImplTest, resetLayerTreeView) {
int page_width = 640;
int page_height = 480;
- web_view_impl->Resize(WebSize(page_width, page_height));
+ web_view_impl->MainFrameWidget()->Resize(WebSize(page_width, page_height));
UpdateAllLifecyclePhases();
WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
@@ -226,21 +240,62 @@ TEST_P(LinkHighlightImplTest, resetLayerTreeView) {
web_view_impl->GetPage()->GetLinkHighlights().link_highlights_;
ASSERT_TRUE(highlights.at(0));
- GraphicsLayer* highlight_layer =
- highlights.at(0)->CurrentGraphicsLayerForTesting();
- ASSERT_TRUE(highlight_layer);
- EXPECT_TRUE(highlight_layer->GetLinkHighlights().at(0));
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ GraphicsLayer* highlight_layer =
+ highlights.at(0)->CurrentGraphicsLayerForTesting();
+ ASSERT_TRUE(highlight_layer);
+ EXPECT_TRUE(highlight_layer->GetLinkHighlights().at(0));
+ }
+}
+
+TEST_P(LinkHighlightImplTest, HighlightInvalidation) {
+ // This test requires GraphicsLayers which are not used in
+ // CompositeAfterPaint.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
+ web_view_impl->MainFrameWidget()->Resize(WebSize(640, 480));
+ UpdateAllLifecyclePhases();
+
+ WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
+ WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests(),
+ kWebGestureDeviceTouchscreen);
+ touch_event.SetPositionInWidget(WebFloatPoint(20, 20));
+ GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
+ auto* touch_element = ToElement(web_view_impl->BestTapNode(targeted_event));
+ web_view_impl->EnableTapHighlightAtPoint(targeted_event);
+
+ web_view_helper_.LocalMainFrame()
+ ->GetFrameView()
+ ->SetTracksPaintInvalidations(true);
+
+ // Change the touched element's height to 12px.
+ auto& style = touch_element->getAttribute(html_names::kStyleAttr);
+ String new_style = style.GetString();
+ new_style.append("height: 12px;");
+ touch_element->setAttribute(html_names::kStyleAttr, AtomicString(new_style));
+ UpdateAllLifecyclePhases();
+
+ const auto& highlights =
+ web_view_impl->GetPage()->GetLinkHighlights().link_highlights_;
+ auto* highlight_layer = highlights.at(0)->CurrentGraphicsLayerForTesting();
+ const auto* tracking = highlight_layer->GetRasterInvalidationTracking();
+ // The invalidation rect should fully cover the layer.
+ EXPECT_EQ(tracking->Invalidations().back().rect, IntRect(0, 0, 200, 12));
}
TEST_P(LinkHighlightImplTest, HighlightLayerEffectNode) {
// This is testing the blink->cc layer integration.
- if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() &&
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
int page_width = 640;
int page_height = 480;
WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
- web_view_impl->Resize(WebSize(page_width, page_height));
+ web_view_impl->MainFrameWidget()->Resize(WebSize(page_width, page_height));
paint_artifact_compositor()->EnableExtraDataForTesting();
UpdateAllLifecyclePhases();
@@ -265,15 +320,19 @@ TEST_P(LinkHighlightImplTest, HighlightLayerEffectNode) {
ASSERT_TRUE(highlight);
// Check that the link highlight cc layer has a cc effect property tree node.
- auto* layer = highlight->Layer();
+ EXPECT_EQ(1u, highlight->FragmentCountForTesting());
+ auto* layer = highlight->LayerForTesting(0);
+ // We don't set layer's element id.
+ EXPECT_EQ(cc::ElementId(), layer->element_id());
auto effect_tree_index = layer->effect_tree_index();
auto* property_trees = layer->layer_tree_host()->property_trees();
EXPECT_EQ(
effect_tree_index,
- property_trees->element_id_to_effect_node_index[layer->element_id()]);
+ property_trees->element_id_to_effect_node_index[highlight->element_id()]);
// The link highlight cc effect node should correspond to the blink effect
// node.
- EXPECT_EQ(highlight->effect()->GetCompositorElementId(), layer->element_id());
+ EXPECT_EQ(highlight->effect()->GetCompositorElementId(),
+ highlight->element_id());
EXPECT_TRUE(highlight->effect()->RequiresCompositingForAnimation());
touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING);
@@ -282,4 +341,83 @@ TEST_P(LinkHighlightImplTest, HighlightLayerEffectNode) {
EXPECT_EQ(layer_count_before_highlight, ContentLayerCount());
}
+TEST_P(LinkHighlightImplTest, MultiColumn) {
+ // This is testing the blink->cc layer integration.
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() &&
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
+ int page_width = 640;
+ int page_height = 480;
+ WebViewImpl* web_view_impl = web_view_helper_.GetWebView();
+ web_view_impl->MainFrameWidget()->Resize(WebSize(page_width, page_height));
+ UpdateAllLifecyclePhases();
+
+ paint_artifact_compositor()->EnableExtraDataForTesting();
+ UpdateAllLifecyclePhases();
+ size_t layer_count_before_highlight = ContentLayerCount();
+
+ WebGestureEvent touch_event(WebInputEvent::kGestureShowPress,
+ WebInputEvent::kNoModifiers,
+ WebInputEvent::GetStaticTimeStampForTests(),
+ kWebGestureDeviceTouchscreen);
+ // This will touch the link under multicol.
+ touch_event.SetPositionInWidget(WebFloatPoint(20, 300));
+
+ GestureEventWithHitTestResults targeted_event = GetTargetedEvent(touch_event);
+ Node* touch_node = web_view_impl->BestTapNode(targeted_event);
+ ASSERT_TRUE(touch_node);
+
+ web_view_impl->EnableTapHighlightAtPoint(targeted_event);
+
+ const auto& highlights =
+ web_view_impl->GetPage()->GetLinkHighlights().link_highlights_;
+ EXPECT_EQ(1u, highlights.size());
+ const auto* highlight = highlights.at(0).get();
+ ASSERT_TRUE(highlight);
+
+ // The link highlight cc effect node should correspond to the blink effect
+ // node.
+ const auto* effect = highlight->effect();
+ ASSERT_TRUE(effect);
+ EXPECT_EQ(effect->GetCompositorElementId(), highlight->element_id());
+ EXPECT_TRUE(effect->RequiresCompositingForAnimation());
+
+ const auto& first_fragment = touch_node->GetLayoutObject()->FirstFragment();
+ EXPECT_EQ(effect, first_fragment.PaintProperties()->LinkHighlightEffect());
+ const auto* second_fragment = first_fragment.NextFragment();
+ ASSERT_TRUE(second_fragment);
+ EXPECT_EQ(effect, second_fragment->PaintProperties()->LinkHighlightEffect());
+ EXPECT_FALSE(second_fragment->NextFragment());
+
+ auto check_layer = [&](const cc::PictureLayer* layer) {
+ ASSERT_TRUE(layer);
+ // We don't set layer's element id.
+ EXPECT_EQ(cc::ElementId(), layer->element_id());
+ auto effect_tree_index = layer->effect_tree_index();
+ auto* property_trees = layer->layer_tree_host()->property_trees();
+ EXPECT_EQ(effect_tree_index,
+ property_trees
+ ->element_id_to_effect_node_index[highlight->element_id()]);
+ };
+
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // The highlight should create 2 additional layer, each for each fragment.
+ EXPECT_EQ(layer_count_before_highlight + 2, ContentLayerCount());
+ EXPECT_EQ(2u, highlight->FragmentCountForTesting());
+ check_layer(highlight->LayerForTesting(0));
+ check_layer(highlight->LayerForTesting(1));
+ } else {
+ // The highlight should create 1 additional layer covering both fragments.
+ EXPECT_EQ(layer_count_before_highlight + 1, ContentLayerCount());
+ EXPECT_EQ(1u, highlight->FragmentCountForTesting());
+ check_layer(highlight->LayerForTesting(0));
+ }
+
+ touch_node->remove(IGNORE_EXCEPTION_FOR_TESTING);
+ UpdateAllLifecyclePhases();
+ // Removing the highlight layer should drop the cc layers for highlights.
+ EXPECT_EQ(layer_count_before_highlight, ContentLayerCount());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index 226cd35199c..18b2bb8f3f7 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -148,14 +148,18 @@ NGBoxFragmentPainter::NGBoxFragmentPainter(const NGPaintFragment& box)
}
void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
+ if (PhysicalFragment().IsAtomicInline())
+ PaintAtomicInline(paint_info);
+ else
+ PaintInternal(paint_info);
+}
+
+void NGBoxFragmentPainter::PaintInternal(const PaintInfo& paint_info) {
ScopedPaintState paint_state(box_fragment_, paint_info);
if (!ShouldPaint(paint_state))
return;
PaintInfo& info = paint_state.MutablePaintInfo();
- if (PhysicalFragment().IsAtomicInline())
- return PaintAtomicInline(info);
-
LayoutPoint paint_offset = paint_state.PaintOffset();
PaintPhase original_phase = info.phase;
@@ -197,20 +201,7 @@ void NGBoxFragmentPainter::Paint(const PaintInfo& paint_info) {
void NGBoxFragmentPainter::RecordHitTestData(const PaintInfo& paint_info,
const LayoutPoint& paint_offset) {
- // Hit test display items are only needed for compositing. This flag is used
- // for for printing and drag images which do not need hit testing.
- if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
- return;
-
- // If an object is not visible, it does not participate in hit testing.
- if (box_fragment_.Style().Visibility() != EVisibility::kVisible)
- return;
-
const NGPhysicalFragment& physical_fragment = PhysicalFragment();
- auto touch_action = physical_fragment.EffectiveWhitelistedTouchAction();
- if (touch_action == TouchAction::kTouchActionAuto)
- return;
-
// TODO(pdr): If we are painting the background into the scrolling contents
// layer, we need to use the overflow rect instead of the border box rect. We
// may want to move the call to RecordHitTestRect into
@@ -222,7 +213,20 @@ void NGBoxFragmentPainter::RecordHitTestData(const PaintInfo& paint_info,
border_box.offset += NGPhysicalOffset(paint_offset);
HitTestDisplayItem::Record(
paint_info.context, box_fragment_,
- HitTestRect(border_box.ToLayoutRect(), touch_action));
+ HitTestRect(border_box.ToLayoutRect(),
+ physical_fragment.EffectiveWhitelistedTouchAction()));
+}
+
+void NGBoxFragmentPainter::RecordHitTestDataForLine(
+ const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset,
+ const NGPaintFragment& line) {
+ NGPhysicalOffsetRect border_box = line.PhysicalFragment().LocalRect();
+ border_box.offset += NGPhysicalOffset(paint_offset);
+ HitTestDisplayItem::Record(
+ paint_info.context, line,
+ HitTestRect(border_box.ToLayoutRect(),
+ PhysicalFragment().EffectiveWhitelistedTouchAction()));
}
void NGBoxFragmentPainter::PaintObject(
@@ -241,13 +245,14 @@ void NGBoxFragmentPainter::PaintObject(
if (!suppress_box_decoration_background && is_visible)
PaintBoxDecorationBackground(paint_info, paint_offset);
- if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
+ if (NGFragmentPainter::ShouldRecordHitTestData(paint_info,
+ PhysicalFragment()))
RecordHitTestData(paint_info, paint_offset);
// Record the scroll hit test after the background so background squashing
// is not affected. Hit test order would be equivalent if this were
// immediately before the background.
- // if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ // if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
// PaintScrollHitTestDisplayItem(paint_info);
// We're done. We don't bother painting any children.
@@ -265,15 +270,15 @@ void NGBoxFragmentPainter::PaintObject(
if (paint_phase != PaintPhase::kSelfOutlineOnly) {
if (PhysicalFragment().ChildrenInline()) {
- if (PhysicalFragment().IsBlockFlow()) {
+ if (PhysicalFragment().IsBlockFlow())
PaintBlockFlowContents(paint_info, paint_offset);
- if (paint_phase == PaintPhase::kFloat ||
- paint_phase == PaintPhase::kSelection ||
- paint_phase == PaintPhase::kTextClip)
- PaintFloats(paint_info);
- } else {
+ else
PaintInlineChildren(box_fragment_.Children(), paint_info, paint_offset);
- }
+
+ if (paint_phase == PaintPhase::kFloat ||
+ paint_phase == PaintPhase::kSelection ||
+ paint_phase == PaintPhase::kTextClip)
+ PaintFloats(paint_info);
} else {
PaintBlockChildren(paint_info);
}
@@ -487,6 +492,13 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackground(
bool NGBoxFragmentPainter::BackgroundIsKnownToBeOpaque(
const PaintInfo& paint_info) {
const LayoutBox& layout_box = ToLayoutBox(*box_fragment_.GetLayoutObject());
+
+ // If the box has multiple fragments, its VisualRect is the bounding box of
+ // all fragments' visual rects, which is likely to cover areas that are not
+ // covered by painted background.
+ if (layout_box.FirstFragment().NextFragment())
+ return false;
+
LayoutRect bounds = IsPaintingScrollingBackground(box_fragment_, paint_info)
? layout_box.LayoutOverflowRect()
: layout_box.SelfVisualOverflowRect();
@@ -533,15 +545,18 @@ void NGBoxFragmentPainter::PaintBoxDecorationBackgroundWithRect(
BoxDecorationData box_decoration_data(PhysicalFragment());
GraphicsContextStateSaver state_saver(paint_info.context, false);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
LayoutRect(EnclosingIntRect(paint_rect)) == paint_rect &&
BackgroundIsKnownToBeOpaque(paint_info))
recorder.SetKnownToBeOpaque();
bool needs_end_layer = false;
if (!painting_overflow_contents) {
+ bool skip_background = layout_box.BackgroundTransfersToView() ||
+ (paint_info.SkipRootBackground() &&
+ paint_info.PaintContainer() == layout_box);
PaintNormalBoxShadow(paint_info, paint_rect, style, border_edges_.line_left,
- border_edges_.line_right);
+ border_edges_.line_right, skip_background);
if (box_fragment_.HasSelfPaintingLayer() && layout_box.IsTableCell() &&
ToLayoutTableCell(layout_box).Table()->ShouldCollapseBorders()) {
@@ -653,53 +668,39 @@ void NGBoxFragmentPainter::PaintInlineChildBoxUsingLegacyFallback(
}
void NGBoxFragmentPainter::PaintAllPhasesAtomically(
- const PaintInfo& paint_info,
- bool is_self_painting) {
- ScopedPaintState paint_state(box_fragment_, paint_info);
- auto paint_offset = paint_state.PaintOffset();
- PaintInfo& local_paint_info = paint_state.MutablePaintInfo();
-
+ const PaintInfo& paint_info) {
// Pass PaintPhaseSelection and PaintPhaseTextClip is handled by the regular
// foreground paint implementation. We don't need complete painting for these
// phases.
PaintPhase phase = paint_info.phase;
if (phase == PaintPhase::kSelection || phase == PaintPhase::kTextClip)
- return PaintObject(local_paint_info, paint_offset);
+ return PaintInternal(paint_info);
- if (paint_info.phase == PaintPhase::kSelfBlockBackgroundOnly &&
- is_self_painting) {
- PaintObject(local_paint_info, paint_offset);
- PaintOverflowControlsIfNeeded(local_paint_info, paint_offset);
- return;
- }
+ // Self-painting AtomicInlines must paint their background in background
+ // phase.
+ bool is_self_painting_atomic_inline =
+ PhysicalFragment().IsAtomicInline() && PhysicalFragment().Layer() &&
+ PhysicalFragment().Layer()->IsSelfPaintingLayer();
+ if (phase == PaintPhase::kSelfBlockBackgroundOnly &&
+ is_self_painting_atomic_inline)
+ return PaintInternal(paint_info);
if (phase != PaintPhase::kForeground)
return;
- if (!is_self_painting) {
+ PaintInfo local_paint_info(paint_info);
+ if (!is_self_painting_atomic_inline) {
local_paint_info.phase = PaintPhase::kBlockBackground;
- PaintObject(local_paint_info, paint_offset);
+ PaintInternal(local_paint_info);
}
local_paint_info.phase = PaintPhase::kFloat;
- PaintObject(local_paint_info, paint_offset);
+ PaintInternal(local_paint_info);
local_paint_info.phase = PaintPhase::kForeground;
- if (box_fragment_.GetLayoutObject()->IsBox()) {
- ScopedBoxContentsPaintState contents_paint_state(
- paint_state, ToLayoutBox(*box_fragment_.GetLayoutObject()));
- PaintObject(contents_paint_state.GetPaintInfo(),
- contents_paint_state.PaintOffset());
- } else {
- PaintObject(local_paint_info, paint_offset);
- }
+ PaintInternal(local_paint_info);
local_paint_info.phase = PaintPhase::kOutline;
- PaintObject(local_paint_info, paint_offset);
-
- if (!is_self_painting) {
- local_paint_info.phase = PaintPhase::kBlockBackground;
- PaintOverflowControlsIfNeeded(local_paint_info, paint_offset);
- }
+ PaintInternal(local_paint_info);
}
void NGBoxFragmentPainter::PaintLineBoxChildren(
@@ -740,6 +741,12 @@ void NGBoxFragmentPainter::PaintLineBoxChildren(
}
DCHECK(line->PhysicalFragment().IsLineBox())
<< line->PhysicalFragment().ToString();
+
+ if (paint_info.phase == PaintPhase::kForeground &&
+ NGFragmentPainter::ShouldRecordHitTestData(paint_info,
+ PhysicalFragment()))
+ RecordHitTestDataForLine(paint_info, child_offset, *line);
+
PaintInlineChildren(line->Children(), paint_info, child_offset);
}
}
@@ -778,7 +785,7 @@ void NGBoxFragmentPainter::PaintAtomicInlineChild(const NGPaintFragment& child,
FragmentRequiresLegacyFallback(fragment)) {
PaintInlineChildBoxUsingLegacyFallback(fragment, paint_info);
} else {
- NGBoxFragmentPainter(child).PaintAllPhasesAtomically(paint_info, false);
+ NGBoxFragmentPainter(child).PaintAllPhasesAtomically(paint_info);
}
}
@@ -795,6 +802,17 @@ void NGBoxFragmentPainter::PaintTextChild(const NGPaintFragment& text_fragment,
paint_info.phase != PaintPhase::kMask)
return;
+ // Note: To paint selection for <br>, we don't check intersection with
+ // fragment paint rect and cull rect since computing selection rect is
+ // expensive.
+ if (!text_fragment.Size().IsEmpty()) {
+ LayoutRect physical_visual_overflow = text_fragment.SelfInkOverflow();
+ physical_visual_overflow.MoveBy(text_fragment.Offset().ToLayoutPoint());
+ physical_visual_overflow.MoveBy(paint_offset);
+ if (!paint_info.GetCullRect().Intersects(physical_visual_overflow))
+ return;
+ }
+
// The text clip phase already has a DrawingRecorder. Text clips are initiated
// only in BoxPainterBase::PaintFillLayer, which is already within a
// DrawingRecorder.
@@ -834,20 +852,13 @@ void NGBoxFragmentPainter::PaintSymbol(const NGPaintFragment& fragment,
rect);
}
-// Follows BlockPainter::PaintInlineBox
void NGBoxFragmentPainter::PaintAtomicInline(const PaintInfo& paint_info) {
- if (paint_info.phase != PaintPhase::kForeground &&
- paint_info.phase != PaintPhase::kSelection &&
- paint_info.phase != PaintPhase::kSelfBlockBackgroundOnly)
- return;
-
// Text clips are painted only for the direct inline children of the object
// that has a text clip style on it, not block children.
- DCHECK(paint_info.phase != PaintPhase::kTextClip);
+ if (paint_info.phase == PaintPhase::kTextClip)
+ return;
- bool is_self_painting = PhysicalFragment().Layer() &&
- PhysicalFragment().Layer()->IsSelfPaintingLayer();
- PaintAllPhasesAtomically(paint_info, is_self_painting);
+ PaintAllPhasesAtomically(paint_info);
}
bool NGBoxFragmentPainter::IsPaintingScrollingBackground(
@@ -977,8 +988,9 @@ bool NGBoxFragmentPainter::NodeAtPoint(
// HitTestOverflowControl(result, location_in_container, physical_offset))
// return true;
- bool skip_children = false;
- if (box_fragment_.ShouldClipOverflow()) {
+ bool skip_children = result.GetHitTestRequest().GetStopNode() ==
+ PhysicalFragment().GetLayoutObject();
+ if (!skip_children && box_fragment_.ShouldClipOverflow()) {
// PaintLayer::HitTestContentsForFragments checked the fragments'
// foreground rect for intersection if a layer is self painting,
// so only do the overflow clip check here for non-self-painting layers.
@@ -1012,6 +1024,11 @@ bool NGBoxFragmentPainter::NodeAtPoint(
// Now hit test ourselves.
if (hit_test_self && VisibleToHitTestRequest(result.GetHitTestRequest())) {
LayoutRect bounds_rect(physical_offset, size);
+ if (UNLIKELY(result.GetHitTestRequest().GetType() &
+ HitTestRequest::kHitTestVisualOverflow)) {
+ bounds_rect = PhysicalFragment().SelfInkOverflow().ToLayoutRect();
+ bounds_rect.MoveBy(physical_offset);
+ }
if (location_in_container.Intersects(bounds_rect)) {
Node* node = box_fragment_.NodeForHitTest();
if (!result.InnerNode() && node) {
@@ -1060,6 +1077,12 @@ bool NGBoxFragmentPainter::HitTestTextFragment(
// TODO(layout-dev): Clip to line-top/bottom.
LayoutRect rect = LayoutRect(PixelSnappedIntRect(border_rect));
+ if (UNLIKELY(result.GetHitTestRequest().GetType() &
+ HitTestRequest::kHitTestVisualOverflow)) {
+ rect = text_paint_fragment.SelfInkOverflow();
+ rect.MoveBy(border_rect.Location());
+ }
+
if (FragmentVisibleToHitTestRequest(text_paint_fragment,
result.GetHitTestRequest()) &&
location_in_container.Intersects(rect)) {
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
index 440d6ad9892..41a6a376eb9 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h
@@ -73,8 +73,8 @@ class NGBoxFragmentPainter : public BoxPainterBase {
const LayoutRect&);
bool BackgroundIsKnownToBeOpaque(const PaintInfo&);
- void PaintAllPhasesAtomically(const PaintInfo&,
- bool is_self_painting);
+ void PaintInternal(const PaintInfo&);
+ void PaintAllPhasesAtomically(const PaintInfo&);
void PaintBlockChildren(const PaintInfo&);
void PaintLineBoxChildren(NGPaintFragment::ChildList,
const PaintInfo&,
@@ -114,6 +114,10 @@ class NGBoxFragmentPainter : public BoxPainterBase {
void RecordHitTestData(const PaintInfo& paint_info,
const LayoutPoint& paint_offset);
+ void RecordHitTestDataForLine(const PaintInfo& paint_info,
+ const LayoutPoint& paint_offset,
+ const NGPaintFragment& line);
+
bool IsInSelfHitTestingPhase(HitTestAction) const;
bool VisibleToHitTestRequest(const HitTestRequest&) const;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
index 80875643be1..068751b0fb8 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.cc
@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
@@ -77,4 +78,26 @@ void NGFragmentPainter::AddPDFURLRectIfNeeded(const PaintInfo& paint_info,
paint_info.context.SetURLForRect(url, rect);
}
+bool NGFragmentPainter::ShouldRecordHitTestData(
+ const PaintInfo& paint_info,
+ const NGPhysicalFragment& fragment) {
+ if (!RuntimeEnabledFeatures::PaintTouchActionRectsEnabled())
+ return false;
+
+ // Hit test display items are only needed for compositing. This flag is used
+ // for for printing and drag images which do not need hit testing.
+ if (paint_info.GetGlobalPaintFlags() & kGlobalPaintFlattenCompositingLayers)
+ return false;
+
+ // If an object is not visible, it does not participate in hit testing.
+ if (fragment.Style().Visibility() != EVisibility::kVisible)
+ return false;
+
+ auto touch_action = fragment.EffectiveWhitelistedTouchAction();
+ if (touch_action == TouchAction::kTouchActionAuto)
+ return false;
+
+ return true;
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
index 7ab368df028..de46ce700c5 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_fragment_painter.h
@@ -12,6 +12,7 @@ namespace blink {
class LayoutPoint;
class NGPaintFragment;
+class NGPhysicalFragment;
struct PaintInfo;
// Generic fragment painter for paint logic shared between all types of
@@ -27,6 +28,9 @@ class NGFragmentPainter : public ObjectPainterBase {
void AddPDFURLRectIfNeeded(const PaintInfo&, const LayoutPoint& paint_offset);
+ static bool ShouldRecordHitTestData(const PaintInfo&,
+ const NGPhysicalFragment&);
+
private:
const NGPaintFragment& paint_fragment_;
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
index c884762044b..1db51376153 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.cc
@@ -82,7 +82,9 @@ void NGInlineBoxFragmentPainter::PaintBackgroundBorderShadow(
inline_box_fragment_.InlineFragmentsFor(
inline_box_fragment_.GetLayoutObject());
NGPaintFragment::FragmentRange::iterator iter = fragments.begin();
- bool object_has_multiple_boxes = ++iter != fragments.end();
+ DCHECK(iter != fragments.end());
+ bool object_has_multiple_boxes =
+ iter != fragments.end() && ++iter != fragments.end();
// TODO(eae): Switch to LayoutNG version of BackgroundImageGeometry.
BackgroundImageGeometry geometry(*static_cast<const LayoutBoxModelObject*>(
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
index 881e314410e..1b4a60ea873 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_inline_box_fragment_painter.h
@@ -8,9 +8,7 @@
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_border_edges.h"
#include "third_party/blink/renderer/core/paint/inline_box_painter_base.h"
#include "third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.h"
-
#include "third_party/blink/renderer/platform/wtf/allocator.h"
-#include "third_party/skia/include/core/SkBlendMode.h"
namespace blink {
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index 81a6fad320b..deb9dc75930 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -14,12 +14,14 @@
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_logical_rect.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_caret_position.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_text_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/layout_ng_block_flow.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h"
#include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_marker.h"
+#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h"
#include "third_party/blink/renderer/core/layout/ng/ng_fragment.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_type.h"
#include "third_party/blink/renderer/core/layout/ng/ng_outline_utils.h"
@@ -286,15 +288,21 @@ scoped_refptr<NGPaintFragment> NGPaintFragment::CreateOrReuse(
scoped_refptr<NGPaintFragment> NGPaintFragment::Create(
scoped_refptr<const NGPhysicalFragment> fragment,
NGPhysicalOffset offset,
+ const NGBlockBreakToken* block_break_token,
scoped_refptr<NGPaintFragment> previous_instance) {
DCHECK(fragment);
bool populate_children = fragment->IsContainer();
+ bool has_previous_instance = previous_instance.get();
scoped_refptr<NGPaintFragment> paint_fragment =
CreateOrReuse(std::move(fragment), offset, nullptr,
std::move(previous_instance), &populate_children);
if (populate_children) {
+ if (has_previous_instance) {
+ NGInlineNode::ClearAssociatedFragments(paint_fragment->PhysicalFragment(),
+ block_break_token);
+ }
HashMap<const LayoutObject*, NGPaintFragment*> last_fragment_map;
paint_fragment->PopulateDescendants(NGPhysicalOffset(), &last_fragment_map);
}
@@ -359,7 +367,7 @@ NGPaintFragment* NGPaintFragment::Last() {
scoped_refptr<NGPaintFragment>* NGPaintFragment::Find(
scoped_refptr<NGPaintFragment>* fragment,
- const NGBreakToken* break_token) {
+ const NGBlockBreakToken* break_token) {
DCHECK(fragment);
if (!break_token)
@@ -459,8 +467,7 @@ void NGPaintFragment::PopulateDescendants(
std::move(previous_child), &populate_children);
if (children_are_inline) {
- if (!child_fragment->IsFloating() &&
- !child_fragment->IsOutOfFlowPositioned() &&
+ if (!child_fragment->IsOutOfFlowPositioned() &&
!child_fragment->IsListMarker()) {
if (LayoutObject* layout_object = child_fragment->GetLayoutObject())
child->AssociateWithLayoutObject(layout_object, last_fragment_map);
@@ -487,17 +494,23 @@ void NGPaintFragment::AssociateWithLayoutObject(
HashMap<const LayoutObject*, NGPaintFragment*>* last_fragment_map) {
DCHECK(layout_object);
DCHECK(!next_for_same_layout_object_);
- DCHECK(layout_object->IsInline());
+ DCHECK(layout_object->IsInline() || layout_object->IsFloating());
auto add_result = last_fragment_map->insert(layout_object, this);
if (add_result.is_new_entry) {
- DCHECK(!layout_object->FirstInlineFragment());
- layout_object->SetFirstInlineFragment(this);
- } else {
- DCHECK(add_result.stored_value->value);
- add_result.stored_value->value->next_for_same_layout_object_ = this;
- add_result.stored_value->value = this;
+ NGPaintFragment* first_fragment = layout_object->FirstInlineFragment();
+ if (!first_fragment) {
+ layout_object->SetFirstInlineFragment(this);
+ return;
+ }
+ // This |layout_object| was fragmented across multiple blocks.
+ NGPaintFragment* last_fragment = first_fragment->LastForSameLayoutObject();
+ last_fragment->next_for_same_layout_object_ = this;
+ return;
}
+ DCHECK(add_result.stored_value->value);
+ add_result.stored_value->value->next_for_same_layout_object_ = this;
+ add_result.stored_value->value = this;
}
NGPaintFragment* NGPaintFragment::GetForInlineContainer(
@@ -539,11 +552,6 @@ NGPaintFragment* NGPaintFragment::LastForSameLayoutObject() {
return fragment;
}
-void NGPaintFragment::DirtyLinesFromChangedChild(LayoutObject* child) {
- if (child->IsInline())
- MarkLineBoxesDirtyFor(*child);
-}
-
bool NGPaintFragment::FlippedLocalVisualRectFor(
const LayoutObject* layout_object,
LayoutRect* visual_rect) {
@@ -629,8 +637,22 @@ NGPaintFragment* NGPaintFragment::FirstLineBox() const {
return nullptr;
}
+void NGPaintFragment::DirtyLinesFromChangedChild(LayoutObject* child) {
+ // This function should be called on every child that has
+ // |IsInLayoutNGInlineFormattingContext()|, meaning it was once collected into
+ // |NGInlineNode|.
+ //
+ // New LayoutObjects will be handled in the next |CollectInline()|.
+ DCHECK(child && child->IsInLayoutNGInlineFormattingContext());
+
+ if (child->IsInline() || child->IsFloatingOrOutOfFlowPositioned())
+ MarkLineBoxesDirtyFor(*child);
+}
+
void NGPaintFragment::MarkLineBoxesDirtyFor(const LayoutObject& layout_object) {
- DCHECK(layout_object.IsInline()) << layout_object;
+ DCHECK(layout_object.IsInline() ||
+ layout_object.IsFloatingOrOutOfFlowPositioned())
+ << layout_object;
// Since |layout_object| isn't in fragment tree, check preceding siblings.
// Note: Once we reuse lines below dirty lines, we should check next siblings.
@@ -774,6 +796,8 @@ PositionWithAffinity NGPaintFragment::PositionForPointInText(
const unsigned text_offset = text_fragment.TextOffsetForPoint(point);
const NGCaretPosition unadjusted_position{
this, NGCaretPositionType::kAtTextOffset, text_offset};
+ if (RuntimeEnabledFeatures::BidiCaretAffinityEnabled())
+ return unadjusted_position.ToPositionInDOMTreeWithAffinity();
if (text_offset > text_fragment.StartOffset() &&
text_offset < text_fragment.EndOffset()) {
return unadjusted_position.ToPositionInDOMTreeWithAffinity();
@@ -804,6 +828,9 @@ PositionWithAffinity NGPaintFragment::PositionForPointInInlineLevelBox(
LayoutUnit closest_child_after_inline_offset = LayoutUnit::Max();
for (const NGPaintFragment* child : Children()) {
+ if (child->PhysicalFragment().IsFloating())
+ continue;
+
const LayoutUnit child_inline_min =
ChildLogicalOffsetInParent(*child).inline_offset;
const LayoutUnit child_inline_max =
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index 7d331af509f..ce17ea10560 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -16,6 +16,7 @@
namespace blink {
class LayoutInline;
+class NGBlockBreakToken;
struct LayoutSelectionStatus;
struct PaintInfo;
enum class NGOutlineType;
@@ -47,6 +48,7 @@ class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>,
static scoped_refptr<NGPaintFragment> Create(
scoped_refptr<const NGPhysicalFragment>,
NGPhysicalOffset offset,
+ const NGBlockBreakToken* break_token,
scoped_refptr<NGPaintFragment> previous_instance = nullptr);
const NGPhysicalFragment& PhysicalFragment() const {
@@ -63,7 +65,7 @@ class CORE_EXPORT NGPaintFragment : public RefCounted<NGPaintFragment>,
NGPaintFragment* Last();
NGPaintFragment* Last(const NGBreakToken&);
static scoped_refptr<NGPaintFragment>* Find(scoped_refptr<NGPaintFragment>*,
- const NGBreakToken*);
+ const NGBlockBreakToken*);
template <typename Traverse>
class List {
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
index c1a1fe50234..2ff8b5d4067 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_test.cc
@@ -482,9 +482,10 @@ TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveChild) {
Element& target = *GetDocument().getElementById("target");
target.remove();
const NGPaintFragment& container = *GetPaintFragmentByElementId("container");
- EXPECT_TRUE(container.FirstChild()->IsDirty());
- EXPECT_TRUE(ToList(container.Children())[1]->IsDirty());
- EXPECT_FALSE(ToList(container.Children())[2]->IsDirty());
+ auto lines = ToList(container.Children());
+ EXPECT_TRUE(lines[0]->IsDirty());
+ EXPECT_FALSE(lines[1]->IsDirty());
+ EXPECT_FALSE(lines[2]->IsDirty());
}
TEST_F(NGPaintFragmentTest, MarkLineBoxesDirtyByRemoveSpanWithBr) {
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h
index 377e5466038..4923bc03057 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_paint_fragment_traversal.h
@@ -155,6 +155,7 @@ class CORE_EXPORT NGPaintFragmentTraversal {
static Vector<NGPaintFragmentWithContainerOffset> InlineDescendantsOf(
const NGPaintFragment&);
+ // Deprecated. Use NGPaintFragment::InlineFragmentsFor() instead.
static Vector<NGPaintFragmentWithContainerOffset> SelfFragmentsOf(
const NGPaintFragment&,
const LayoutObject* target);
diff --git a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc
index 8bbcb7b0c2b..460f49e71d5 100644
--- a/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/ng/ng_text_fragment_painter_test.cc
@@ -47,8 +47,7 @@ TEST_P(NGTextFragmentPainterTest, TestTextStyle) {
InvalidateAll(RootPaintController());
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- IntRect interest_rect(0, 0, 640, 480);
- Paint(&interest_rect);
+ Paint(IntRect(0, 0, 640, 480));
const NGPaintFragment& root_fragment = *block_flow.PaintFragment();
EXPECT_EQ(1u, root_fragment.Children().size());
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
index 806caccaa65..e5cff41e26b 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator.cc
@@ -138,7 +138,7 @@ void ObjectPaintInvalidator::
void ObjectPaintInvalidator::
InvalidatePaintIncludingNonCompositingDescendants() {
- DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
SlowSetPaintingLayerNeedsRepaint();
// This method may be used to invalidate paint of objects changing paint
// invalidation container. Visual rects don't have to be cleared, since they
@@ -178,7 +178,7 @@ bool IsClientNGPaintFragmentForObject(const DisplayItemClient& client,
if (!RuntimeEnabledFeatures::LayoutNGEnabled())
return false;
// TODO(crbug.com/880519): This hack only makes current invalidation tracking
- // layout tests pass with LayoutNG. More work is needed if we want to launch
+ // web tests pass with LayoutNG. More work is needed if we want to launch
// the invalidation tracking feature.
return object.IsLayoutBlockFlow() &&
&client == ToLayoutBlockFlow(object).PaintFragment();
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
index f538faee254..8c639ac8c9b 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_invalidator_test.cc
@@ -22,7 +22,7 @@ using ::testing::ElementsAre;
TEST_F(ObjectPaintInvalidatorTest,
TraverseNonCompositingDescendantsInPaintOrder) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
EnableCompositing();
@@ -73,7 +73,7 @@ TEST_F(ObjectPaintInvalidatorTest,
}
TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
EnableCompositing();
@@ -156,7 +156,7 @@ TEST_F(ObjectPaintInvalidatorTest, TraverseFloatUnderCompositedInline) {
TEST_F(ObjectPaintInvalidatorTest,
TraverseFloatUnderMultiLevelCompositedInlines) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
EnableCompositing();
@@ -220,7 +220,7 @@ TEST_F(ObjectPaintInvalidatorTest,
}
TEST_F(ObjectPaintInvalidatorTest, TraverseStackedFloatUnderCompositedInline) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
EnableCompositing();
diff --git a/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h b/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h
index 4c2f4b3ead3..a0562f50394 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h
+++ b/chromium/third_party/blink/renderer/core/paint/object_paint_properties.h
@@ -173,6 +173,13 @@ class CORE_EXPORT ObjectPaintProperties {
ADD_EFFECT(LinkHighlightEffect, link_highlight_effect_);
ADD_EFFECT(EffectIsolationNode, effect_isolation_node_);
+ // For a fragmented link highlight, we only need one LinkHighlightEffect node.
+ // PaintPropertyTreeBuilder uses this method to let the subsequent fragments
+ // share the same LinkHighlightEffect node created for the first fragment.
+ void SetLinkHighlightEffect(const EffectPaintPropertyNode* effect) {
+ link_highlight_effect_ = const_cast<EffectPaintPropertyNode*>(effect);
+ }
+
// The hierarchy of the clip subtree created by a LayoutObject is as follows:
// [ fragment clip ]
// | Clips to a fragment's bounds.
diff --git a/chromium/third_party/blink/renderer/core/paint/object_painter.cc b/chromium/third_party/blink/renderer/core/paint/object_painter.cc
index 9445e34562c..112deedc4ef 100644
--- a/chromium/third_party/blink/renderer/core/paint/object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/object_painter.cc
@@ -35,9 +35,8 @@ void ObjectPainter::PaintOutline(const PaintInfo& paint_info,
return;
}
- Vector<LayoutRect> outline_rects;
- layout_object_.AddOutlineRects(
- outline_rects, paint_offset,
+ auto outline_rects = layout_object_.PhysicalOutlineRects(
+ paint_offset,
layout_object_.OutlineRectsShouldIncludeBlockVisualOverflow());
if (outline_rects.IsEmpty())
return;
@@ -46,18 +45,6 @@ void ObjectPainter::PaintOutline(const PaintInfo& paint_info,
paint_info.context, layout_object_, paint_info.phase))
return;
- // The result rects are in coordinates of m_layoutObject's border box.
- // Block flipping is not applied yet if !m_layoutObject.isBox().
- if (!layout_object_.IsBox() &&
- layout_object_.StyleRef().IsFlippedBlocksWritingMode()) {
- LayoutBlock* container = layout_object_.ContainingBlock();
- if (container) {
- layout_object_.LocalToAncestorRects(outline_rects, container,
- -paint_offset, paint_offset);
- if (outline_rects.IsEmpty())
- return;
- }
- }
DrawingRecorder recorder(paint_info.context, layout_object_,
paint_info.phase);
PaintOutlineRects(paint_info, outline_rects, style_to_use);
@@ -87,10 +74,9 @@ void ObjectPainter::AddPDFURLRectIfNeeded(const PaintInfo& paint_info,
if (!url.IsValid())
return;
- Vector<LayoutRect> visual_overflow_rects;
- layout_object_.AddElementVisualOverflowRects(visual_overflow_rects,
- paint_offset);
- IntRect rect = PixelSnappedIntRect(UnionRect(visual_overflow_rects));
+ auto outline_rects = layout_object_.PhysicalOutlineRects(
+ paint_offset, NGOutlineType::kIncludeBlockVisualOverflow);
+ IntRect rect = PixelSnappedIntRect(UnionRect(outline_rects));
if (rect.IsEmpty())
return;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
index 96048abd457..53f6c8f6556 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.cc
@@ -67,7 +67,7 @@ TEST_P(PaintAndRasterInvalidationTest, TrackingForTracing) {
auto* target = GetDocument().getElementById("target");
auto get_debug_info = [&]() -> std::string {
auto* cc_layer =
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled()
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
? GetDocument()
.View()
->GetPaintArtifactCompositorForTesting()
@@ -320,7 +320,7 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedLayoutViewResize) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
GetLayoutView().GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto* mapping = GetLayoutView().Layer()->GetCompositedLayerMapping();
EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
@@ -355,7 +355,7 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedLayoutViewGradientResize) {
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
GetLayoutView().GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto* mapping = GetLayoutView().Layer()->GetCompositedLayerMapping();
EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
@@ -419,9 +419,9 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewResize) {
GetDocument().View()->SetTracksPaintInvalidations(true);
iframe->setAttribute(html_names::kStyleAttr, "height: 200px");
UpdateAllLifecyclePhasesForTest();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// TODO(wangxianzhu): This is probably incorrect, but for now we assume
- // any scrolling contents as composited during SPv2 painting. Perhaps we
+ // any scrolling contents as composited during CAP painting. Perhaps we
// need some heuristic about composited scrolling during painting.
EXPECT_FALSE(GetRasterInvalidationTracking()->HasInvalidations());
} else {
@@ -467,9 +467,9 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewGradientResize) {
GetDocument().View()->SetTracksPaintInvalidations(true);
content->setAttribute(html_names::kStyleAttr, "height: 500px");
UpdateAllLifecyclePhasesForTest();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// TODO(wangxianzhu): This is probably incorrect, but for now we assume
- // any scrolling contents as composited during SPv2 painting. Perhaps we
+ // any scrolling contents as composited during CAP painting. Perhaps we
// need some heuristic about composited scrolling during painting.
EXPECT_FALSE(GetRasterInvalidationTracking()->HasInvalidations());
} else {
@@ -485,9 +485,9 @@ TEST_P(PaintAndRasterInvalidationTest, NonCompositedLayoutViewGradientResize) {
GetDocument().View()->SetTracksPaintInvalidations(true);
iframe->setAttribute(html_names::kStyleAttr, "height: 200px");
UpdateAllLifecyclePhasesForTest();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// TODO(wangxianzhu): This is probably incorrect, but for now we assume
- // any scrolling contents as composited during SPv2 painting. Perhaps we
+ // any scrolling contents as composited during CAP painting. Perhaps we
// need some heuristic about composited scrolling during painting.
EXPECT_FALSE(GetRasterInvalidationTracking()->HasInvalidations());
} else {
@@ -517,7 +517,7 @@ TEST_P(PaintAndRasterInvalidationTest,
auto* target_obj = ToLayoutBoxModelObject(target->GetLayoutObject());
EXPECT_EQ(kBackgroundPaintInScrollingContents,
target_obj->GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto* mapping = target_obj->Layer()->GetCompositedLayerMapping();
EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
@@ -525,7 +525,7 @@ TEST_P(PaintAndRasterInvalidationTest,
auto container_raster_invalidation_tracking =
[&]() -> const RasterInvalidationTracking* {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return GetRasterInvalidationTracking(1);
return target_obj->Layer()
->GraphicsLayerBacking(target_obj)
@@ -533,7 +533,7 @@ TEST_P(PaintAndRasterInvalidationTest,
};
auto contents_raster_invalidation_tracking =
[&]() -> const RasterInvalidationTracking* {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return GetRasterInvalidationTracking(2);
return target_obj->Layer()
->GraphicsLayerBacking()
@@ -585,7 +585,7 @@ TEST_P(PaintAndRasterInvalidationTest,
ToLayoutBoxModelObject(target->GetLayoutObject());
auto container_raster_invalidation_tracking =
[&]() -> const RasterInvalidationTracking* {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return GetRasterInvalidationTracking(1);
return target_obj->Layer()
->GraphicsLayerBacking(target_obj)
@@ -593,7 +593,7 @@ TEST_P(PaintAndRasterInvalidationTest,
};
auto contents_raster_invalidation_tracking =
[&]() -> const RasterInvalidationTracking* {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return GetRasterInvalidationTracking(2);
return target_obj->Layer()
->GraphicsLayerBacking()
@@ -606,7 +606,7 @@ TEST_P(PaintAndRasterInvalidationTest,
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(kBackgroundPaintInScrollingContents,
target_obj->GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto* mapping = target_obj->Layer()->GetCompositedLayerMapping();
EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
EXPECT_FALSE(mapping->BackgroundPaintsOntoGraphicsLayer());
@@ -664,9 +664,9 @@ TEST_P(PaintAndRasterInvalidationTest,
GetDocument().View()->SetTracksPaintInvalidations(true);
target->setAttribute(html_names::kStyleAttr, "height: 200px");
UpdateAllLifecyclePhasesForTest();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// TODO(wangxianzhu): This is probably incorrect, but for now we assume
- // any scrolling contents as composited during SPv2 painting. Perhaps we
+ // any scrolling contents as composited during CAP painting. Perhaps we
// need some heuristic about composited scrolling during painting.
EXPECT_FALSE(GetRasterInvalidationTracking()->HasInvalidations());
} else {
@@ -701,14 +701,14 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedSolidBackgroundResize) {
EXPECT_EQ(
kBackgroundPaintInScrollingContents | kBackgroundPaintInGraphicsLayer,
target_object->GetBackgroundPaintLocation());
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto* mapping = target_object->Layer()->GetCompositedLayerMapping();
EXPECT_TRUE(mapping->BackgroundPaintsOntoScrollingContentsLayer());
EXPECT_TRUE(mapping->BackgroundPaintsOntoGraphicsLayer());
}
const auto* contents_raster_invalidation_tracking =
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled()
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
? GetRasterInvalidationTracking(2)
: target_object->Layer()
->GraphicsLayerBacking()
@@ -720,7 +720,7 @@ TEST_P(PaintAndRasterInvalidationTest, CompositedSolidBackgroundResize) {
&client, client.DebugName(), IntRect(50, 0, 50, 500),
PaintInvalidationReason::kIncremental}));
const auto* container_raster_invalidation_tracking =
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled()
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled()
? GetRasterInvalidationTracking(1)
: target_object->Layer()
->GraphicsLayerBacking(target_object)
@@ -877,8 +877,8 @@ TEST_P(PaintAndRasterInvalidationTest, SVGHiddenContainer) {
EXPECT_EQ(LayoutRect(55, 66, 7, 8), real_rect->FirstFragment().VisualRect());
// Should invalidate raster for real_rect only.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // SPv2 creates composited layers for the rect and its mask.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // CAP creates composited layers for the rect and its mask.
EXPECT_THAT(GetRasterInvalidationTracking(1)->Invalidations(),
UnorderedElementsAre(RasterInvalidationInfo{
real_rect, real_rect->DebugName(), IntRect(0, 0, 7, 8),
@@ -1055,7 +1055,7 @@ class PaintInvalidatorCustomClientTest : public RenderingTest {
public:
PaintInvalidatorCustomClientTest()
: RenderingTest(EmptyLocalFrameClient::Create()),
- chrome_client_(new PaintInvalidatorTestClient) {}
+ chrome_client_(MakeGarbageCollected<PaintInvalidatorTestClient>()) {}
PaintInvalidatorTestClient& GetChromeClient() const override {
return *chrome_client_;
@@ -1075,9 +1075,7 @@ TEST_F(PaintInvalidatorCustomClientTest,
NonCompositedInvalidationChangeOpacity) {
// This test runs in a non-composited mode, so invalidations should
// be issued via InvalidateChromeClient.
- SetBodyInnerHTML(R"HTML(
- <div id=target style="opacity: 0.99"></div>
- )HTML");
+ SetBodyInnerHTML("<div id=target style='opacity: 0.99'></div>");
auto* target = GetDocument().getElementById("target");
ASSERT_TRUE(target);
@@ -1090,4 +1088,26 @@ TEST_F(PaintInvalidatorCustomClientTest,
EXPECT_TRUE(InvalidationRecorded());
}
+TEST_F(PaintInvalidatorCustomClientTest,
+ NoInvalidationRepeatedUpdateLifecyleExceptPaint) {
+ SetBodyInnerHTML("<div id=target style='opacity: 0.99'></div>");
+
+ auto* target = GetDocument().getElementById("target");
+ ASSERT_TRUE(target);
+ ResetInvalidationRecorded();
+
+ target->setAttribute(html_names::kStyleAttr, "opacity: 0.98");
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ EXPECT_TRUE(GetDocument().View()->GetLayoutView()->Layer()->NeedsRepaint());
+ EXPECT_TRUE(InvalidationRecorded());
+
+ ResetInvalidationRecorded();
+ // Let PrePaintTreeWalk do something instead of no-op.
+ GetDocument().View()->SetNeedsPaintPropertyUpdate();
+ GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
+ // The layer NeedsRepaint flag is only cleared after paint.
+ EXPECT_TRUE(GetDocument().View()->GetLayoutView()->Layer()->NeedsRepaint());
+ EXPECT_FALSE(InvalidationRecorded());
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h b/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h
index fd4ee35e43e..4ce2ac4488e 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_and_raster_invalidation_test.h
@@ -19,7 +19,7 @@ class PaintAndRasterInvalidationTest : public PaintControllerPaintTest {
protected:
ContentLayerClientImpl* GetContentLayerClient(size_t index = 0) const {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
const auto& clients = GetDocument()
.View()
->GetPaintArtifactCompositorForTesting()
@@ -29,7 +29,7 @@ class PaintAndRasterInvalidationTest : public PaintControllerPaintTest {
const RasterInvalidationTracking* GetRasterInvalidationTracking(
size_t index = 0) const {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (auto* client = GetContentLayerClient(index))
return client->GetRasterInvalidator().GetTracking();
return nullptr;
@@ -43,7 +43,7 @@ class PaintAndRasterInvalidationTest : public PaintControllerPaintTest {
void SetUp() override {
PaintControllerPaintTest::SetUp();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
layer_tree_ = std::make_unique<LayerTreeHostEmbedder>();
layer_tree_->layer_tree_host()->SetRootLayer(
GetDocument()
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
index 40084431197..e0152cd3379 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.cc
@@ -22,8 +22,8 @@ namespace blink {
INSTANTIATE_PAINT_TEST_CASE_P(PaintControllerPaintTest);
-using PaintControllerPaintTestForSPv2 = PaintControllerPaintTest;
-INSTANTIATE_SPV2_TEST_CASE_P(PaintControllerPaintTestForSPv2);
+using PaintControllerPaintTestForCAP = PaintControllerPaintTest;
+INSTANTIATE_CAP_TEST_CASE_P(PaintControllerPaintTestForCAP);
TEST_P(PaintControllerPaintTest, FullDocumentPaintingWithCaret) {
SetBodyInnerHTML(
@@ -134,7 +134,7 @@ TEST_P(PaintControllerPaintTest, CompositingNoFold) {
IsSameId(&sub_div, kBackgroundType)));
}
-TEST_P(PaintControllerPaintTestForSPv2, FrameScrollingContents) {
+TEST_P(PaintControllerPaintTestForCAP, FrameScrollingContents) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none }
@@ -173,7 +173,7 @@ TEST_P(PaintControllerPaintTestForSPv2, FrameScrollingContents) {
IsSameId(&div4, kBackgroundType)));
}
-TEST_P(PaintControllerPaintTestForSPv2, BlockScrollingNonLayeredContents) {
+TEST_P(PaintControllerPaintTestForCAP, BlockScrollingNonLayeredContents) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none }
@@ -218,7 +218,7 @@ TEST_P(PaintControllerPaintTestForSPv2, BlockScrollingNonLayeredContents) {
IsSameId(&div4, kBackgroundType)));
}
-TEST_P(PaintControllerPaintTestForSPv2, ScrollHitTestOrder) {
+TEST_P(PaintControllerPaintTestForCAP, ScrollHitTestOrder) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none }
@@ -253,7 +253,7 @@ TEST_P(PaintControllerPaintTestForSPv2, ScrollHitTestOrder) {
IsSameId(&child, kBackgroundType)));
}
-TEST_P(PaintControllerPaintTestForSPv2, NonStackingScrollHitTestOrder) {
+TEST_P(PaintControllerPaintTestForCAP, NonStackingScrollHitTestOrder) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none }
@@ -299,7 +299,7 @@ TEST_P(PaintControllerPaintTestForSPv2, NonStackingScrollHitTestOrder) {
IsSameId(&pos_z_child, kBackgroundType)));
}
-TEST_P(PaintControllerPaintTestForSPv2, StackingScrollHitTestOrder) {
+TEST_P(PaintControllerPaintTestForCAP, StackingScrollHitTestOrder) {
SetBodyInnerHTML(R"HTML(
<style>
::-webkit-scrollbar { display: none }
@@ -343,7 +343,7 @@ TEST_P(PaintControllerPaintTestForSPv2, StackingScrollHitTestOrder) {
IsSameId(&pos_z_child, kBackgroundType)));
}
-TEST_P(PaintControllerPaintTestForSPv2,
+TEST_P(PaintControllerPaintTestForCAP,
NonStackingScrollHitTestOrderWithoutBackground) {
SetBodyInnerHTML(R"HTML(
<style>
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
index 10a82a00786..1a42a09c836 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_controller_paint_test.h
@@ -27,7 +27,7 @@ class PaintControllerPaintTestBase : public RenderingTest {
protected:
LayoutView& GetLayoutView() const { return *GetDocument().GetLayoutView(); }
PaintController& RootPaintController() const {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return *GetDocument().View()->GetPaintController();
return GetLayoutView()
.Layer()
@@ -40,9 +40,10 @@ class PaintControllerPaintTestBase : public RenderingTest {
EnableCompositing();
}
- bool PaintWithoutCommit(const IntRect* interest_rect = nullptr) {
+ bool PaintWithoutCommit(
+ const base::Optional<IntRect>& interest_rect = base::nullopt) {
GetDocument().View()->Lifecycle().AdvanceTo(DocumentLifecycle::kInPaint);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (GetLayoutView().Layer()->NeedsRepaint()) {
GraphicsContext graphics_context(RootPaintController());
GetDocument().View()->Paint(
@@ -55,8 +56,10 @@ class PaintControllerPaintTestBase : public RenderingTest {
return false;
}
// Only root graphics layer is supported.
- if (!GetLayoutView().Layer()->GraphicsLayerBacking()->PaintWithoutCommit(
- interest_rect)) {
+ if (!GetLayoutView()
+ .Layer()
+ ->GraphicsLayerBacking()
+ ->PaintWithoutCommitForTesting(interest_rect)) {
GetDocument().View()->Lifecycle().AdvanceTo(
DocumentLifecycle::kPaintClean);
return false;
@@ -77,7 +80,7 @@ class PaintControllerPaintTestBase : public RenderingTest {
GetDocument().View()->Lifecycle().AdvanceTo(DocumentLifecycle::kPaintClean);
}
- void Paint(const IntRect* interest_rect = nullptr) {
+ void Paint(const base::Optional<IntRect>& interest_rect = base::nullopt) {
// Only root graphics layer is supported.
if (PaintWithoutCommit(interest_rect))
CommitAndFinishCycle();
@@ -106,7 +109,7 @@ class PaintControllerPaintTestBase : public RenderingTest {
void InvalidateAll(PaintController& paint_controller) {
paint_controller.InvalidateAllForTesting();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
DCHECK_EQ(&paint_controller, GetDocument().View()->GetPaintController());
GetLayoutView().Layer()->SetNeedsRepaint();
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_event.h b/chromium/third_party/blink/renderer/core/paint/paint_event.h
index 69ba47b6238..02962212e7f 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_event.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_event.h
@@ -13,7 +13,6 @@ enum class PaintEvent {
kFirstPaint,
kFirstContentfulPaint,
kProvisionalFirstMeaningfulPaint,
- kFirstTextPaint,
kFirstImagePaint,
};
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_info.h b/chromium/third_party/blink/renderer/core/paint/paint_info.h
index fa4838be50b..6ad51c8e7f5 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_info.h
@@ -113,12 +113,12 @@ struct CORE_EXPORT PaintInfo {
return paint_flags_ & kPaintLayerPaintingRenderingResourceSubtree;
}
- // TODO(wangxianzhu): Rename this function to SkipBackground() for SPv2.
+ // TODO(wangxianzhu): Rename this function to SkipBackground() for CAP.
bool SkipRootBackground() const {
return paint_flags_ & kPaintLayerPaintingSkipRootBackground;
}
void SetSkipsBackground(bool b) {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
if (b)
paint_flags_ |= kPaintLayerPaintingSkipRootBackground;
else
@@ -170,11 +170,11 @@ struct CORE_EXPORT PaintInfo {
}
bool IsPaintingScrollingBackground() const {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
return is_painting_scrolling_background_;
}
void SetIsPaintingScrollingBackground(bool b) {
- DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
is_painting_scrolling_background_ = b;
}
@@ -197,7 +197,7 @@ struct CORE_EXPORT PaintInfo {
const GlobalPaintFlags global_paint_flags_;
const bool suppress_painting_descendants_;
- // For SPv2 only.
+ // For CAP only.
bool is_painting_scrolling_background_;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
index 83e098a5dc3..745a165a94b 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -14,8 +14,8 @@
#include "third_party/blink/renderer/core/layout/layout_table_section.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/layout/ng/geometry/ng_physical_offset_rect.h"
+#include "third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h"
#include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
-#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/paint/clip_path_clipper.h"
#include "third_party/blink/renderer/core/paint/find_paint_offset_and_visual_rect_needing_update.h"
#include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
@@ -35,8 +35,8 @@ void PaintInvalidator::ExcludeCompositedLayerSubpixelAccumulation(
const LayoutObject& object,
const PaintInvalidatorContext& context,
Rect& rect) {
- // TODO(wangxianzhu): How to handle sub-pixel location animation for SPv2?
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ // TODO(wangxianzhu): How to handle sub-pixel location animation for CAP?
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
// One of the following conditions happened in crbug.com/837226.
@@ -96,7 +96,7 @@ LayoutRect PaintInvalidator::MapLocalRectToVisualRect(
ToLayoutBox(object).FlipForWritingMode(rect);
} else if (!(context.subtree_flags &
PaintInvalidatorContext::kSubtreeSlowPathRect)) {
- // For SPv2 and the GeometryMapper path, we also need to convert the
+ // For CAP and the GeometryMapper path, we also need to convert the
// rect for non-boxes into physical coordinates before applying paint
// offset. (Otherwise we'll call mapToVisualrectInAncestorSpace() which
// requires physical coordinates for boxes, but "physical coordinates
@@ -162,8 +162,7 @@ LayoutRect PaintInvalidator::ComputeVisualRect(
static LayoutRect ComputeFragmentLocalSelectionRect(
const NGPaintFragment& fragment) {
- if (!fragment.PhysicalFragment().IsText())
- return LayoutRect();
+ DCHECK(fragment.PhysicalFragment().IsText());
const FrameSelection& frame_selection =
fragment.GetLayoutObject()->GetFrame()->Selection();
const LayoutSelectionStatus status =
@@ -193,12 +192,20 @@ void PaintInvalidator::UpdatePaintingLayer(const LayoutObject& object,
context.painting_layer = ToLayoutBoxModelObject(object).Layer();
} else if (object.IsColumnSpanAll() ||
object.IsFloatingWithNonContainingBlockParent()) {
- // See LayoutObject::paintingLayer() for the special-cases of floating under
+ // See |LayoutObject::PaintingLayer| for the special-cases of floating under
// inline and multicolumn.
+ // Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent|
+ // check can be removed as floats will be painted by the correct layer.
context.painting_layer = object.PaintingLayer();
}
- if (object.IsLayoutBlockFlow() && ToLayoutBlockFlow(object).ContainsFloats())
+ if (object.IsLayoutBlockFlow() && !object.IsLayoutNGBlockFlow() &&
+ ToLayoutBlockFlow(object).ContainsFloats())
+ context.painting_layer->SetNeedsPaintPhaseFloat();
+
+ if (object.IsFloating() &&
+ (object.IsInLayoutNGInlineFormattingContext() ||
+ IsLayoutNGContainingBlock(object.ContainingBlock())))
context.painting_layer->SetNeedsPaintPhaseFloat();
// Table collapsed borders are painted in PaintPhaseDescendantBlockBackgrounds
@@ -240,17 +247,20 @@ void PaintInvalidator::UpdatePaintInvalidationContainer(
context.paint_invalidation_container_for_stacked_contents =
ToLayoutBoxModelObject(&object);
} else if (object.IsLayoutView()) {
- // paintInvalidationContainerForStackedContents is only for stacked
+ // paint_invalidation_container_for_stacked_contents is only for stacked
// descendants in its own frame, because it doesn't establish stacking
// context for stacked contents in sub-frames.
// Contents stacked in the root stacking context in this frame should use
- // this frame's paintInvalidationContainer.
+ // this frame's PaintInvalidationContainer.
context.paint_invalidation_container_for_stacked_contents =
- context.paint_invalidation_container;
- } else if (object.IsFloatingWithNonContainingBlockParent() ||
- object.IsColumnSpanAll()) {
+ context.paint_invalidation_container =
+ &object.ContainerForPaintInvalidation();
+ } else if (object.IsColumnSpanAll() ||
+ object.IsFloatingWithNonContainingBlockParent()) {
// In these cases, the object may belong to an ancestor of the current
// paint invalidation container, in paint order.
+ // Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent|
+ // check can be removed as floats will be painted by the correct layer.
context.paint_invalidation_container =
&object.ContainerForPaintInvalidation();
} else if (object.StyleRef().IsStacked() &&
@@ -331,70 +341,52 @@ void PaintInvalidator::UpdateVisualRect(const LayoutObject& object,
// VisualRect for each fragment from |new_visual_rect|.
auto fragments = NGPaintFragment::InlineFragmentsFor(&object);
if (fragments.IsInLayoutNGInlineFormattingContext()) {
- for (NGPaintFragment* fragment : fragments) {
- LayoutRect local_selection_rect =
- ComputeFragmentLocalSelectionRect(*fragment);
- LayoutRect local_visual_rect =
- UnionRect(fragment->SelfInkOverflow(), local_selection_rect);
- fragment->SetVisualRect(MapFragmentLocalRectToVisualRect(
- local_visual_rect, object, *fragment, context));
-
- LayoutRect selection_visual_rect = MapFragmentLocalRectToVisualRect(
- local_selection_rect, object, *fragment, context);
- const bool should_invalidate =
- object.ShouldInvalidateSelection() ||
- selection_visual_rect != fragment->SelectionVisualRect();
- const bool rect_exists = !selection_visual_rect.IsEmpty() ||
- !fragment->SelectionVisualRect().IsEmpty();
- if (should_invalidate && rect_exists) {
- context.painting_layer->SetNeedsRepaint();
- ObjectPaintInvalidator(object).InvalidateDisplayItemClient(
- *fragment, PaintInvalidationReason::kSelection);
- fragment->SetSelectionVisualRect(selection_visual_rect);
+ bool has_selection_in_this_object =
+ object.IsText() && ToLayoutText(object).IsSelected();
+ if (!has_selection_in_this_object) {
+ for (NGPaintFragment* fragment : fragments) {
+ LayoutRect local_visual_rect = fragment->SelfInkOverflow();
+ fragment->SetVisualRect(MapFragmentLocalRectToVisualRect(
+ local_visual_rect, object, *fragment, context));
+
+ if (UNLIKELY(!fragment->SelectionVisualRect().IsEmpty())) {
+ context.painting_layer->SetNeedsRepaint();
+ ObjectPaintInvalidator(object).InvalidateDisplayItemClient(
+ *fragment, PaintInvalidationReason::kSelection);
+ fragment->SetSelectionVisualRect(LayoutRect());
+ }
+ }
+ } else {
+ // TODO(kojii): It's not clear why we need to pre-compute selection rect
+ // for all fragments when legacy can handle it as needed. yoichio will
+ // look into this.
+ for (NGPaintFragment* fragment : fragments) {
+ LayoutRect local_selection_rect =
+ ComputeFragmentLocalSelectionRect(*fragment);
+ LayoutRect local_visual_rect =
+ UnionRect(fragment->SelfInkOverflow(), local_selection_rect);
+ fragment->SetVisualRect(MapFragmentLocalRectToVisualRect(
+ local_visual_rect, object, *fragment, context));
+
+ LayoutRect selection_visual_rect = MapFragmentLocalRectToVisualRect(
+ local_selection_rect, object, *fragment, context);
+ const bool should_invalidate =
+ object.ShouldInvalidateSelection() ||
+ selection_visual_rect != fragment->SelectionVisualRect();
+ const bool rect_exists = !selection_visual_rect.IsEmpty() ||
+ !fragment->SelectionVisualRect().IsEmpty();
+ if (should_invalidate && rect_exists) {
+ context.painting_layer->SetNeedsRepaint();
+ ObjectPaintInvalidator(object).InvalidateDisplayItemClient(
+ *fragment, PaintInvalidationReason::kSelection);
+ fragment->SetSelectionVisualRect(selection_visual_rect);
+ }
}
}
}
}
}
-void PaintInvalidator::InvalidatePaint(
- LocalFrameView& frame_view,
- const PaintPropertyTreeBuilderContext* tree_builder_context,
-
- PaintInvalidatorContext& context) {
- LayoutView* layout_view = frame_view.GetLayoutView();
- CHECK(layout_view);
-
- context.paint_invalidation_container =
- context.paint_invalidation_container_for_stacked_contents =
- &layout_view->ContainerForPaintInvalidation();
- context.painting_layer = layout_view->Layer();
- context.fragment_data = &layout_view->FirstFragment();
- if (tree_builder_context) {
- context.tree_builder_context_ = &tree_builder_context->fragments[0];
-#if DCHECK_IS_ON()
- context.tree_builder_context_actually_needed_ =
- tree_builder_context->is_actually_needed;
-#endif
- }
-}
-
-static void InvalidateChromeClient(
- const LayoutBoxModelObject& paint_invalidation_container) {
- if (paint_invalidation_container.GetDocument().Printing() &&
- !RuntimeEnabledFeatures::PrintBrowserEnabled())
- return;
-
- DCHECK(paint_invalidation_container.IsLayoutView());
- DCHECK(!paint_invalidation_container.IsPaintInvalidationContainer());
-
- auto* frame_view = paint_invalidation_container.GetFrameView();
- DCHECK(!frame_view->GetFrame().OwnerLayoutObject());
- if (auto* client = frame_view->GetChromeClient()) {
- client->InvalidateRect(IntRect(IntPoint(), frame_view->Size()));
- }
-}
-
void PaintInvalidator::UpdateEmptyVisualRectFlag(
const LayoutObject& object,
PaintInvalidatorContext& context) {
@@ -404,7 +396,7 @@ void PaintInvalidator::UpdateEmptyVisualRectFlag(
// Content under transforms needs to invalidate, even if visual
// rects before and after update were the same. This is because
// we don't know whether this transform will end up composited in
- // SPv2, so such transforms are painted even if not visible
+ // CAP, so such transforms are painted even if not visible
// due to ancestor clips. This does not apply in SPv1 mode when
// crossing paint invalidation container boundaries.
if (is_paint_invalidation_container) {
@@ -417,7 +409,7 @@ void PaintInvalidator::UpdateEmptyVisualRectFlag(
}
}
-void PaintInvalidator::InvalidatePaint(
+bool PaintInvalidator::InvalidatePaint(
const LayoutObject& object,
const PaintPropertyTreeBuilderContext* tree_builder_context,
PaintInvalidatorContext& context) {
@@ -425,11 +417,11 @@ void PaintInvalidator::InvalidatePaint(
"PaintInvalidator::InvalidatePaint()", "object",
object.DebugName().Ascii());
- if (object.IsSVGHiddenContainer()) {
+ if (object.IsSVGHiddenContainer())
context.subtree_flags |= PaintInvalidatorContext::kSubtreeNoInvalidation;
- }
+
if (context.subtree_flags & PaintInvalidatorContext::kSubtreeNoInvalidation)
- return;
+ return false;
object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation();
@@ -449,7 +441,7 @@ void PaintInvalidator::InvalidatePaint(
UpdateEmptyVisualRectFlag(object, context);
if (!object.ShouldCheckForPaintInvalidation() && !context.NeedsSubtreeWalk())
- return;
+ return false;
unsigned tree_builder_index = 0;
@@ -521,14 +513,7 @@ void PaintInvalidator::InvalidatePaint(
PaintInvalidatorContext::kSubtreeInvalidationChecking;
}
- // The object is under a frame for WebViewPlugin, SVG images etc. Need to
- // inform the chrome client of the invalidation so that the client will
- // initiate painting of the contents.
- // TODO(wangxianzhu): Do we need this for SPv2?
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
- !context.paint_invalidation_container->IsPaintInvalidationContainer() &&
- reason != PaintInvalidationReason::kNone)
- InvalidateChromeClient(*context.paint_invalidation_container);
+ return reason != PaintInvalidationReason::kNone;
}
void PaintInvalidator::ProcessPendingDelayedPaintInvalidations() {
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
index cabfa006fe6..870bc8adff3 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -138,10 +138,8 @@ struct CORE_EXPORT PaintInvalidatorContext {
class PaintInvalidator {
public:
- void InvalidatePaint(LocalFrameView&,
- const PaintPropertyTreeBuilderContext*,
- PaintInvalidatorContext&);
- void InvalidatePaint(const LayoutObject&,
+ // Returns true if the object is invalidated.
+ bool InvalidatePaint(const LayoutObject&,
const PaintPropertyTreeBuilderContext*,
PaintInvalidatorContext&);
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 90810d02437..701e10b3659 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -140,6 +140,7 @@ PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
: is_root_layer_(layout_object.IsLayoutView()),
has_visible_content_(false),
needs_descendant_dependent_flags_update_(true),
+ needs_visual_overflow_recalc_(true),
has_visible_descendant_(false),
#if DCHECK_IS_ON()
// The root layer (LayoutView) does not need position update at start
@@ -148,8 +149,10 @@ PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
#endif
has3d_transformed_descendant_(false),
contains_dirty_overlay_scrollbars_(false),
- needs_ancestor_dependent_compositing_inputs_update_(true),
- child_needs_compositing_inputs_update_(true),
+ needs_ancestor_dependent_compositing_inputs_update_(
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()),
+ child_needs_compositing_inputs_update_(
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()),
has_compositing_descendant_(false),
should_isolate_composited_descendants_(false),
lost_grouped_mapping_(false),
@@ -167,7 +170,8 @@ PaintLayer::PaintLayer(LayoutBoxModelObject& layout_object)
filter_on_effect_node_dirty_(false),
is_under_svg_hidden_container_(false),
descendant_has_direct_or_scrolling_compositing_reason_(false),
- needs_compositing_reasons_update_(true),
+ needs_compositing_reasons_update_(
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()),
descendant_may_need_compositing_requirements_update_(false),
needs_compositing_layer_assignment_(false),
descendant_needs_compositing_layer_assignment_(false),
@@ -348,26 +352,6 @@ bool PaintLayer::SticksToScroller() const {
bool PaintLayer::FixedToViewport() const {
if (GetLayoutObject().StyleRef().GetPosition() != EPosition::kFixed)
return false;
-
- // TODO(pdr): This approach of calculating the nearest scroll node is O(n).
- // An option for improving this is to cache the nearest scroll node in
- // the local border box properties.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- const auto view_border_box_properties =
- GetLayoutObject().View()->FirstFragment().LocalBorderBoxProperties();
- const auto* view_scroll = view_border_box_properties.Transform()
- ->NearestScrollTranslationNode()
- .ScrollNode();
-
- const auto* scroll = GetLayoutObject()
- .FirstFragment()
- .LocalBorderBoxProperties()
- .Transform()
- ->NearestScrollTranslationNode()
- .ScrollNode();
- return scroll == view_scroll;
- }
-
return GetLayoutObject().Container() == GetLayoutObject().View();
}
@@ -467,7 +451,7 @@ void PaintLayer::UpdateTransform(const ComputedStyle* old_style,
if (had3d_transform != Has3DTransform()) {
SetNeedsCompositingInputsUpdateInternal();
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
}
if (LocalFrameView* frame_view = GetLayoutObject().GetDocument().View())
@@ -611,20 +595,20 @@ void PaintLayer::MapPointInPaintInvalidationContainerToBacking(
if (!paint_invalidation_layer->GroupedMapping())
return;
- LayoutBoxModelObject& transformed_ancestor =
- paint_invalidation_layer->TransformAncestorOrRoot().GetLayoutObject();
+ GraphicsLayer* squashing_layer =
+ paint_invalidation_layer->GroupedMapping()->SquashingLayer();
- // |paintInvalidationContainer| may have a local 2D transform on it, so take
- // that into account when mapping into the space of the transformed ancestor.
- point = paint_invalidation_container.LocalToAncestorPoint(
- point, &transformed_ancestor);
- // Don't include composited scroll offsets, since
- // SquashingOffsetFromTransformedAncestor does not.
- if (transformed_ancestor.UsesCompositedScrolling())
- point.Move(ToLayoutBox(transformed_ancestor).ScrolledContentOffset());
+ PropertyTreeState source_state =
+ paint_invalidation_container.FirstFragment().LocalBorderBoxProperties();
+ PropertyTreeState dest_state = squashing_layer->GetPropertyTreeState();
- point.MoveBy(-paint_invalidation_layer->GroupedMapping()
- ->SquashingOffsetFromTransformedAncestor());
+ // Move the point into the source_state transform space, map to dest_state
+ // transform space, then move into squashing layer state.
+ point.MoveBy(paint_invalidation_container.FirstFragment().PaintOffset());
+ point = GeometryMapper::SourceToDestinationProjection(
+ source_state.Transform(), dest_state.Transform())
+ .MapPoint(point);
+ point.MoveBy(-squashing_layer->GetOffsetFromTransformNode());
}
void PaintLayer::MapRectInPaintInvalidationContainerToBacking(
@@ -634,61 +618,44 @@ void PaintLayer::MapRectInPaintInvalidationContainerToBacking(
if (!paint_invalidation_layer->GroupedMapping())
return;
- LayoutBoxModelObject& transformed_ancestor =
- paint_invalidation_layer->TransformAncestorOrRoot().GetLayoutObject();
+ GraphicsLayer* squashing_layer =
+ paint_invalidation_layer->GroupedMapping()->SquashingLayer();
- // |paintInvalidationContainer| may have a local 2D transform on it, so take
- // that into account when mapping into the space of the transformed ancestor.
- rect = LayoutRect(
- paint_invalidation_container
- .LocalToAncestorQuad(FloatRect(rect), &transformed_ancestor)
- .BoundingBox());
- // Don't include composited scroll offsets, since
- // SquashingOffsetFromTransformedAncestor does not.
- if (transformed_ancestor.UsesCompositedScrolling())
- rect.Move(ToLayoutBox(transformed_ancestor).ScrolledContentOffset());
+ PropertyTreeState source_state =
+ paint_invalidation_container.FirstFragment().LocalBorderBoxProperties();
+ PropertyTreeState dest_state = squashing_layer->GetPropertyTreeState();
- rect.MoveBy(-paint_invalidation_layer->GroupedMapping()
- ->SquashingOffsetFromTransformedAncestor());
-}
-
-void PaintLayer::MapRectToPaintInvalidationBacking(
- const LayoutObject& layout_object,
- const LayoutBoxModelObject& paint_invalidation_container,
- LayoutRect& rect) {
- if (!paint_invalidation_container.Layer()->GroupedMapping()) {
- layout_object.MapToVisualRectInAncestorSpace(&paint_invalidation_container,
- rect);
- return;
- }
-
- // This code adjusts the visual rect to be in the space of the transformed
- // ancestor of the grouped (i.e. squashed) layer. This is because all layers
- // that squash together need to issue paint invalidations w.r.t. a single
- // container that is an ancestor of all of them, in order to properly take
- // into account any local transforms etc.
- // FIXME: remove this special-case code that works around the paint
- // invalidation code structure.
- layout_object.MapToVisualRectInAncestorSpace(&paint_invalidation_container,
- rect);
-
- MapRectInPaintInvalidationContainerToBacking(paint_invalidation_container,
- rect);
+ // Move the point into the source_state transform space, map to dest_state
+ // transform space, then move into squashing layer state.
+ rect.MoveBy(paint_invalidation_container.FirstFragment().PaintOffset());
+ rect = GeometryMapper::SourceToDestinationProjection(source_state.Transform(),
+ dest_state.Transform())
+ .MapRect(rect);
+ rect.MoveBy(-squashing_layer->GetOffsetFromTransformNode());
}
void PaintLayer::DirtyVisibleContentStatus() {
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
// Non-self-painting layers paint into their ancestor layer, and count as part
// of the "visible contents" of the parent, so we need to dirty it.
if (!IsSelfPaintingLayer())
Parent()->DirtyVisibleContentStatus();
}
-void PaintLayer::MarkAncestorChainForDescendantDependentFlagsUpdate() {
+void PaintLayer::MarkAncestorChainForFlagsUpdate(
+ DescendantDependentFlagsUpdateFlag flag) {
+#if DCHECK_IS_ON()
+ DCHECK(flag == DoesNotNeedDescendantDependentUpdate ||
+ !layout_object_.GetDocument()
+ .View()
+ ->IsUpdatingDescendantDependentFlags());
+#endif
for (PaintLayer* layer = this; layer; layer = layer->Parent()) {
- if (layer->needs_descendant_dependent_flags_update_)
+ if (layer->needs_descendant_dependent_flags_update_ &&
+ layer->GetLayoutObject().NeedsPaintPropertyUpdate())
break;
- layer->needs_descendant_dependent_flags_update_ = true;
+ if (flag == NeedsDescendantDependentUpdate)
+ layer->needs_descendant_dependent_flags_update_ = true;
layer->GetLayoutObject().SetNeedsPaintPropertyUpdate();
}
}
@@ -765,6 +732,16 @@ void PaintLayer::UpdateDescendantDependentFlags() {
static_cast<bool>(has_non_isolated_descendant_with_blend_mode_))
GetLayoutObject().SetNeedsPaintPropertyUpdate();
needs_descendant_dependent_flags_update_ = false;
+
+ if (IsSelfPaintingLayer() && needs_visual_overflow_recalc_) {
+ LayoutRect old_visual_rect = GetLayoutObject().VisualOverflowRect();
+ GetLayoutObject().RecalcVisualOverflow();
+ if (old_visual_rect != GetLayoutObject().VisualOverflowRect()) {
+ SetNeedsCompositingInputsUpdateInternal();
+ MarkAncestorChainForFlagsUpdate(DoesNotNeedDescendantDependentUpdate);
+ }
+ }
+ needs_visual_overflow_recalc_ = false;
}
bool previously_has_visible_content = has_visible_content_;
@@ -1098,12 +1075,21 @@ void PaintLayer::SetNeedsCompositingInputsUpdate() {
// TODO(chrishtr): These are a bit of a heavy hammer, because not all
// things which require compositing inputs update require a descendant-
- // dependent flags udpate. Reduce call sites after SPv2 launch allows
+ // dependent flags update. Reduce call sites after CAP launch allows
/// removal of CompositingInputsUpdater.
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate(NeedsDescendantDependentUpdate);
+}
+
+void PaintLayer::SetNeedsVisualOverflowRecalc() {
+ DCHECK(IsSelfPaintingLayer());
+ needs_visual_overflow_recalc_ = true;
+ MarkAncestorChainForFlagsUpdate();
}
void PaintLayer::SetNeedsCompositingInputsUpdateInternal() {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ return;
+
needs_ancestor_dependent_compositing_inputs_update_ = true;
for (PaintLayer* current = this;
@@ -1119,11 +1105,13 @@ void PaintLayer::SetNeedsCompositingInputsUpdateInternal() {
void PaintLayer::UpdateAncestorDependentCompositingInputs(
const AncestorDependentCompositingInputs& compositing_inputs) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
EnsureAncestorDependentCompositingInputs() = compositing_inputs;
needs_ancestor_dependent_compositing_inputs_update_ = false;
}
void PaintLayer::ClearChildNeedsCompositingInputsUpdate() {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
DCHECK(!NeedsCompositingInputsUpdate());
child_needs_compositing_inputs_update_ = false;
}
@@ -1350,7 +1338,7 @@ void PaintLayer::AddChild(PaintLayer* child, PaintLayer* before_child) {
// building up generated content layers. This is ok, since the lists will
// start off dirty in that case anyway.
PaintLayerStackingNode::DirtyStackingContextZOrderLists(child);
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
}
// Non-self-painting children paint into this layer, so the visible contents
@@ -1358,7 +1346,7 @@ void PaintLayer::AddChild(PaintLayer* child, PaintLayer* before_child) {
if (!child->IsSelfPaintingLayer())
DirtyVisibleContentStatus();
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
// Need to force requirements update, due to change of stacking order.
SetNeedsCompositingRequirementsUpdate();
@@ -1404,7 +1392,7 @@ PaintLayer* PaintLayer::RemoveChild(PaintLayer* old_child) {
old_child->RemoveAncestorOverflowLayer(old_child->AncestorOverflowLayer());
if (old_child->has_visible_content_ || old_child->has_visible_descendant_)
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
if (old_child->EnclosingPaginationLayer())
old_child->ClearPaginationRecursive();
@@ -1413,7 +1401,7 @@ PaintLayer* PaintLayer::RemoveChild(PaintLayer* old_child) {
}
void PaintLayer::ClearClipRects(ClipRectsCacheSlot cache_slot) {
- Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ Clipper(GeometryMapperOption::kDoNotUseGeometryMapper)
.ClearClipRectsIncludingDescendants(cache_slot);
}
@@ -1424,11 +1412,11 @@ void PaintLayer::RemoveOnlyThisLayerAfterStyleChange(
if (old_style && old_style->IsStacked()) {
PaintLayerStackingNode::DirtyStackingContextZOrderLists(this);
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
}
bool did_set_paint_invalidation = false;
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// Destructing PaintLayer would cause CompositedLayerMapping and composited
// layers to be destructed and detach from layer tree immediately. Layers
// could have dangling scroll/clip parent if compositing update were
@@ -1497,7 +1485,7 @@ void PaintLayer::InsertOnlyThisLayerAfterStyleChange() {
// this object is stacked content, creating this layer may cause this object
// and its descendants to change paint invalidation container.
bool did_set_paint_invalidation = false;
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
!GetLayoutObject().IsLayoutView() && GetLayoutObject().IsRooted() &&
GetLayoutObject().StyleRef().IsStacked()) {
const LayoutBoxModelObject& previous_paint_invalidation_container =
@@ -1672,7 +1660,7 @@ void PaintLayer::AppendSingleFragmentIgnoringPagination(
root_layer, &root_layer->GetLayoutObject().FirstFragment(),
kUncachedClipRects, overlay_scrollbar_clip_behavior,
respect_overflow_clip, sub_pixel_accumulation);
- Clipper(kUseGeometryMapper)
+ Clipper(GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(clip_rects_context, &GetLayoutObject().FirstFragment(),
cull_rect, fragment.layer_bounds,
fragment.background_rect, fragment.foreground_rect,
@@ -1686,7 +1674,7 @@ bool PaintLayer::ShouldFragmentCompositedBounds(
const PaintLayer* compositing_layer) const {
if (!EnclosingPaginationLayer())
return false;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return true;
if (PaintsWithTransform(kGlobalPaintNormalPhase))
return true;
@@ -1770,7 +1758,7 @@ void PaintLayer::CollectFragments(
fragment_cull_rect.emplace(rect);
}
- Clipper(kUseGeometryMapper)
+ Clipper(GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(
clip_rects_context, fragment_data,
fragment_cull_rect ? &*fragment_cull_rect : nullptr,
@@ -1981,6 +1969,9 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
HitTestingTransformState* transform_state,
double* z_offset) {
const LayoutObject& layout_object = GetLayoutObject();
+ if (layout_object.PaintBlockedByDisplayLock())
+ return nullptr;
+
DCHECK_GE(layout_object.GetDocument().Lifecycle().GetState(),
DocumentLifecycle::kCompositingClean);
@@ -2014,7 +2005,7 @@ PaintLayer* PaintLayer::HitTestLayer(PaintLayer* root_layer,
// Make sure the parent's clip rects have been calculated.
if (Parent()) {
ClipRect clip_rect;
- Clipper(PaintLayer::kUseGeometryMapper)
+ Clipper(GeometryMapperOption::kUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(
root_layer, &root_layer->GetLayoutObject().FirstFragment(),
@@ -2442,16 +2433,42 @@ PaintLayer* PaintLayer::HitTestChildren(
return result_layer;
}
-FloatRect PaintLayer::FilterReferenceBox(const FilterOperations& filter,
- float zoom) const {
- if (!filter.HasReferenceFilter())
- return FloatRect();
+void PaintLayer::UpdateFilterReferenceBox() {
+ if (!NeedsFilterReferenceBox())
+ return;
+ FloatRect reference_box =
+ FloatRect(PhysicalBoundingBoxIncludingStackingChildren(
+ LayoutPoint(),
+ PaintLayer::kIncludeTransformsAndCompositedChildLayers));
+ float zoom = GetLayoutObject().StyleRef().EffectiveZoom();
+ if (zoom != 1)
+ reference_box.Scale(1 / zoom);
+ EnsureResourceInfo().SetFilterReferenceBox(reference_box);
+}
- FloatRect reference_box(PhysicalBoundingBoxIncludingStackingChildren(
- LayoutPoint(), PaintLayer::CalculateBoundsOptions::
- kIncludeTransformsAndCompositedChildLayers));
+bool PaintLayer::NeedsFilterReferenceBox() const {
+ if (GetLayoutObject().HasReflection() && GetLayoutObject().IsBox())
+ return true;
+ FilterOperations operations = GetLayoutObject().StyleRef().Filter();
+ if (operations.HasBlurOrReferenceFilter())
+ return true;
+ operations = GetLayoutObject().StyleRef().BackdropFilter();
+ return !operations.IsEmpty();
+}
+
+FloatRect PaintLayer::FilterReferenceBox() const {
+ DCHECK(IsAllowedToQueryCompositingState());
+ if (ResourceInfo())
+ return ResourceInfo()->FilterReferenceBox();
+ return FloatRect();
+}
+
+FloatRect PaintLayer::BackdropFilterBounds() const {
+ FloatRect reference_box(GetLayoutObject().BorderBoundingBox());
+ float zoom = GetLayoutObject().StyleRef().EffectiveZoom();
if (zoom != 1)
reference_box.Scale(1 / zoom);
+ reference_box.Move(-ToFloatSize(FilterReferenceBox().Location()));
return reference_box;
}
@@ -2669,7 +2686,7 @@ LayoutRect PaintLayer::BoundingBoxForCompositingInternal(
// If there is a clip applied by an ancestor to this PaintLayer but below or
// equal to |ancestorLayer|, apply that clip.
- LayoutRect result = Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ LayoutRect result = Clipper(GeometryMapperOption::kDoNotUseGeometryMapper)
.LocalClipRect(composited_layer);
result.Intersect(PhysicalBoundingBox(LayoutPoint()));
@@ -2720,7 +2737,7 @@ CompositingState PaintLayer::GetCompositingState() const {
bool PaintLayer::IsAllowedToQueryCompositingState() const {
if (g_compositing_query_mode == kCompositingQueriesAreAllowed ||
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return true;
return GetLayoutObject().GetDocument().Lifecycle().GetState() >=
DocumentLifecycle::kInCompositingUpdate;
@@ -2753,9 +2770,6 @@ void PaintLayer::EnsureCompositedLayerMapping() {
std::make_unique<CompositedLayerMapping>(*this);
rare_data_->composited_layer_mapping->SetNeedsGraphicsLayerUpdate(
kGraphicsLayerUpdateSubtree);
-
- if (PaintLayerResourceInfo* resource_info = ResourceInfo())
- resource_info->InvalidateFilterChain();
}
void PaintLayer::ClearCompositedLayerMapping(bool layer_being_destroyed) {
@@ -2772,12 +2786,6 @@ void PaintLayer::ClearCompositedLayerMapping(bool layer_being_destroyed) {
if (rare_data_)
rare_data_->composited_layer_mapping.reset();
-
- if (layer_being_destroyed)
- return;
-
- if (PaintLayerResourceInfo* resource_info = ResourceInfo())
- resource_info->InvalidateFilterChain();
}
void PaintLayer::SetGroupedMapping(CompositedLayerMapping* grouped_mapping,
@@ -2870,8 +2878,7 @@ bool PaintLayer::BackgroundIsKnownToBeOpaqueInRect(
if (Transform() && GetCompositingState() != kPaintsIntoOwnBacking)
return false;
- if (!RuntimeEnabledFeatures::CompositeOpaqueFixedPositionEnabled() &&
- GetLayoutObject().StyleRef().GetPosition() == EPosition::kFixed &&
+ if (GetLayoutObject().StyleRef().GetPosition() == EPosition::kFixed &&
GetCompositingState() != kPaintsIntoOwnBacking)
return false;
@@ -2946,8 +2953,11 @@ void PaintLayer::UpdateSelfPaintingLayer() {
// invalidate the new chain in addition to the old one.
MarkCompositingContainerChainForNeedsRepaint();
+ if (is_self_painting_layer)
+ SetNeedsVisualOverflowRecalc();
+
if (PaintLayer* parent = Parent()) {
- parent->MarkAncestorChainForDescendantDependentFlagsUpdate();
+ parent->MarkAncestorChainForFlagsUpdate();
if (PaintLayer* enclosing_self_painting_layer =
parent->EnclosingSelfPaintingLayer()) {
@@ -3016,8 +3026,6 @@ void PaintLayer::UpdateFilters(const ComputedStyle* old_style,
new_style.Filter().AddClient(EnsureResourceInfo());
if (had_resource_info && old_style)
old_style->Filter().RemoveClient(*ResourceInfo());
- if (PaintLayerResourceInfo* resource_info = ResourceInfo())
- resource_info->InvalidateFilterChain();
}
void PaintLayer::UpdateClipPath(const ComputedStyle* old_style,
@@ -3114,7 +3122,7 @@ void PaintLayer::StyleDidChange(StyleDifference diff,
}
if (PaintLayerStackingNode::StyleDidChange(this, old_style))
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
if (RequiresScrollableArea()) {
DCHECK(scrollable_area_);
@@ -3163,7 +3171,7 @@ void PaintLayer::StyleDidChange(StyleDifference diff,
// HasNonContainedAbsolutePositionDescendant depends on position changes.
if (!old_style || old_style->GetPosition() != new_style.GetPosition())
- MarkAncestorChainForDescendantDependentFlagsUpdate();
+ MarkAncestorChainForFlagsUpdate();
UpdateTransform(old_style, new_style);
UpdateFilters(old_style, new_style);
@@ -3176,15 +3184,12 @@ void PaintLayer::StyleDidChange(StyleDifference diff,
// context, in order to generate new paint chunks in the correct order.
// Raster invalidation will be issued if needed during paint.
SetNeedsRepaint();
- } else if (old_style) {
+ } else if (old_style &&
+ !RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// Change of PaintedOutputInvisible() will affect existence of paint
// chunks, so needs repaint.
- PaintLayerPainter painter(*this);
- // It's fine for PaintedOutputInvisible() to access the current
- // compositing state.
- DisableCompositingQueryAsserts disable;
- if (painter.PaintedOutputInvisible(*old_style) !=
- painter.PaintedOutputInvisible(new_style))
+ if (PaintLayerPainter::PaintedOutputInvisible(*old_style) !=
+ PaintLayerPainter::PaintedOutputInvisible(new_style))
SetNeedsRepaint();
}
}
@@ -3202,7 +3207,8 @@ LayoutPoint PaintLayer::LocationInternal() const {
PaintLayerClipper PaintLayer::Clipper(
GeometryMapperOption geometry_mapper_option) const {
- return PaintLayerClipper(*this, geometry_mapper_option == kUseGeometryMapper);
+ return PaintLayerClipper(*this, geometry_mapper_option ==
+ GeometryMapperOption::kUseGeometryMapper);
}
bool PaintLayer::ScrollsOverflow() const {
@@ -3225,35 +3231,44 @@ FilterOperations PaintLayer::FilterOperationsIncludingReflection() const {
void PaintLayer::UpdateCompositorFilterOperationsForFilter(
CompositorFilterOperations& operations) const {
- const auto& style = GetLayoutObject().StyleRef();
- float zoom = style.EffectiveZoom();
auto filter = FilterOperationsIncludingReflection();
- FloatRect reference_box = FilterReferenceBox(filter, zoom);
+ FloatRect reference_box = FilterReferenceBox();
if (!operations.IsEmpty() && !filter_on_effect_node_dirty_ &&
reference_box == operations.ReferenceBox())
return;
+ float zoom = GetLayoutObject().StyleRef().EffectiveZoom();
operations =
FilterEffectBuilder(reference_box, zoom).BuildFilterOperations(filter);
}
void PaintLayer::UpdateCompositorFilterOperationsForBackdropFilter(
- CompositorFilterOperations& operations) const {
+ CompositorFilterOperations& operations,
+ gfx::RectF* backdrop_filter_bounds) const {
+ DCHECK(backdrop_filter_bounds);
const auto& style = GetLayoutObject().StyleRef();
- float zoom = style.EffectiveZoom();
- auto filter = FilterOperationsIncludingReflection();
- FloatRect reference_box = FilterReferenceBox(filter, zoom);
- if (!operations.IsEmpty() && reference_box == operations.ReferenceBox())
+ if (style.BackdropFilter().IsEmpty()) {
+ operations.Clear();
return;
- operations = CreateCompositorFilterOperationsForBackdropFilter();
+ }
+ FloatRect reference_box = BackdropFilterBounds();
+ *backdrop_filter_bounds = reference_box;
+ if (operations.IsEmpty() || reference_box != operations.ReferenceBox())
+ operations = CreateCompositorFilterOperationsForBackdropFilter();
}
CompositorFilterOperations
PaintLayer::CreateCompositorFilterOperationsForBackdropFilter() const {
const auto& style = GetLayoutObject().StyleRef();
+ CompositorFilterOperations return_value;
+ if (style.BackdropFilter().IsEmpty()) {
+ return return_value;
+ }
float zoom = style.EffectiveZoom();
- FloatRect reference_box = FilterReferenceBox(style.BackdropFilter(), zoom);
- return FilterEffectBuilder(reference_box, zoom)
- .BuildFilterOperations(style.BackdropFilter());
+ FloatRect reference_box = BackdropFilterBounds();
+ return_value = FilterEffectBuilder(reference_box, zoom)
+ .BuildFilterOperations(style.BackdropFilter());
+ DCHECK(!return_value.IsEmpty());
+ return return_value;
}
PaintLayerResourceInfo& PaintLayer::EnsureResourceInfo() {
@@ -3283,9 +3298,9 @@ void PaintLayer::RemoveAncestorOverflowLayer(const PaintLayer* removed_layer) {
if (PaintLayerScrollableArea* ancestor_scrollable_area =
AncestorOverflowLayer()->GetScrollableArea()) {
- // TODO(pdr): When slimming paint v2 is enabled, we will need to
- // invalidate the scroll paint property subtree for this so main
- // thread scroll reasons are recomputed.
+ // TODO(pdr): When CompositeAfterPaint is enabled, we will need to
+ // invalidate the scroll paint property subtree for this so main thread
+ // scroll reasons are recomputed.
ancestor_scrollable_area->InvalidateStickyConstraintsFor(this);
}
}
@@ -3297,32 +3312,9 @@ void PaintLayer::RemoveAncestorOverflowLayer(const PaintLayer* removed_layer) {
}
}
-FilterEffect* PaintLayer::LastFilterEffect() const {
- // TODO(chrishtr): ensure (and assert) that compositing is clean here.
- if (!PaintsWithFilters())
- return nullptr;
- PaintLayerResourceInfo* resource_info = ResourceInfo();
- DCHECK(resource_info);
-
- if (resource_info->LastEffect())
- return resource_info->LastEffect();
-
- const auto& style = GetLayoutObject().StyleRef();
- float zoom = style.EffectiveZoom();
- FilterEffectBuilder builder(FilterReferenceBox(style.Filter(), zoom), zoom);
- resource_info->SetLastEffect(
- builder.BuildFilterEffect(FilterOperationsIncludingReflection()));
- return resource_info->LastEffect();
-}
-
FloatRect PaintLayer::MapRectForFilter(const FloatRect& rect) const {
if (!HasFilterThatMovesPixels())
return rect;
-
- // Ensure the filter-chain is refreshed wrt reference filters.
- // TODO(fs): Avoid having this side-effect inducing call.
- LastFilterEffect();
-
return FilterOperationsIncludingReflection().MapRect(rect);
}
@@ -3395,6 +3387,13 @@ void PaintLayer::ComputeSelfHitTestRects(
void PaintLayer::SetNeedsRepaint() {
SetNeedsRepaintInternal();
+ // If you need repaint, then you might issue raster invalidations, and in
+ // Composite after Paint mode, we do these in PAC::Update().
+ LocalFrameView* frame_view = GetLayoutObject().GetDocument().View();
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && frame_view) {
+ frame_view->SetPaintArtifactCompositorNeedsUpdate();
+ }
+
// Do this unconditionally to ensure container chain is marked when
// compositing status of the layer changes.
MarkCompositingContainerChainForNeedsRepaint();
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 232b549fab4..9068cf57d98 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer.h
@@ -346,6 +346,8 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
void DirtyVisibleContentStatus();
+ // True if this layer paints box decorations or a background. Touch-action
+ // rects are painted as part of the background so these are included here.
bool HasBoxDecorationsOrBackground() const;
bool HasVisibleBoxDecorations() const;
// True if this layer container layoutObjects that paint.
@@ -567,15 +569,6 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
const LayoutBoxModelObject& paint_invalidation_container,
LayoutRect&);
- // Adjusts the given rect (in the coordinate space of the LayoutObject) to the
- // coordinate space of |paintInvalidationContainer|'s GraphicsLayer backing.
- // Should use PaintInvalidatorContext::MapRectToPaintInvalidationBacking()
- // instead if PaintInvalidatorContext.
- static void MapRectToPaintInvalidationBacking(
- const LayoutObject&,
- const LayoutBoxModelObject& paint_invalidation_container,
- LayoutRect&);
-
bool PaintsWithTransparency(GlobalPaintFlags global_paint_flags) const {
return IsTransparent() && !PaintsIntoOwnBacking(global_paint_flags);
}
@@ -614,23 +607,26 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// only if |filter_on_effect_node_dirty_| is true or the reference box has
// changed. Otherwise it will be populated unconditionally.
void UpdateCompositorFilterOperationsForFilter(
- CompositorFilterOperations&) const;
+ CompositorFilterOperations& operations) const;
void SetFilterOnEffectNodeDirty() { filter_on_effect_node_dirty_ = true; }
void ClearFilterOnEffectNodeDirty() { filter_on_effect_node_dirty_ = false; }
+ // |backdrop_filter_bounds| is an out param from both of these functions, and
+ // it represents the clipping bounds for the filtered backdrop image only.
+ // This rect lives in the local transform space of the containing
+ // EffectPaintPropertyNode.
void UpdateCompositorFilterOperationsForBackdropFilter(
- CompositorFilterOperations&) const;
+ CompositorFilterOperations& operations,
+ gfx::RectF* backdrop_filter_bounds) const;
+ CompositorFilterOperations CreateCompositorFilterOperationsForBackdropFilter()
+ const;
void SetIsUnderSVGHiddenContainer(bool value) {
is_under_svg_hidden_container_ = value;
}
bool IsUnderSVGHiddenContainer() { return is_under_svg_hidden_container_; }
- CompositorFilterOperations CreateCompositorFilterOperationsForBackdropFilter()
- const;
-
bool PaintsWithFilters() const;
- FilterEffect* LastFilterEffect() const;
// Maps "forward" to determine which pixels in a destination rect are
// affected by pixels in the source rect.
@@ -647,6 +643,13 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
}
PaintLayerResourceInfo& EnsureResourceInfo();
+ // Filter reference box is the area over which the filter is computed, in the
+ // coordinate system of the object with the filter. Filter bounds is the
+ // reference box, offset by the object's location in the graphics layer.
+ FloatRect FilterReferenceBox() const;
+ FloatRect BackdropFilterBounds() const;
+
+ void UpdateFilterReferenceBox();
void UpdateFilters(const ComputedStyle* old_style,
const ComputedStyle& new_style);
void UpdateClipPath(const ComputedStyle* old_style,
@@ -678,7 +681,10 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
return scrollable_area_.Get();
}
- enum GeometryMapperOption { kUseGeometryMapper, kDoNotUseGeometryMapper };
+ enum class GeometryMapperOption {
+ kUseGeometryMapper,
+ kDoNotUseGeometryMapper
+ };
PaintLayerClipper Clipper(GeometryMapperOption) const;
@@ -757,8 +763,11 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool is_under_video = false;
};
-
+ void SetNeedsVisualOverflowRecalc();
void SetNeedsCompositingInputsUpdate();
+
+ // Use this internal method only for cases during the descendant-dependent
+ // tree walk.
bool ChildNeedsCompositingInputsUpdate() const {
return child_needs_compositing_inputs_update_;
}
@@ -1036,11 +1045,11 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
// Whether the value of isSelfPaintingLayer() changed since the last clearing
// (which happens after the flag is chedked during compositing update).
bool SelfPaintingStatusChanged() const {
- DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
return self_painting_status_changed_;
}
void ClearSelfPaintingStatusChanged() {
- DCHECK(!RuntimeEnabledFeatures::SlimmingPaintV2Enabled());
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
self_painting_status_changed_ = false;
}
@@ -1175,7 +1184,17 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
bool RequiresScrollableArea() const;
void UpdateScrollableArea();
- void MarkAncestorChainForDescendantDependentFlagsUpdate();
+ // Indicates whether the descendant-dependent tree walk bit should also
+ // be set.
+ enum DescendantDependentFlagsUpdateFlag {
+ NeedsDescendantDependentUpdate,
+ DoesNotNeedDescendantDependentUpdate
+ };
+
+ // Marks the ancestor chain for paint property update, and if
+ // the flag is set, the descendant-dependent tree walk as well.
+ void MarkAncestorChainForFlagsUpdate(
+ DescendantDependentFlagsUpdateFlag = NeedsDescendantDependentUpdate);
bool AttemptDirectCompositingUpdate(const StyleDifference&,
const ComputedStyle* old_style);
@@ -1215,7 +1234,7 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
const PaintLayer* stacking_parent,
CalculateBoundsOptions) const;
- FloatRect FilterReferenceBox(const FilterOperations&, float zoom) const;
+ bool NeedsFilterReferenceBox() const;
LayoutPoint LocationInternal() const;
@@ -1238,7 +1257,10 @@ class CORE_EXPORT PaintLayer : public DisplayItemClient {
const unsigned is_root_layer_ : 1;
unsigned has_visible_content_ : 1;
+
unsigned needs_descendant_dependent_flags_update_ : 1;
+ unsigned needs_visual_overflow_recalc_ : 1;
+
unsigned has_visible_descendant_ : 1;
#if DCHECK_IS_ON()
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
index 31723b02f8d..b068340c278 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_clipper_test.cc
@@ -48,14 +48,16 @@ TEST_F(PaintLayerClipperTest, ParentBackgroundClipRectSubpixelAccumulation) {
LayoutSize(FloatSize(0.25, 0.35)));
ClipRect background_rect_gm;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateBackgroundClipRect(context, background_rect_gm);
EXPECT_EQ(LayoutRect(FloatRect(8.25, 8.34375, 300, 300)),
background_rect_gm.Rect());
ClipRect background_rect_nogm;
- target_paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(context, background_rect_nogm);
EXPECT_EQ(LayoutRect(FloatRect(8.25, 8.34375, 300, 300)),
@@ -78,14 +80,16 @@ TEST_F(PaintLayerClipperTest, BackgroundClipRectSubpixelAccumulation) {
LayoutSize(FloatSize(0.25, 0.35)));
ClipRect background_rect_gm;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateBackgroundClipRect(context, background_rect_gm);
EXPECT_GE(background_rect_gm.Rect().Size().Width().ToInt(), 33554422);
EXPECT_GE(background_rect_gm.Rect().Size().Height().ToInt(), 33554422);
ClipRect background_rect_nogm;
- target_paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(context, background_rect_nogm);
EXPECT_GE(background_rect_nogm.Rect().Size().Width().ToInt(), 33554422);
@@ -110,14 +114,16 @@ TEST_F(PaintLayerClipperTest, SVGBackgroundClipRectSubpixelAccumulation) {
LayoutSize(FloatSize(0.25, 0.35)));
ClipRect background_rect_gm;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateBackgroundClipRect(context, background_rect_gm);
EXPECT_GE(background_rect_gm.Rect().Size().Width().ToInt(), 33554422);
EXPECT_GE(background_rect_gm.Rect().Size().Height().ToInt(), 33554422);
ClipRect background_rect_nogm;
- target_paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(context, background_rect_nogm);
EXPECT_GE(background_rect_nogm.Rect().Size().Width().ToInt(), 33554422);
@@ -145,7 +151,8 @@ TEST_F(PaintLayerClipperTest, LayoutSVGRoot) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -175,7 +182,8 @@ TEST_F(PaintLayerClipperTest, ControlClip) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -215,7 +223,8 @@ TEST_F(PaintLayerClipperTest, RoundedClip) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -256,7 +265,8 @@ TEST_F(PaintLayerClipperTest, RoundedClipNested) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- child_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ child_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&child_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -293,7 +303,8 @@ TEST_F(PaintLayerClipperTest, ControlClipSelect) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -326,7 +337,8 @@ TEST_F(PaintLayerClipperTest, LayoutSVGRootChild) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -352,7 +364,7 @@ TEST_F(PaintLayerClipperTest, ContainPaintClip) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- layer->Clipper(PaintLayer::kUseGeometryMapper)
+ layer->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
EXPECT_GE(background_rect.Rect().Size().Width().ToInt(), 33554422);
@@ -363,7 +375,7 @@ TEST_F(PaintLayerClipperTest, ContainPaintClip) {
ClipRectsContext context_clip(
layer, &layer->GetLayoutObject().FirstFragment(), kUncachedClipRects);
- layer->Clipper(PaintLayer::kUseGeometryMapper)
+ layer->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context_clip, &layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
EXPECT_EQ(LayoutRect(0, 0, 200, 200), background_rect.Rect());
@@ -389,7 +401,7 @@ TEST_F(PaintLayerClipperTest, NestedContainPaintClip) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- layer->Clipper(PaintLayer::kUseGeometryMapper)
+ layer->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
EXPECT_EQ(LayoutRect(0, 0, 200, 400), background_rect.Rect());
@@ -400,7 +412,7 @@ TEST_F(PaintLayerClipperTest, NestedContainPaintClip) {
layer->Parent(), &layer->Parent()->GetLayoutObject().FirstFragment(),
kUncachedClipRects);
- layer->Clipper(PaintLayer::kUseGeometryMapper)
+ layer->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context_clip, &layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
EXPECT_EQ(LayoutRect(0, 0, 200, 200), background_rect.Rect());
@@ -426,18 +438,19 @@ TEST_F(PaintLayerClipperTest, LocalClipRectFixedUnderTransform) {
PaintLayer* fixed =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("fixed"))->Layer();
- EXPECT_EQ(LayoutRect(0, 0, 100, 100),
- transformed->Clipper(PaintLayer::kUseGeometryMapper)
- .LocalClipRect(*transformed));
+ EXPECT_EQ(
+ LayoutRect(0, 0, 100, 100),
+ transformed->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
+ .LocalClipRect(*transformed));
EXPECT_EQ(LayoutRect(0, 50, 100, 100),
- fixed->Clipper(PaintLayer::kUseGeometryMapper)
+ fixed->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.LocalClipRect(*transformed));
}
TEST_F(PaintLayerClipperTest, ClearClipRectsRecursive) {
- // SPv2 will re-use a global GeometryMapper, so this
+ // CAP will re-use a global GeometryMapper, so this
// logic does not apply.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -462,7 +475,7 @@ TEST_F(PaintLayerClipperTest, ClearClipRectsRecursive) {
EXPECT_TRUE(parent->GetClipRectsCache());
EXPECT_TRUE(child->GetClipRectsCache());
- parent->Clipper(PaintLayer::kUseGeometryMapper)
+ parent->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.ClearClipRectsIncludingDescendants();
EXPECT_FALSE(parent->GetClipRectsCache());
@@ -470,9 +483,9 @@ TEST_F(PaintLayerClipperTest, ClearClipRectsRecursive) {
}
TEST_F(PaintLayerClipperTest, ClearClipRectsRecursiveChild) {
- // SPv2 will re-use a global GeometryMapper, so this
+ // CAP will re-use a global GeometryMapper, so this
// logic does not apply.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -497,7 +510,7 @@ TEST_F(PaintLayerClipperTest, ClearClipRectsRecursiveChild) {
EXPECT_TRUE(parent->GetClipRectsCache());
EXPECT_TRUE(child->GetClipRectsCache());
- child->Clipper(PaintLayer::kUseGeometryMapper)
+ child->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.ClearClipRectsIncludingDescendants();
EXPECT_TRUE(parent->GetClipRectsCache());
@@ -524,7 +537,7 @@ TEST_F(PaintLayerClipperTest, CSSClip) {
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
ClipRect foreground_rect(infinite_rect);
- target->Clipper(PaintLayer::kUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &target->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -554,7 +567,7 @@ TEST_F(PaintLayerClipperTest, Filter) {
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
ClipRect foreground_rect(infinite_rect);
- target->Clipper(PaintLayer::kUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &target->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -569,7 +582,7 @@ TEST_F(PaintLayerClipperTest, Filter) {
// Test without GeometryMapper.
background_rect = infinite_rect;
foreground_rect = infinite_rect;
- target->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateRects(context, nullptr, nullptr, layer_bounds, background_rect,
foreground_rect);
// The non-GeometryMapper path applies the immediate filter effect in
@@ -583,7 +596,7 @@ TEST_F(PaintLayerClipperTest, Filter) {
kUncachedClipRects);
background_rect = infinite_rect;
foreground_rect = infinite_rect;
- target->Clipper(PaintLayer::kUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(root_context, &target->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
// This includes the filter effect because it's applied before mapping the
@@ -594,7 +607,7 @@ TEST_F(PaintLayerClipperTest, Filter) {
// Test mapping to the root layer without GeometryMapper.
background_rect = infinite_rect;
foreground_rect = infinite_rect;
- target->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateRects(root_context, nullptr, nullptr, layer_bounds,
background_rect, foreground_rect);
EXPECT_EQ(LayoutRect(38, 41, 204, 304), background_rect.Rect());
@@ -636,7 +649,7 @@ TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithCSSClip) {
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
ClipRect foreground_rect(infinite_rect);
- target->Clipper(PaintLayer::kUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &target->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -672,7 +685,7 @@ TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithOverflowClip) {
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
ClipRect foreground_rect(infinite_rect);
- target->Clipper(PaintLayer::kUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &target->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -709,7 +722,7 @@ TEST_F(PaintLayerClipperTest, IgnoreRootLayerClipWithBothClip) {
LayoutRect layer_bounds(infinite_rect);
ClipRect background_rect(infinite_rect);
ClipRect foreground_rect(infinite_rect);
- target->Clipper(PaintLayer::kUseGeometryMapper)
+ target->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context, &target->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -747,7 +760,8 @@ TEST_F(PaintLayerClipperTest, Fragmentation) {
.NextFragment()
->NextFragment());
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&target_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -758,7 +772,8 @@ TEST_F(PaintLayerClipperTest, Fragmentation) {
foreground_rect.Rect());
EXPECT_EQ(LayoutRect(FloatRect(0, 0, 100, 200)), layer_bounds);
- target_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ target_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(
context,
target_paint_layer->GetLayoutObject().FirstFragment().NextFragment(),
@@ -798,7 +813,8 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorChild) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- child_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ child_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&child_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -808,7 +824,8 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorChild) {
EXPECT_EQ(LayoutRect(0, 0, 193, 293), foreground_rect.Rect());
EXPECT_EQ(LayoutRect(0, 0, 500, 500), layer_bounds);
- child_paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ child_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateRects(context, nullptr, nullptr, layer_bounds, background_rect,
foreground_rect);
@@ -842,7 +859,8 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorChildScrollBetween) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- child_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ child_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&child_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -852,7 +870,8 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorChildScrollBetween) {
EXPECT_EQ(LayoutRect(8, 8, 193, 293), foreground_rect.Rect());
EXPECT_EQ(LayoutRect(8, 8, 500, 500), layer_bounds);
- child_paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ child_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateRects(context, nullptr, nullptr, layer_bounds, background_rect,
foreground_rect);
@@ -884,7 +903,8 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorParent) {
LayoutRect layer_bounds;
ClipRect background_rect, foreground_rect;
- parent_paint_layer->Clipper(PaintLayer::kUseGeometryMapper)
+ parent_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kUseGeometryMapper)
.CalculateRects(context,
&parent_paint_layer->GetLayoutObject().FirstFragment(),
nullptr, layer_bounds, background_rect, foreground_rect);
@@ -895,7 +915,8 @@ TEST_F(PaintLayerClipperTest, ScrollbarClipBehaviorParent) {
EXPECT_EQ(LayoutRect(0, 0, 193, 293), foreground_rect.Rect());
EXPECT_EQ(LayoutRect(0, 0, 200, 300), layer_bounds);
- parent_paint_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ parent_paint_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateRects(context, nullptr, nullptr, layer_bounds, background_rect,
foreground_rect);
@@ -922,12 +943,13 @@ TEST_F(PaintLayerClipperTest, FixedLayerClipRectInDocumentSpace) {
GetDocument()
.GetLayoutView()
->Layer()
- ->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.ClearClipRectsIncludingDescendants();
{
ClipRect clip_rect;
- target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
&GetDocument().GetLayoutView()->FirstFragment(),
@@ -942,7 +964,8 @@ TEST_F(PaintLayerClipperTest, FixedLayerClipRectInDocumentSpace) {
{
ClipRect clip_rect;
- target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
&GetDocument().GetLayoutView()->FirstFragment(),
@@ -974,12 +997,13 @@ TEST_F(PaintLayerClipperTest,
GetDocument()
.GetLayoutView()
->Layer()
- ->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.ClearClipRectsIncludingDescendants();
{
ClipRect clip_rect;
- target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
&GetDocument().GetLayoutView()->FirstFragment(),
@@ -994,7 +1018,8 @@ TEST_F(PaintLayerClipperTest,
{
ClipRect clip_rect;
- target_layer->Clipper(PaintLayer::kDoNotUseGeometryMapper)
+ target_layer
+ ->Clipper(PaintLayer::GeometryMapperOption::kDoNotUseGeometryMapper)
.CalculateBackgroundClipRect(
ClipRectsContext(GetDocument().GetLayoutView()->Layer(),
&GetDocument().GetLayoutView()->FirstFragment(),
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 aaca470e4d1..0171009e127 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
@@ -58,9 +58,9 @@ static ShouldRespectOverflowClipType ShouldRespectOverflowClip(
: kRespectOverflowClip;
}
-bool PaintLayerPainter::PaintedOutputInvisible(
- const ComputedStyle& style,
- GlobalPaintFlags global_paint_flags) const {
+bool PaintLayerPainter::PaintedOutputInvisible(const ComputedStyle& style) {
+ DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
+
if (style.HasBackdropFilter())
return false;
@@ -70,29 +70,14 @@ bool PaintLayerPainter::PaintedOutputInvisible(
if (style.HasWillChangeOpacityHint())
return false;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- if (style.Opacity())
- return false;
-
- const auto* effect = paint_layer_.GetLayoutObject()
- .FirstFragment()
- .PaintProperties()
- ->Effect();
- if (effect && effect->RequiresCompositingForAnimation()) {
- return false;
- }
- }
-
// 0.0004f < 1/2048. With 10-bit color channels (only available on the
// newest Macs; otherwise it's 8-bit), we see that an alpha of 1/2048 or
// less leads to a color output of less than 0.5 in all channels, hence
// not visible.
static const float kMinimumVisibleOpacity = 0.0004f;
- if (paint_layer_.PaintsWithTransparency(global_paint_flags)) {
- if (style.Opacity() < kMinimumVisibleOpacity) {
- return true;
- }
- }
+ if (style.Opacity() < kMinimumVisibleOpacity)
+ return true;
+
return false;
}
@@ -132,14 +117,17 @@ PaintResult PaintLayerPainter::Paint(
if (ShouldSuppressPaintingLayer(paint_layer_))
return kFullyPainted;
- // If this layer is totally invisible then there is nothing to paint. In SPv2
+ // If this layer is totally invisible then there is nothing to paint. In CAP
// we simplify this optimization by painting even when effectively invisible
// but skipping the painted content during layerization in
// PaintArtifactCompositor.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
- PaintedOutputInvisible(paint_layer_.GetLayoutObject().StyleRef(),
- painting_info.GetGlobalPaintFlags())) {
- return kFullyPainted;
+ if (paint_layer_.PaintsWithTransparency(
+ painting_info.GetGlobalPaintFlags())) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ PaintedOutputInvisible(paint_layer_.GetLayoutObject().StyleRef()))
+ return kFullyPainted;
+
+ paint_flags |= kPaintLayerHaveTransparency;
}
// If the transform can't be inverted, then don't paint anything.
@@ -149,9 +137,6 @@ PaintResult PaintLayerPainter::Paint(
return kFullyPainted;
}
- if (paint_layer_.PaintsWithTransparency(painting_info.GetGlobalPaintFlags()))
- paint_flags |= kPaintLayerHaveTransparency;
-
paint_flags |= kPaintLayerPaintingCompositingAllPhases;
return PaintLayerContents(context, painting_info, paint_flags);
}
@@ -295,7 +280,7 @@ void PaintLayerPainter::AdjustForPaintProperties(
painting_info.root_layer->GetLayoutObject().FirstFragment();
const auto* source_transform =
first_root_fragment.LocalBorderBoxProperties().Transform();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
IsMainFrameNotClippingContents(*painting_info.root_layer)) {
// Use PostScrollTranslation as the source transform to avoid clipping of
// the scrolling contents in CullRect::ApplyTransforms().
@@ -306,7 +291,7 @@ void PaintLayerPainter::AdjustForPaintProperties(
if (source_transform == destination_transform)
return;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
auto& cull_rect = painting_info.cull_rect;
// CullRect::ApplyTransforms() requires the cull rect in the source
// transform space. Convert cull_rect from the root layer's local space.
@@ -612,7 +597,7 @@ PaintResult PaintLayerPainter::PaintLayerContents(
if (should_paint_mask) {
PaintMaskForFragments(layer_fragments, context, local_painting_info,
paint_flags);
- } else if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ } else if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
is_painting_mask &&
!(painting_info.GetGlobalPaintFlags() &
kGlobalPaintFlattenCompositingLayers) &&
@@ -708,6 +693,7 @@ PaintResult PaintLayerPainter::PaintChildren(
return result;
if (!paint_layer_.StackingNode())
return result;
+
#if DCHECK_IS_ON()
LayerListMutationDetector mutation_checker(paint_layer_.StackingNode());
#endif
@@ -717,7 +703,6 @@ PaintResult PaintLayerPainter::PaintChildren(
PaintLayer* child = iterator.Next();
if (!child)
return result;
-
for (; child; child = iterator.Next()) {
// If this Layer should paint into its own backing or a grouped backing,
// that will be done via CompositedLayerMapping::PaintContents() and
@@ -818,7 +803,6 @@ void PaintLayerPainter::PaintFragmentWithPhase(
? fragment.fragment_data->LogicalTopInFlowThread()
: LayoutUnit(),
suppress_painting_descendants);
-
paint_layer_.GetLayoutObject().Paint(paint_info);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h
index 4c39e007f2b..11a28177159 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter.h
@@ -55,8 +55,7 @@ class CORE_EXPORT PaintLayerPainter {
// Returns true if the painted output of this PaintLayer and its children is
// invisible and therefore can't impact painted output.
- bool PaintedOutputInvisible(const ComputedStyle&,
- GlobalPaintFlags = kGlobalPaintNormalPhase) const;
+ static bool PaintedOutputInvisible(const ComputedStyle&);
private:
friend class PaintLayerPainterTest;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
index ccafe4bd544..d4683513060 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_painter_test.cc
@@ -20,24 +20,22 @@ class PaintLayerPainterTest : public PaintControllerPaintTest {
USING_FAST_MALLOC(PaintLayerPainterTest);
public:
- void ExpectPaintedOutputInvisible(const char* element_name,
- bool expected_value) {
+ void ExpectPaintedOutputInvisibleAndPaintsWithTransparency(
+ const char* element_name,
+ bool expected_invisible,
+ bool expected_paints_with_transparency) {
// The optimization to skip painting for effectively-invisible content is
- // limited to pre-SPv2.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ // limited to pre-CAP.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
PaintLayer* target_layer =
ToLayoutBox(GetLayoutObjectByElementId(element_name))->Layer();
- PaintLayerPaintingInfo painting_info(nullptr, CullRect(),
- kGlobalPaintNormalPhase, LayoutSize());
- bool invisible =
- PaintLayerPainter(*target_layer)
- .PaintedOutputInvisible(target_layer->GetLayoutObject().StyleRef(),
- painting_info.GetGlobalPaintFlags());
- EXPECT_EQ(expected_value, invisible)
- << "Failed painted output visibility, expected=" << expected_value
- << ", actual=" << invisible << "].";
+ bool invisible = PaintLayerPainter::PaintedOutputInvisible(
+ target_layer->GetLayoutObject().StyleRef());
+ EXPECT_EQ(expected_invisible, invisible);
+ EXPECT_EQ(expected_paints_with_transparency,
+ target_layer->PaintsWithTransparency(kGlobalPaintNormalPhase));
}
PaintController& MainGraphicsLayerPaintController() {
@@ -208,8 +206,7 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceOnCullRectChange) {
DisplayItemClient& content3 = *GetDisplayItemClientFromElementId("content3");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- IntRect cull_rect(0, 0, 400, 300);
- Paint(&cull_rect);
+ Paint(IntRect(0, 0, 400, 300));
const auto& background_display_item_client = ViewScrollingBackgroundClient();
@@ -228,8 +225,7 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceOnCullRectChange) {
IsSameId(&content3, kBackgroundType)));
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- IntRect new_cull_rect(0, 100, 300, 1000);
- EXPECT_TRUE(PaintWithoutCommit(&new_cull_rect));
+ EXPECT_TRUE(PaintWithoutCommit(IntRect(0, 100, 300, 1000)));
// Container1 becomes partly in the interest rect, but uses cached subsequence
// because it was fully painted before;
@@ -265,14 +261,12 @@ TEST_P(PaintLayerPainterTest,
// |target| will be fully painted.
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- IntRect cull_rect(0, 0, 400, 300);
- Paint(&cull_rect);
+ Paint(IntRect(0, 0, 400, 300));
// |target| will be partially painted. Should not trigger under-invalidation
// checking DCHECKs.
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- IntRect new_cull_rect(0, 100, 300, 1000);
- Paint(&new_cull_rect);
+ Paint(IntRect(0, 100, 300, 1000));
}
TEST_P(PaintLayerPainterTest,
@@ -291,8 +285,7 @@ TEST_P(PaintLayerPainterTest,
)HTML");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// PaintResult of all subsequences will be MayBeClippedByCullRect.
- IntRect cull_rect(0, 0, 50, 300);
- Paint(&cull_rect);
+ Paint(IntRect(0, 0, 50, 300));
DisplayItemClient& container1 =
*GetDisplayItemClientFromElementId("container1");
@@ -315,7 +308,7 @@ TEST_P(PaintLayerPainterTest,
"position: absolute; width: 100px; height: 100px; "
"background-color: green");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- EXPECT_TRUE(PaintWithoutCommit(&cull_rect));
+ EXPECT_TRUE(PaintWithoutCommit(IntRect(0, 0, 50, 300)));
EXPECT_EQ(4, NumCachedNewItems());
CommitAndFinishCycle();
@@ -350,8 +343,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
const auto& view_client = ViewScrollingBackgroundClient();
// |target| is partially painted.
EXPECT_EQ(kMayBeClippedByCullRect, target_layer->PreviousPaintResult());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // SPv2 doesn't clip the cull rect by the scrolling contents rect, which
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // CAP doesn't clip the cull rect by the scrolling contents rect, which
// doesn't affect painted results.
EXPECT_EQ(CullRect(IntRect(-4000, -4000, 8800, 8600)),
target_layer->PreviousCullRect());
@@ -386,8 +379,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
// |target| is still partially painted.
EXPECT_EQ(kMayBeClippedByCullRect, target_layer->PreviousPaintResult());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // SPv2 doens't clip the cull rect by the scrolling contents rect, which
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // CAP doens't clip the cull rect by the scrolling contents rect, which
// doesn't affect painted results.
EXPECT_EQ(CullRect(IntRect(-4000, -4000, 8800, 8600)),
target_layer->PreviousCullRect());
@@ -422,8 +415,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
// |target| is still partially painted.
EXPECT_EQ(kMayBeClippedByCullRect, target_layer->PreviousPaintResult());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // SPv2 doens't clip the cull rect by the scrolling contents rect, which
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // CAP doens't clip the cull rect by the scrolling contents rect, which
// doesn't affect painted results.
EXPECT_EQ(CullRect(IntRect(-4000, -1000, 8800, 8600)),
target_layer->PreviousCullRect());
@@ -590,7 +583,11 @@ TEST_P(PaintLayerPainterTest, PaintPhaseFloatUnderInlineLayer) {
GetDocument().getElementById("span")->GetLayoutObject());
PaintLayer& span_layer = *span.Layer();
ASSERT_TRUE(&span_layer == float_div.EnclosingLayer());
- ASSERT_FALSE(span_layer.NeedsPaintPhaseFloat());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ ASSERT_TRUE(span_layer.NeedsPaintPhaseFloat());
+ } else {
+ ASSERT_FALSE(span_layer.NeedsPaintPhaseFloat());
+ }
LayoutBoxModelObject& self_painting_layer_object = *ToLayoutBoxModelObject(
GetDocument().getElementById("self-painting-layer")->GetLayoutObject());
PaintLayer& self_painting_layer = *self_painting_layer_object.Layer();
@@ -602,9 +599,14 @@ TEST_P(PaintLayerPainterTest, PaintPhaseFloatUnderInlineLayer) {
->Layer();
ASSERT_FALSE(non_self_painting_layer.IsSelfPaintingLayer());
- EXPECT_TRUE(self_painting_layer.NeedsPaintPhaseFloat());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_FALSE(self_painting_layer.NeedsPaintPhaseFloat());
+ EXPECT_TRUE(span_layer.NeedsPaintPhaseFloat());
+ } else {
+ EXPECT_TRUE(self_painting_layer.NeedsPaintPhaseFloat());
+ EXPECT_FALSE(span_layer.NeedsPaintPhaseFloat());
+ }
EXPECT_FALSE(non_self_painting_layer.NeedsPaintPhaseFloat());
- EXPECT_FALSE(span_layer.NeedsPaintPhaseFloat());
EXPECT_TRUE(DisplayItemListContains(
RootPaintController().GetDisplayItemList(), float_div,
DisplayItem::kBoxDecorationBackground));
@@ -834,21 +836,21 @@ TEST_P(PaintLayerPainterTest,
TEST_P(PaintLayerPainterTest, DontPaintWithTinyOpacity) {
SetBodyInnerHTML(
"<div id='target' style='background: blue; opacity: 0.0001'></div>");
- ExpectPaintedOutputInvisible("target", true);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", true, true);
}
TEST_P(PaintLayerPainterTest, DoPaintWithTinyOpacityAndWillChangeOpacity) {
SetBodyInnerHTML(
"<div id='target' style='background: blue; opacity: 0.0001; "
" will-change: opacity'></div>");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
TEST_P(PaintLayerPainterTest, DoPaintWithTinyOpacityAndBackdropFilter) {
SetBodyInnerHTML(
"<div id='target' style='background: blue; opacity: 0.0001;"
" backdrop-filter: blur(2px);'></div>");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
TEST_P(PaintLayerPainterTest,
@@ -856,20 +858,20 @@ TEST_P(PaintLayerPainterTest,
SetBodyInnerHTML(
"<div id='target' style='background: blue; opacity: 0.0001;"
" backdrop-filter: blur(2px); will-change: opacity'></div>");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
TEST_P(PaintLayerPainterTest, DoPaintWithCompositedTinyOpacity) {
SetBodyInnerHTML(
"<div id='target' style='background: blue; opacity: 0.0001;"
" will-change: transform'></div>");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", true, false);
}
TEST_P(PaintLayerPainterTest, DoPaintWithNonTinyOpacity) {
SetBodyInnerHTML(
"<div id='target' style='background: blue; opacity: 0.1'></div>");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, true);
}
TEST_P(PaintLayerPainterTest, DoPaintWithEffectAnimationZeroOpacity) {
@@ -888,7 +890,7 @@ TEST_P(PaintLayerPainterTest, DoPaintWithEffectAnimationZeroOpacity) {
</style>
<div id='target'></div>
)HTML");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", true, false);
}
TEST_P(PaintLayerPainterTest, DoPaintWithTransformAnimationZeroOpacity) {
@@ -906,7 +908,7 @@ TEST_P(PaintLayerPainterTest, DoPaintWithTransformAnimationZeroOpacity) {
</style>
<div id='target'>x</div></div>
)HTML");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", true, false);
}
TEST_P(PaintLayerPainterTest,
@@ -926,7 +928,7 @@ TEST_P(PaintLayerPainterTest,
</style>
<div id='target'>x</div></div>
)HTML");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
TEST_P(PaintLayerPainterTest, DoPaintWithWillChangeOpacity) {
@@ -940,7 +942,7 @@ TEST_P(PaintLayerPainterTest, DoPaintWithWillChangeOpacity) {
</style>
<div id='target'></div>
)HTML");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
TEST_P(PaintLayerPainterTest, DoPaintWithZeroOpacityAndWillChangeOpacity) {
@@ -955,7 +957,7 @@ TEST_P(PaintLayerPainterTest, DoPaintWithZeroOpacityAndWillChangeOpacity) {
</style>
<div id='target'></div>
)HTML");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
TEST_P(PaintLayerPainterTest,
@@ -971,14 +973,14 @@ TEST_P(PaintLayerPainterTest,
</style>
<div id='target'></div>
)HTML");
- ExpectPaintedOutputInvisible("target", false);
+ ExpectPaintedOutputInvisibleAndPaintsWithTransparency("target", false, false);
}
-using PaintLayerPainterTestSPv2 = PaintLayerPainterTest;
+using PaintLayerPainterTestCAP = PaintLayerPainterTest;
-INSTANTIATE_SPV2_TEST_CASE_P(PaintLayerPainterTestSPv2);
+INSTANTIATE_CAP_TEST_CASE_P(PaintLayerPainterTestCAP);
-TEST_P(PaintLayerPainterTestSPv2, SimpleCullRect) {
+TEST_P(PaintLayerPainterTestCAP, SimpleCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target'
style='width: 200px; height: 200px; position: relative'>
@@ -989,7 +991,7 @@ TEST_P(PaintLayerPainterTestSPv2, SimpleCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, TallLayerCullRect) {
+TEST_P(PaintLayerPainterTestCAP, TallLayerCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target'
style='width: 200px; height: 10000px; position: relative'>
@@ -1001,7 +1003,7 @@ TEST_P(PaintLayerPainterTestSPv2, TallLayerCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, WideLayerCullRect) {
+TEST_P(PaintLayerPainterTestCAP, WideLayerCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target'
style='width: 10000px; height: 200px; position: relative'>
@@ -1013,7 +1015,7 @@ TEST_P(PaintLayerPainterTestSPv2, WideLayerCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, TallScrolledLayerCullRect) {
+TEST_P(PaintLayerPainterTestCAP, TallScrolledLayerCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target' style='width: 200px; height: 10000px; position: relative'>
</div>
@@ -1044,7 +1046,7 @@ TEST_P(PaintLayerPainterTestSPv2, TallScrolledLayerCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, WholeDocumentCullRect) {
+TEST_P(PaintLayerPainterTestCAP, WholeDocumentCullRect) {
GetDocument().GetSettings()->SetMainFrameClipsContent(false);
SetBodyInnerHTML(R"HTML(
<style>
@@ -1100,7 +1102,7 @@ TEST_P(PaintLayerPainterTestSPv2, WholeDocumentCullRect) {
kBackgroundType)));
}
-TEST_P(PaintLayerPainterTestSPv2, VerticalRightLeftWritingModeDocument) {
+TEST_P(PaintLayerPainterTestCAP, VerticalRightLeftWritingModeDocument) {
SetBodyInnerHTML(R"HTML(
<style>
html { writing-mode: vertical-rl; }
@@ -1121,7 +1123,7 @@ TEST_P(PaintLayerPainterTestSPv2, VerticalRightLeftWritingModeDocument) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, ScaledCullRect) {
+TEST_P(PaintLayerPainterTestCAP, ScaledCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
transform: scaleX(2) scaleY(0.5)'>
@@ -1134,7 +1136,7 @@ TEST_P(PaintLayerPainterTestSPv2, ScaledCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, ScaledAndRotatedCullRect) {
+TEST_P(PaintLayerPainterTestCAP, ScaledAndRotatedCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
transform: scaleX(2) scaleY(0.5) rotateZ(45deg)'>
@@ -1147,7 +1149,7 @@ TEST_P(PaintLayerPainterTestSPv2, ScaledAndRotatedCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, 3DRotated90DegreesCullRect) {
+TEST_P(PaintLayerPainterTestCAP, 3DRotated90DegreesCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
transform: rotateY(90deg)'>
@@ -1161,7 +1163,7 @@ TEST_P(PaintLayerPainterTestSPv2, 3DRotated90DegreesCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, 3DRotatedNear90DegreesCullRect) {
+TEST_P(PaintLayerPainterTestCAP, 3DRotatedNear90DegreesCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
transform: rotateY(89.9999deg)'>
@@ -1177,7 +1179,7 @@ TEST_P(PaintLayerPainterTestSPv2, 3DRotatedNear90DegreesCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, PerspectiveCullRect) {
+TEST_P(PaintLayerPainterTestCAP, PerspectiveCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target'
style='width: 100px; height: 100px; transform: perspective(1000px)'>
@@ -1189,7 +1191,7 @@ TEST_P(PaintLayerPainterTestSPv2, PerspectiveCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().IsInfinite());
}
-TEST_P(PaintLayerPainterTestSPv2, 3D45DegRotatedTallCullRect) {
+TEST_P(PaintLayerPainterTestCAP, 3D45DegRotatedTallCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target'
style='width: 200px; height: 10000px; transform: rotateY(45deg)'>
@@ -1201,7 +1203,7 @@ TEST_P(PaintLayerPainterTestSPv2, 3D45DegRotatedTallCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().IsInfinite());
}
-TEST_P(PaintLayerPainterTestSPv2, FixedPositionCullRect) {
+TEST_P(PaintLayerPainterTestCAP, FixedPositionCullRect) {
SetBodyInnerHTML(R"HTML(
<div id='target' style='width: 1000px; height: 2000px;
position: fixed; top: 100px; left: 200px;'>
@@ -1212,7 +1214,7 @@ TEST_P(PaintLayerPainterTestSPv2, FixedPositionCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, LayerOffscreenNearCullRect) {
+TEST_P(PaintLayerPainterTestCAP, LayerOffscreenNearCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
position: absolute; top: 3000px; left: 0px;'>
@@ -1224,7 +1226,7 @@ TEST_P(PaintLayerPainterTestSPv2, LayerOffscreenNearCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, LayerOffscreenFarCullRect) {
+TEST_P(PaintLayerPainterTestCAP, LayerOffscreenFarCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
position: absolute; top: 9000px'>
@@ -1237,7 +1239,7 @@ TEST_P(PaintLayerPainterTestSPv2, LayerOffscreenFarCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, ScrollingLayerCullRect) {
+TEST_P(PaintLayerPainterTestCAP, ScrollingLayerCullRect) {
SetBodyInnerHTML(R"HTML(
<style>
div::-webkit-scrollbar { width: 5px; }
@@ -1258,7 +1260,7 @@ TEST_P(PaintLayerPainterTestSPv2, ScrollingLayerCullRect) {
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
-TEST_P(PaintLayerPainterTestSPv2, ClippedBigLayer) {
+TEST_P(PaintLayerPainterTestCAP, ClippedBigLayer) {
SetBodyInnerHTML(R"HTML(
<div style='width: 1px; height: 1px; overflow: hidden'>
<div id='target'
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.cc
index 2587cb77fa2..a6149011498 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.cc
@@ -50,9 +50,6 @@ void PaintLayerResourceInfo::ResourceContentChanged(InvalidationModeMask) {
// to update these properties when filter resources change.
layout_object.SetNeedsPaintPropertyUpdate();
layer_->SetFilterOnEffectNodeDirty();
- const ComputedStyle& style = layout_object.StyleRef();
- if (style.HasFilter() && style.Filter().HasReferenceFilter())
- InvalidateFilterChain();
}
void PaintLayerResourceInfo::ResourceElementChanged() {
@@ -64,26 +61,6 @@ void PaintLayerResourceInfo::ResourceElementChanged() {
// to update these properties when filter resources change.
layout_object.SetNeedsPaintPropertyUpdate();
layer_->SetFilterOnEffectNodeDirty();
- const ComputedStyle& style = layout_object.StyleRef();
- if (style.HasFilter() && style.Filter().HasReferenceFilter())
- InvalidateFilterChain();
-}
-
-void PaintLayerResourceInfo::SetLastEffect(FilterEffect* last_effect) {
- last_effect_ = last_effect;
-}
-
-FilterEffect* PaintLayerResourceInfo::LastEffect() const {
- return last_effect_;
-}
-
-void PaintLayerResourceInfo::InvalidateFilterChain() {
- last_effect_ = nullptr;
-}
-
-void PaintLayerResourceInfo::Trace(blink::Visitor* visitor) {
- visitor->Trace(last_effect_);
- SVGResourceClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.h b/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.h
index 2b7a0998399..9de93eca472 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_resource_info.h
@@ -32,6 +32,7 @@
#include "base/macros.h"
#include "third_party/blink/renderer/core/svg/svg_resource_client.h"
+#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
@@ -57,21 +58,20 @@ class PaintLayerResourceInfo final
explicit PaintLayerResourceInfo(PaintLayer*);
~PaintLayerResourceInfo() override;
- void SetLastEffect(FilterEffect*);
- FilterEffect* LastEffect() const;
- void InvalidateFilterChain();
+ FloatRect FilterReferenceBox() const { return filter_reference_box_; }
+ void SetFilterReferenceBox(const FloatRect& rect) {
+ filter_reference_box_ = rect;
+ }
void ClearLayer() { layer_ = nullptr; }
void ResourceContentChanged(InvalidationModeMask) override;
void ResourceElementChanged() override;
- void Trace(blink::Visitor*) override;
-
private:
- // |clearLayer| must be called before *m_layer becomes invalid.
+ // |ClearLayer| must be called before *layer_ becomes invalid.
PaintLayer* layer_;
- Member<FilterEffect> last_effect_;
+ FloatRect filter_reference_box_;
DISALLOW_COPY_AND_ASSIGN(PaintLayerResourceInfo);
};
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 5d9cb4586e2..d9d5c3c4c6e 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -80,6 +80,7 @@
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h"
+#include "third_party/blink/renderer/core/page/scrolling/fragment_anchor.h"
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
#include "third_party/blink/renderer/core/page/scrolling/root_scroller_util.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
@@ -487,10 +488,12 @@ void PaintLayerScrollableArea::UpdateScrollOffset(
}
}
+ if (FragmentAnchor* anchor = frame_view->GetFragmentAnchor())
+ anchor->DidScroll(scroll_type);
+
if (IsExplicitScrollType(scroll_type)) {
if (scroll_type != kCompositorScroll)
ShowOverlayScrollbars();
- frame_view->ClearFragmentAnchor();
GetScrollAnchor()->Clear();
}
@@ -520,7 +523,7 @@ void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange() {
// If not composited, background always paints into the main graphics layer.
bool background_paint_in_graphics_layer = true;
bool background_paint_in_scrolling_contents = false;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
UsesCompositedScrolling()) {
auto background_paint_location = box->GetBackgroundPaintLocation();
background_paint_in_graphics_layer =
@@ -545,7 +548,7 @@ void PaintLayerScrollableArea::InvalidatePaintForScrollOffsetChange() {
// scrollers, this will be taken care of by the interest rect computation
// in CompositedLayerMapping.
// TODO(wangxianzhu): replace this shortcut with interest rects.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
!UsesCompositedScrolling())
Layer()->SetNeedsRepaint();
}
@@ -832,7 +835,7 @@ void PaintLayerScrollableArea::UpdateScrollOrigin() {
LayoutRect scrollable_overflow(overflow_rect_);
scrollable_overflow.Move(-GetLayoutBox()->BorderLeft(),
-GetLayoutBox()->BorderTop());
- IntPoint new_origin(-scrollable_overflow.PixelSnappedLocation() +
+ IntPoint new_origin(FlooredIntPoint(-scrollable_overflow.Location()) +
GetLayoutBox()->OriginAdjustmentForScrollbars());
if (new_origin != scroll_origin_)
scroll_origin_changed_ = true;
@@ -1626,9 +1629,9 @@ void PaintLayerScrollableArea::SnapAfterScrollbarScrolling(
if (!snap_coordinator)
return;
- snap_coordinator->SnapForEndPosition(*GetLayoutBox(),
- orientation == kHorizontalScrollbar,
- orientation == kVerticalScrollbar);
+ snap_coordinator->SnapAtCurrentPosition(*GetLayoutBox(),
+ orientation == kHorizontalScrollbar,
+ orientation == kVerticalScrollbar);
}
void PaintLayerScrollableArea::PositionOverflowControls() {
@@ -1827,7 +1830,7 @@ void PaintLayerScrollableArea::UpdateResizerAreaSet() {
void PaintLayerScrollableArea::UpdateResizerStyle(
const ComputedStyle* old_style) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() && old_style &&
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && old_style &&
old_style->Resize() != GetLayoutBox()->StyleRef().Resize()) {
// Invalidate the composited scroll corner layer on resize style change.
if (auto* graphics_layer = LayerForScrollCorner())
@@ -2156,12 +2159,21 @@ void PaintLayerScrollableArea::UpdateCompositingLayersAfterScroll() {
DCHECK(Layer()->HasCompositedLayerMapping());
ScrollingCoordinator* scrolling_coordinator = GetScrollingCoordinator();
bool handled_scroll =
- Layer()->IsRootLayer() && scrolling_coordinator &&
+ (Layer()->IsRootLayer() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) &&
+ scrolling_coordinator &&
scrolling_coordinator->UpdateCompositedScrollOffset(this);
if (!handled_scroll) {
- Layer()->GetCompositedLayerMapping()->SetNeedsGraphicsLayerUpdate(
- kGraphicsLayerUpdateSubtree);
+ if (!RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // In non-BGPT mode, we need to do a full sub-tree update here, because
+ // we need to update the position property to compute
+ // offset_to_transform_parent. For more context, see the comment from
+ // chrishtr@ here:
+ // https://chromium-review.googlesource.com/c/chromium/src/+/1403639/6/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+ Layer()->GetCompositedLayerMapping()->SetNeedsGraphicsLayerUpdate(
+ kGraphicsLayerUpdateSubtree);
+ }
compositor->SetNeedsCompositingUpdate(
kCompositingUpdateAfterGeometryChange);
}
@@ -2682,7 +2694,7 @@ static LayoutRect InvalidatePaintOfScrollbarIfNeeded(
// container to ensure newly expanded/shrunk areas of the box to be
// invalidated.
needs_paint_invalidation = false;
- DCHECK(!graphics_layer->DrawsContent() ||
+ DCHECK(!graphics_layer->PaintsContentOrHitTest() ||
graphics_layer->GetPaintController().GetPaintArtifact().IsEmpty());
}
@@ -2847,15 +2859,15 @@ LayoutRect
PaintLayerScrollableArea::ScrollingBackgroundDisplayItemClient::VisualRect()
const {
const auto* box = scrollable_area_->GetLayoutBox();
- auto overflow_clip_rect = box->OverflowClipRect(LayoutPoint());
- auto scroll_size = scrollable_area_->overflow_rect_.Size();
+ const auto& paint_offset = box->FirstFragment().PaintOffset();
+ auto overflow_clip_rect =
+ PixelSnappedIntRect(box->OverflowClipRect(paint_offset));
+ auto scroll_size = scrollable_area_->PixelSnappedContentsSize(paint_offset);
// Ensure scrolling contents are at least as large as the scroll clip
scroll_size = scroll_size.ExpandedTo(overflow_clip_rect.Size());
LayoutRect result(overflow_clip_rect.Location(), scroll_size);
- result.MoveBy(box->FirstFragment().PaintOffset());
- result = LayoutRect(PixelSnappedIntRect(result));
#if DCHECK_IS_ON()
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
DCHECK_EQ(result,
scrollable_area_->layer_->GraphicsLayerBacking()->VisualRect());
}
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
index 5a3f1d6c312..fc4a1d509d5 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -35,7 +35,8 @@ class PaintLayerScrollableAreaTestBase : public RenderingTest {
public:
PaintLayerScrollableAreaTestBase()
: RenderingTest(EmptyLocalFrameClient::Create()),
- chrome_client_(new ScrollableAreaMockChromeClient) {}
+ chrome_client_(MakeGarbageCollected<ScrollableAreaMockChromeClient>()) {
+ }
~PaintLayerScrollableAreaTestBase() override {
testing::Mock::VerifyAndClearExpectations(&GetChromeClient());
@@ -856,7 +857,7 @@ TEST_P(PaintLayerScrollableAreaTest,
// Programmatically changing the scroll offset.
scrollable_area->SetScrollOffset(ScrollOffset(0, 1), kProgrammaticScroll);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
// No invalidation because the background paints into scrolling contents.
EXPECT_FALSE(scroller->ShouldDoFullPaintInvalidation());
EXPECT_FALSE(scroller->BackgroundNeedsFullPaintInvalidation());
@@ -937,15 +938,8 @@ TEST_P(PaintLayerScrollableAreaTest, ViewScrollWithFixedAttachmentBackground) {
EXPECT_TRUE(fixed_background_div->ShouldDoFullPaintInvalidation());
EXPECT_TRUE(fixed_background_div->BackgroundNeedsFullPaintInvalidation());
EXPECT_FALSE(fixed_background_div->NeedsPaintPropertyUpdate());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // In SPv2, we assume the view's fixed attachment background is composited
- // at this time and doesn't need paint invalidation on view scroll.
- EXPECT_FALSE(GetLayoutView().ShouldDoFullPaintInvalidation());
- EXPECT_FALSE(GetLayoutView().BackgroundNeedsFullPaintInvalidation());
- } else {
- EXPECT_TRUE(GetLayoutView().ShouldDoFullPaintInvalidation());
- EXPECT_TRUE(GetLayoutView().BackgroundNeedsFullPaintInvalidation());
- }
+ EXPECT_TRUE(GetLayoutView().ShouldDoFullPaintInvalidation());
+ EXPECT_TRUE(GetLayoutView().BackgroundNeedsFullPaintInvalidation());
EXPECT_TRUE(GetLayoutView().NeedsPaintPropertyUpdate());
UpdateAllLifecyclePhasesForTest();
@@ -1018,7 +1012,7 @@ TEST_P(PaintLayerScrollableAreaTest, CompositedStickyDescendant) {
auto* scroller =
ToLayoutBoxModelObject(GetLayoutObjectByElementId("scroller"));
auto* scrollable_area = scroller->GetScrollableArea();
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_EQ(kPaintsIntoOwnBacking, scroller->Layer()->GetCompositingState());
auto* sticky = ToLayoutBoxModelObject(GetLayoutObjectByElementId("sticky"));
@@ -1087,4 +1081,75 @@ TEST_P(PaintLayerScrollableAreaTest, ScrollbarMaximum) {
EXPECT_EQ(scrollbar->CurrentPos(), scrollbar->Maximum());
}
+TEST_P(PaintLayerScrollableAreaTest, ScrollingBackgroundDisplayItemClient) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ ::-webkit-scrollbar { display: none; }
+ #scroller {
+ width: 100.7px;
+ height: 100.4px;
+ overflow: scroll;
+ border-top: 2.6px solid blue;
+ border-left: 2.4px solid blue;
+ will-change: transform;
+ }
+ #content {
+ width: 50.7px;
+ height: 200.4px;
+ }
+ </style>
+ <div id="scroller">
+ <div id="content"></div>
+ </div>
+ )HTML");
+
+ EXPECT_EQ(LayoutRect(2, 3, 101, 200),
+ ToLayoutBox(GetLayoutObjectByElementId("scroller"))
+ ->GetScrollableArea()
+ ->GetScrollingBackgroundDisplayItemClient()
+ .VisualRect());
+}
+
+TEST_P(PaintLayerScrollableAreaTest, RtlScrollOriginSnapping) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #container {
+ direction: rtl;
+ display: flex;
+ }
+ #scroller {
+ width: 100%;
+ height: 100px;
+ overflow: hidden;
+ }
+ #scroller-content {
+ width: 200%;
+ height: 200px;
+ }
+ </style>
+ <div id="container">
+ <div id="first-child" style="flex:1; display:none"></div>
+ <div style="flex:2.2">
+ <div id="scroller">
+ <div id ="scroller-content"></div>
+ </div>
+ </div>
+ </div>
+ )HTML");
+
+ // Test that scroll origin is snapped such that maximum scroll offset is
+ // always zero for an rtl block.
+
+ GetFrame().View()->Resize(795, 600);
+ UpdateAllLifecyclePhasesForTest();
+ LayoutBox* scroller = ToLayoutBox(GetLayoutObjectByElementId("scroller"));
+ PaintLayerScrollableArea* scrollable_area = scroller->GetScrollableArea();
+ EXPECT_EQ(scrollable_area->MaximumScrollOffsetInt(), IntSize(0, 100));
+
+ Element* first_child = GetElementById("first-child");
+ first_child->RemoveInlineStyleProperty(CSSPropertyDisplay);
+ UpdateAllLifecyclePhasesForTest();
+ EXPECT_EQ(scrollable_area->MaximumScrollOffsetInt(), IntSize(0, 100));
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc
index 115dc3c2ba2..cdb169b1c25 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_layer_test.cc
@@ -39,8 +39,8 @@ TEST_P(PaintLayerTest, ChildWithoutPaintLayer) {
}
TEST_P(PaintLayerTest, CompositedBoundsAbsPosGrandchild) {
- // BoundingBoxForCompositing is not used in SPv2 mode.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ // BoundingBoxForCompositing is not used in CAP mode.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(
" <div id='parent'><div id='absposparent'><div id='absposchild'>"
@@ -61,8 +61,8 @@ TEST_P(PaintLayerTest, CompositedBoundsAbsPosGrandchild) {
}
TEST_P(PaintLayerTest, CompositedBoundsTransformedChild) {
- // TODO(chrishtr): fix this test for SPv2
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ // TODO(chrishtr): fix this test for CAP
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -160,23 +160,6 @@ TEST_P(PaintLayerTest, ScrollsWithViewportFixedPositionInsideTransform) {
EXPECT_FALSE(layer->FixedToViewport());
}
-TEST_P(PaintLayerTest,
- ScrollsWithViewportFixedPositionInsideTransformNoScroll) {
- SetBodyInnerHTML(R"HTML(
- <div style='transform: translateZ(0)'>
- <div id='target' style='position: fixed'></div>
- </div>
- )HTML");
- PaintLayer* layer = GetPaintLayerByElementId("target");
-
- // In SPv2 mode, we correctly determine that the frame doesn't scroll at all,
- // and so return true.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
- EXPECT_TRUE(layer->FixedToViewport());
- else
- EXPECT_FALSE(layer->FixedToViewport());
-}
-
TEST_P(PaintLayerTest, SticksToScrollerStickyPosition) {
SetBodyInnerHTML(R"HTML(
<div style='transform: translateZ(0)'>
@@ -226,7 +209,7 @@ TEST_P(PaintLayerTest, SticksToScrollerStickyPositionInsideScroller) {
}
TEST_P(PaintLayerTest, CompositedScrollingNoNeedsRepaint) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -254,10 +237,10 @@ TEST_P(PaintLayerTest, CompositedScrollingNoNeedsRepaint) {
}
TEST_P(PaintLayerTest, NonCompositedScrollingNeedsRepaint) {
- // SPV2 scrolling raster invalidation decisions are made in
+ // CAP scrolling raster invalidation decisions are made in
// ContentLayerClientImpl::GenerateRasterInvalidations through
// PaintArtifactCompositor.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -779,7 +762,7 @@ TEST_P(PaintLayerTest, DescendantDependentFlagsStopsAtThrottledFrames) {
}
TEST_P(PaintLayerTest, PaintInvalidationOnNonCompositedScroll) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -854,8 +837,8 @@ TEST_P(PaintLayerTest, CompositingContainerStackedFloatUnderStackingInline) {
EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -879,8 +862,8 @@ TEST_P(PaintLayerTest,
EXPECT_EQ(span, target->CompositingContainer());
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(span,
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -899,12 +882,16 @@ TEST_P(PaintLayerTest, CompositingContainerNonStackedFloatUnderStackingInline) {
)HTML");
PaintLayer* target = GetPaintLayerByElementId("target");
- EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
- target->CompositingContainer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
+ target->CompositingContainer());
+ }
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -924,14 +911,23 @@ TEST_P(PaintLayerTest,
)HTML");
PaintLayer* target = GetPaintLayerByElementId("target");
- EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
- target->CompositingContainer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
+ target->CompositingContainer());
+ }
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
- target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"),
+ target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
+ target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
+ }
}
}
@@ -954,8 +950,8 @@ TEST_P(PaintLayerTest,
EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -981,8 +977,8 @@ TEST_P(PaintLayerTest,
EXPECT_EQ(span, target->CompositingContainer());
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(span,
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -1004,12 +1000,16 @@ TEST_P(PaintLayerTest,
)HTML");
PaintLayer* target = GetPaintLayerByElementId("target");
- EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
- target->CompositingContainer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
+ target->CompositingContainer());
+ }
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -1031,14 +1031,23 @@ TEST_P(PaintLayerTest,
)HTML");
PaintLayer* target = GetPaintLayerByElementId("target");
- EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
- target->CompositingContainer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
+ target->CompositingContainer());
+ }
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
- target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"),
+ target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("compositedContainer"),
+ target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
+ }
}
}
@@ -1064,20 +1073,35 @@ TEST_P(PaintLayerTest, FloatLayerAndAbsoluteUnderInlineLayer) {
PaintLayer* container = GetPaintLayerByElementId("container");
EXPECT_EQ(span, floating->Parent());
- EXPECT_EQ(container, floating->ContainingLayer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span, floating->ContainingLayer());
+ } else {
+ EXPECT_EQ(container, floating->ContainingLayer());
+ }
EXPECT_EQ(span, absolute->Parent());
EXPECT_EQ(span, absolute->ContainingLayer());
EXPECT_EQ(container, span->Parent());
EXPECT_EQ(container, span->ContainingLayer());
- EXPECT_EQ(LayoutPoint(83, 83), floating->Location());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(50, 50), floating->Location());
+ } else {
+ EXPECT_EQ(LayoutPoint(83, 83), floating->Location());
+ }
EXPECT_EQ(LayoutPoint(50, 50), absolute->Location());
EXPECT_EQ(LayoutPoint(133, 133), span->Location());
EXPECT_EQ(LayoutPoint(20, 20), container->Location());
- EXPECT_EQ(LayoutPoint(-50, -50), floating->VisualOffsetFromAncestor(span));
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(50, 50), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(183, 183),
+ floating->VisualOffsetFromAncestor(container));
+ } else {
+ EXPECT_EQ(LayoutPoint(-50, -50), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(83, 83),
+ floating->VisualOffsetFromAncestor(container));
+ }
EXPECT_EQ(LayoutPoint(50, 50), absolute->VisualOffsetFromAncestor(span));
- EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(container));
EXPECT_EQ(LayoutPoint(183, 183),
absolute->VisualOffsetFromAncestor(container));
}
@@ -1101,16 +1125,26 @@ TEST_P(PaintLayerTest, FloatLayerUnderInlineLayerScrolled) {
kProgrammaticScroll);
EXPECT_EQ(span, floating->Parent());
- EXPECT_EQ(container, floating->ContainingLayer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span, floating->ContainingLayer());
+ } else {
+ EXPECT_EQ(container, floating->ContainingLayer());
+ }
EXPECT_EQ(container, span->Parent());
EXPECT_EQ(container, span->ContainingLayer());
- EXPECT_EQ(LayoutPoint(50, -350), floating->Location());
EXPECT_EQ(LayoutPoint(100, -300), span->Location());
-
- EXPECT_EQ(LayoutPoint(-50, -50), floating->VisualOffsetFromAncestor(span));
- EXPECT_EQ(LayoutPoint(50, -350),
- floating->VisualOffsetFromAncestor(container));
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(50, 50), floating->Location());
+ EXPECT_EQ(LayoutPoint(50, 50), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(150, -250),
+ floating->VisualOffsetFromAncestor(container));
+ } else {
+ EXPECT_EQ(LayoutPoint(50, -350), floating->Location());
+ EXPECT_EQ(LayoutPoint(-50, -50), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(50, -350),
+ floating->VisualOffsetFromAncestor(container));
+ }
}
TEST_P(PaintLayerTest, FloatLayerUnderBlockUnderInlineLayer) {
@@ -1154,13 +1188,24 @@ TEST_P(PaintLayerTest, FloatLayerUnderFloatUnderInlineLayer) {
PaintLayer* span = GetPaintLayerByElementId("span");
EXPECT_EQ(span, floating->Parent());
- EXPECT_EQ(span->Parent(), floating->ContainingLayer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span, floating->ContainingLayer());
+ } else {
+ EXPECT_EQ(span->Parent(), floating->ContainingLayer());
+ }
EXPECT_EQ(LayoutPoint(83, 83), floating->Location());
EXPECT_EQ(LayoutPoint(100, 100), span->Location());
- EXPECT_EQ(LayoutPoint(-17, -17), floating->VisualOffsetFromAncestor(span));
- EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(
- GetDocument().GetLayoutView()->Layer()));
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(183, 183),
+ floating->VisualOffsetFromAncestor(
+ GetDocument().GetLayoutView()->Layer()));
+ } else {
+ EXPECT_EQ(LayoutPoint(-17, -17), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(
+ GetDocument().GetLayoutView()->Layer()));
+ }
}
TEST_P(PaintLayerTest, FloatLayerUnderFloatLayerUnderInlineLayer) {
@@ -1183,16 +1228,29 @@ TEST_P(PaintLayerTest, FloatLayerUnderFloatLayerUnderInlineLayer) {
EXPECT_EQ(floating_parent, floating->Parent());
EXPECT_EQ(floating_parent, floating->ContainingLayer());
EXPECT_EQ(span, floating_parent->Parent());
- EXPECT_EQ(span->Parent(), floating_parent->ContainingLayer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span, floating_parent->ContainingLayer());
+ } else {
+ EXPECT_EQ(span->Parent(), floating_parent->ContainingLayer());
+ }
EXPECT_EQ(LayoutPoint(50, 50), floating->Location());
EXPECT_EQ(LayoutPoint(33, 33), floating_parent->Location());
EXPECT_EQ(LayoutPoint(100, 100), span->Location());
- EXPECT_EQ(LayoutPoint(-17, -17), floating->VisualOffsetFromAncestor(span));
- EXPECT_EQ(LayoutPoint(-67, -67),
- floating_parent->VisualOffsetFromAncestor(span));
- EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(
- GetDocument().GetLayoutView()->Layer()));
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(33, 33),
+ floating_parent->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(183, 183),
+ floating->VisualOffsetFromAncestor(
+ GetDocument().GetLayoutView()->Layer()));
+ } else {
+ EXPECT_EQ(LayoutPoint(-17, -17), floating->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(-67, -67),
+ floating_parent->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(83, 83), floating->VisualOffsetFromAncestor(
+ GetDocument().GetLayoutView()->Layer()));
+ }
}
TEST_P(PaintLayerTest, LayerUnderFloatUnderInlineLayer) {
@@ -1212,13 +1270,25 @@ TEST_P(PaintLayerTest, LayerUnderFloatUnderInlineLayer) {
PaintLayer* span = GetPaintLayerByElementId("span");
EXPECT_EQ(span, child->Parent());
- EXPECT_EQ(span->Parent(), child->ContainingLayer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span, child->ContainingLayer());
+ } else {
+ EXPECT_EQ(span->Parent(), child->ContainingLayer());
+ }
EXPECT_EQ(LayoutPoint(83, 83), child->Location());
EXPECT_EQ(LayoutPoint(100, 100), span->Location());
- EXPECT_EQ(LayoutPoint(-17, -17), child->VisualOffsetFromAncestor(span));
- EXPECT_EQ(LayoutPoint(83, 83), child->VisualOffsetFromAncestor(
- GetDocument().GetLayoutView()->Layer()));
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(83, 83), child->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(183, 183),
+ child->VisualOffsetFromAncestor(
+ GetDocument().GetLayoutView()->Layer()));
+
+ } else {
+ EXPECT_EQ(LayoutPoint(-17, -17), child->VisualOffsetFromAncestor(span));
+ EXPECT_EQ(LayoutPoint(83, 83), child->VisualOffsetFromAncestor(
+ GetDocument().GetLayoutView()->Layer()));
+ }
}
TEST_P(PaintLayerTest, CompositingContainerFloatingIframe) {
@@ -1240,14 +1310,18 @@ TEST_P(PaintLayerTest, CompositingContainerFloatingIframe) {
// A non-positioned iframe still gets a PaintLayer because PaintLayers are
// forced for all LayoutEmbeddedContent objects. However, such PaintLayers are
// not stacked.
- PaintLayer* containing_block = GetPaintLayerByElementId("containingBlock");
- EXPECT_EQ(containing_block, target->CompositingContainer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(GetPaintLayerByElementId("span"), target->CompositingContainer());
+ } else {
+ EXPECT_EQ(GetPaintLayerByElementId("containingBlock"),
+ target->CompositingContainer());
+ }
PaintLayer* composited_container =
GetPaintLayerByElementId("compositedContainer");
// enclosingLayerWithCompositedLayerMapping is not needed or applicable to
- // SPv2.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // CAP.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(composited_container,
target->EnclosingLayerWithCompositedLayerMapping(kExcludeSelf));
}
@@ -1269,7 +1343,11 @@ TEST_P(PaintLayerTest, CompositingContainerSelfPaintingNonStackedFloat) {
PaintLayer* container = GetPaintLayerByElementId("container");
PaintLayer* span = GetPaintLayerByElementId("span");
- EXPECT_EQ(container, target->ContainingLayer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span, target->ContainingLayer());
+ } else {
+ EXPECT_EQ(container, target->ContainingLayer());
+ }
EXPECT_EQ(span, target->CompositingContainer());
}
@@ -1352,7 +1430,11 @@ TEST_P(PaintLayerTest, NeedsRepaintOnSelfPaintingStatusChange) {
"overflow: hidden; float: left");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
EXPECT_FALSE(target_layer->IsSelfPaintingLayer());
- EXPECT_EQ(span_layer->Parent(), target_layer->CompositingContainer());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(span_layer, target_layer->CompositingContainer());
+ } else {
+ EXPECT_EQ(span_layer->Parent(), target_layer->CompositingContainer());
+ }
EXPECT_TRUE(target_layer->NeedsRepaint());
EXPECT_TRUE(target_layer->CompositingContainer()->NeedsRepaint());
EXPECT_TRUE(span_layer->NeedsRepaint());
@@ -1452,7 +1534,7 @@ TEST_P(PaintLayerTest, FragmentedHitTest) {
}
TEST_P(PaintLayerTest, SquashingOffsets) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetHtmlInnerHTML(R"HTML(
<style>
@@ -1759,7 +1841,8 @@ TEST_P(PaintLayerTest, BackgroundIsKnownToBeOpaqueInRectChildren) {
LayoutRect(0, 0, 100, 100), false));
}
-TEST_P(PaintLayerTest, ChangeAlphaNeedsCompositingInputs) {
+TEST_P(PaintLayerTest,
+ ChangeAlphaNeedsCompositingInputsAndPaintPropertyUpdate) {
SetBodyInnerHTML(R"HTML(
<style>
#target {
@@ -1773,10 +1856,20 @@ TEST_P(PaintLayerTest, ChangeAlphaNeedsCompositingInputs) {
</div>
)HTML");
PaintLayer* target = GetPaintLayerByElementId("target");
+ EXPECT_FALSE(target->NeedsCompositingInputsUpdate());
+ EXPECT_FALSE(target->GetLayoutObject().NeedsPaintPropertyUpdate());
+ EXPECT_FALSE(target->Parent()->GetLayoutObject().NeedsPaintPropertyUpdate());
+
StyleDifference diff;
diff.SetHasAlphaChanged();
target->StyleDidChange(diff, target->GetLayoutObject().Style());
- EXPECT_TRUE(target->NeedsCompositingInputsUpdate());
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
+ EXPECT_FALSE(target->NeedsCompositingInputsUpdate());
+ else
+ EXPECT_TRUE(target->NeedsCompositingInputsUpdate());
+ EXPECT_TRUE(target->GetLayoutObject().NeedsPaintPropertyUpdate());
+ // See the TODO in PaintLayer::SetNeedsCompositingInputsUpdate().
+ EXPECT_TRUE(target->Parent()->GetLayoutObject().NeedsPaintPropertyUpdate());
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index 1c65f407cff..11a7196cd65 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -212,10 +212,28 @@ class FragmentPaintPropertyTreeBuilder {
full_context_.clip_changed |=
!(result.Unchanged() || only_updated_hit_test_values);
}
+ // Like |OnUpdate| but forces a piercing subtree update if the scroll tree
+ // hierarchy changes because the scroll tree does not have isolation nodes
+ // and non-piercing updates can fail to update scroll descendants.
+ void OnUpdateScroll(const ObjectPaintProperties::UpdateResult& result) {
+ OnUpdate(result);
+ if (result.NewNodeCreated()) {
+ full_context_.force_subtree_update_reasons |=
+ PaintPropertyTreeBuilderContext::kSubtreeUpdateIsolationPiercing;
+ }
+ }
void OnClear(bool cleared) {
property_added_or_removed_ |= cleared;
property_changed_ |= cleared;
}
+ // See: |OnUpdateScroll|.
+ void OnClearScroll(bool cleared) {
+ OnClear(cleared);
+ if (cleared) {
+ full_context_.force_subtree_update_reasons |=
+ PaintPropertyTreeBuilderContext::kSubtreeUpdateIsolationPiercing;
+ }
+ }
void OnClearClip(bool cleared) {
OnClear(cleared);
full_context_.clip_changed |= cleared;
@@ -252,10 +270,10 @@ static bool NeedsScrollNode(const LayoutObject& object) {
if (!object.HasOverflowClip())
return false;
const LayoutBox& box = ToLayoutBox(object);
- // TODO(pdr): SPV2 has invalidation issues (crbug.com/732611) as well as
+ // TODO(pdr): CAP has invalidation issues (crbug.com/732611) as well as
// subpixel issues (crbug.com/693741) which prevent us from compositing the
// root scroller.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return HasScrollsOverflow(box);
return HasScrollsOverflow(box) || IsRootScroller(box);
}
@@ -293,7 +311,7 @@ static bool NeedsReplacedContentTransform(const LayoutObject& object) {
// to the object-fit box. Note that we don't actually know whether the image
// will be directly composited. This condition is relaxed to stay on the
// safe side.
- // TODO(crbug.com/875110): Figure out the condition for SPv2.
+ // TODO(crbug.com/875110): Figure out the condition for CAP.
bool is_spv1_composited =
object.HasLayer() &&
ToLayoutBoxModelObject(object).Layer()->GetCompositedLayerMapping();
@@ -317,13 +335,16 @@ static bool NeedsIsolationNodes(const LayoutObject& object) {
return false;
// Paint containment establishes isolation.
- if (object.ShouldApplyPaintContainment())
+ // Style & Layout containment also establish isolation.
+ if (object.ShouldApplyPaintContainment() ||
+ (object.ShouldApplyStyleContainment() &&
+ object.ShouldApplyLayoutContainment())) {
return true;
+ }
// Layout view establishes isolation with the exception of local roots (since
// they are already essentially isolated).
- if (RuntimeEnabledFeatures::LayoutViewIsolationNodesEnabled() &&
- object.IsLayoutView()) {
+ if (object.IsLayoutView()) {
const auto* parent_frame = object.GetFrame()->Tree().Parent();
return parent_frame && parent_frame->IsLocalFrame();
}
@@ -381,9 +402,9 @@ static bool NeedsPaintOffsetTranslation(const LayoutObject& object) {
// unnecessary full layer paint/raster invalidation when paint offset in
// ancestor transform node changes which should not affect the descendants
// of the composited layer.
- // TODO(wangxianzhu): For SPv2, we also need a avoid unnecessary paint/raster
+ // TODO(wangxianzhu): For CAP, we also need a avoid unnecessary paint/raster
// invalidation in composited layers when their paint offset changes.
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
// For only LayoutBlocks that won't be escaped by floating objects and
// column spans when finding their containing blocks.
// TODO(crbug.com/780242): This can be avoided if we have fully correct
@@ -442,7 +463,7 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffsetTranslation(
object_.StyleRef().GetPosition() == EPosition::kFixed &&
object_.StyleRef().IsFixedToBottom();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
state.rendering_context_id = context_.current.rendering_context_id;
OnUpdate(properties_->UpdatePaintOffsetTranslation(
@@ -589,14 +610,21 @@ static CompositingReasons CompositingReasonsForTransform(const LayoutBox& box) {
if (CompositingReasonFinder::RequiresCompositingForTransform(box))
compositing_reasons |= CompositingReason::k3DTransform;
- // Currently, we create transform nodes for an element whenever any property
- // is being animated so that the existence of the effect node implies the
- // existence of all nodes.
- // TODO(flackr): Check for nodes for each KeyframeModel target
- // property instead of creating all nodes and only create a transform node
- // if needed, https://crbug.com/900241
- compositing_reasons |=
- CompositingReasonFinder::CompositingReasonsForAnimation(style);
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ // Currently, we create transform nodes for an element whenever any property
+ // is being animated so that the existence of the effect node implies the
+ // existence of all nodes.
+ // TODO(flackr): Check for nodes for each KeyframeModel target
+ // property instead of creating all nodes and only create a transform node
+ // if needed, https://crbug.com/900241
+ compositing_reasons |=
+ CompositingReasonFinder::CompositingReasonsForAnimation(style);
+ } else {
+ if (CompositingReasonFinder::RequiresCompositingForTransformAnimation(
+ style))
+ compositing_reasons |= CompositingReason::kActiveTransformAnimation;
+ }
if (style.HasWillChangeCompositingHint() &&
!style.SubtreeWillChangeContents())
@@ -625,7 +653,7 @@ static FloatPoint3D TransformOrigin(const LayoutBox& box) {
}
static bool NeedsTransform(const LayoutObject& object) {
- if ((RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if ((RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) &&
object.StyleRef().BackfaceVisibility() == EBackfaceVisibility::kHidden)
return true;
@@ -662,7 +690,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
ComputedStyle::kIncludeMotionPath,
ComputedStyle::kIncludeIndependentTransformProperties);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
// TODO(trchen): transform-style should only be respected if a
// PaintLayer is created. If a node with transform-style: preserve-3d
@@ -681,7 +709,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() {
state.flattens_inherited_transform =
context_.current.should_flatten_inherited_transform;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
state.backface_visibility =
object_.HasHiddenBackface()
@@ -783,8 +811,14 @@ static bool NeedsEffect(const LayoutObject& object) {
// TODO(flackr): Check for nodes for each KeyframeModel target
// property instead of creating all nodes and only create an effect node
// if needed, https://crbug.com/900241
- if (CompositingReasonFinder::CompositingReasonsForAnimation(style))
- return true;
+ if ((RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())) {
+ if (CompositingReasonFinder::CompositingReasonsForAnimation(style))
+ return true;
+ } else {
+ if (CompositingReasonFinder::RequiresCompositingForOpacityAnimation(style))
+ return true;
+ }
if (object.StyleRef().HasMask())
return true;
@@ -828,6 +862,8 @@ bool FragmentPaintPropertyTreeBuilder::EffectCanUseCurrentClipAsOutputClip()
// Some descendants under a pagination container (e.g. composited objects
// in SPv1 and column spanners) may escape fragment clips.
+ // TODO(crbug.com/803649): Remove this when we fix fragment clip hierarchy
+ // issues.
if (layer->EnclosingPaginationLayer())
return false;
@@ -892,7 +928,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
state.blend_mode = WebCoreCompositeToSkiaComposite(
kCompositeSourceOver, style.GetBlendMode());
}
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
// We may begin to composite our subtree prior to an animation starts,
// but a compositor element ID is only needed when an animation is
@@ -926,7 +962,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
mask_state.output_clip = output_clip;
mask_state.color_filter = CSSMaskPainter::MaskColorFilter(object_);
mask_state.blend_mode = SkBlendMode::kDstIn;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
mask_state.compositor_element_id =
CompositorElementIdFromUniqueObjectId(
@@ -947,7 +983,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateEffect() {
clip_path_state.local_transform_space = context_.current.transform;
clip_path_state.output_clip = output_clip;
clip_path_state.blend_mode = SkBlendMode::kDstIn;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
clip_path_state.compositor_element_id =
CompositorElementIdFromUniqueObjectId(
@@ -982,46 +1018,68 @@ static bool NeedsLinkHighlightEffect(const LayoutObject& object) {
}
void FragmentPaintPropertyTreeBuilder::UpdateLinkHighlightEffect() {
- if (NeedsPaintPropertyUpdate()) {
- if (NeedsLinkHighlightEffect(object_)) {
- // While the link highlight uses the current transform space for
- // positioning, it's parent effect is the root so that it is not affected
- // by enclosing filters.
- const auto& parent = EffectPaintPropertyNode::Root();
- EffectPaintPropertyNode::State link_highlight_state;
- link_highlight_state.local_transform_space = context_.current.transform;
- link_highlight_state.compositor_element_id =
- object_.GetFrame()->GetPage()->GetLinkHighlights().element_id(
- object_);
- link_highlight_state.direct_compositing_reasons =
- CompositingReason::kActiveOpacityAnimation;
- // Unlike other property nodes, link highlight effect nodes are guaranteed
- // to be leaf nodes and do not require subtree invalidation, so we do not
- // call |OnUpdate| here.
- properties_->UpdateLinkHighlightEffect(parent,
- std::move(link_highlight_state));
- } else {
- // Unlike other property nodes, link highlight effect nodes are guaranteed
- // to be leaf nodes and do not require subtree invalidation, so we do not
- // call |OnClear| here.
- properties_->ClearLinkHighlightEffect();
- }
+ if (!NeedsPaintPropertyUpdate())
+ return;
+
+ DCHECK(properties_);
+
+ if (!NeedsLinkHighlightEffect(object_)) {
+ // Unlike other property nodes, link highlight effect nodes are guaranteed
+ // to be leaf nodes and do not require subtree invalidation, so we do not
+ // call |OnClear| here.
+ properties_->ClearLinkHighlightEffect();
+ return;
}
+
+ if (&fragment_data_ != &object_.FirstFragment()) {
+ // All fragments share the same LinkHighlightEffect node.
+ DCHECK(object_.FirstFragment().PaintProperties());
+ DCHECK(object_.FirstFragment().PaintProperties()->LinkHighlightEffect());
+ properties_->SetLinkHighlightEffect(
+ object_.FirstFragment().PaintProperties()->LinkHighlightEffect());
+ return;
+ }
+
+ // While the link highlight uses the current transform space for
+ // positioning, it's parent effect is the root so that it is not affected
+ // by enclosing filters.
+ const auto& parent = EffectPaintPropertyNode::Root();
+ EffectPaintPropertyNode::State link_highlight_state;
+ link_highlight_state.local_transform_space = context_.current.transform;
+ link_highlight_state.compositor_element_id =
+ object_.GetFrame()->GetPage()->GetLinkHighlights().element_id(object_);
+ link_highlight_state.direct_compositing_reasons =
+ CompositingReason::kActiveOpacityAnimation;
+ // Unlike other property nodes, link highlight effect nodes are guaranteed
+ // to be leaf nodes and do not require subtree invalidation, so we do not
+ // call |OnUpdate| here.
+ properties_->UpdateLinkHighlightEffect(parent,
+ std::move(link_highlight_state));
}
static bool NeedsFilter(const LayoutObject& object) {
// Currently, we create filter nodes for an element whenever any property
// is being animated so that the existence of the effect node implies the
// existence of all animation nodes.
+ if (!object.IsBoxModelObject() || !ToLayoutBoxModelObject(object).Layer())
+ return false;
+
+ // TODO(trchen): SVG caches filters in SVGResources. Implement it.
+ if (object.StyleRef().HasFilter() || object.HasReflection() ||
+ object.HasBackdropFilter())
+ return true;
+
// TODO(flackr): Check for nodes for each KeyframeModel target
// property instead of creating all nodes and only create a filter node
// if needed, https://crbug.com/900241
- // TODO(trchen): SVG caches filters in SVGResources. Implement it.
- return (object.IsBoxModelObject() && ToLayoutBoxModelObject(object).Layer() &&
- (object.StyleRef().HasFilter() || object.HasReflection() ||
- object.HasBackdropFilter() ||
- CompositingReasonFinder::CompositingReasonsForAnimation(
- object.StyleRef())));
+ bool needs_compositing_for_animation =
+ (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
+ ? CompositingReasonFinder::CompositingReasonsForAnimation(
+ object.StyleRef())
+ : CompositingReasonFinder::RequiresCompositingForFilterAnimation(
+ object.StyleRef());
+ return needs_compositing_for_animation;
}
void FragmentPaintPropertyTreeBuilder::UpdateFilter() {
@@ -1036,12 +1094,23 @@ void FragmentPaintPropertyTreeBuilder::UpdateFilter() {
if (auto* layer = ToLayoutBoxModelObject(object_).Layer()) {
// Try to use the cached filter.
- if (properties_->Filter())
+ if (properties_->Filter()) {
state.filter = properties_->Filter()->Filter();
+ state.backdrop_filter = properties_->Filter()->BackdropFilter();
+ state.backdrop_filter_bounds =
+ properties_->Filter()->BackdropFilterBounds();
+ }
+ // With BGPT disabled, UpdateFilterReferenceBox gets called from
+ // CompositedLayerMapping::UpdateGraphicsLayerGeometry, but only
+ // for composited layers.
+ if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() ||
+ layer->GetCompositingState() != kPaintsIntoOwnBacking) {
+ layer->UpdateFilterReferenceBox();
+ }
layer->UpdateCompositorFilterOperationsForFilter(state.filter);
layer->UpdateCompositorFilterOperationsForBackdropFilter(
- state.backdrop_filter);
+ state.backdrop_filter, &state.backdrop_filter_bounds);
layer->ClearFilterOnEffectNodeDirty();
}
@@ -1069,7 +1138,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateFilter() {
// output pixel may depend on an input pixel outside of the output clip.
// We should generate a special clip node to represent this expansion.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
// We may begin to composite our subtree prior to an animation starts,
// but a compositor element ID is only needed when an animation is
@@ -1207,6 +1276,9 @@ static bool IsPrintingRootLayoutView(const LayoutObject& object) {
return !ToLocalFrame(parent_frame)->GetDocument()->Printing();
}
+// TODO(wangxianzhu): Combine the logic by overriding LayoutBox::
+// ComputeShouldClipOverflow() in LayoutReplaced and subclasses and remove
+// this function.
static bool NeedsOverflowClipForReplacedContents(
const LayoutReplaced& replaced) {
// <svg> may optionally allow overflow. If an overflow clip is required,
@@ -1214,18 +1286,17 @@ static bool NeedsOverflowClipForReplacedContents(
if (replaced.IsSVGRoot())
return ToLayoutSVGRoot(replaced).ShouldApplyViewportClip();
+ // A replaced element with border-radius always clips the content.
if (replaced.StyleRef().HasBorderRadius())
return true;
- // Non-composited images have a micro-optimization to embed clip rects into
- // the drawings instead of using a clip node.
- bool is_spv1_composited =
- replaced.HasLayer() && replaced.Layer()->GetCompositedLayerMapping();
- if (replaced.IsImage() && !is_spv1_composited)
+ // ImagePainter (but not painters for LayoutMedia whose IsImage is also true)
+ // won't paint outside of the content box.
+ if (replaced.IsImage() && !replaced.IsMedia())
return false;
- // Embedded objects are always sized to fit the content rect.
- if (replaced.IsLayoutEmbeddedContent())
+ // Non-plugin embedded contents are always sized to fit the content box.
+ if (replaced.IsLayoutEmbeddedContent() && !replaced.IsEmbeddedObject())
return false;
return true;
@@ -1368,12 +1439,6 @@ static bool CanOmitOverflowClip(const LayoutObject& object) {
return false;
const auto& block = ToLayoutBlock(object);
- // This is a heuristic to avoid costly paint property subtree rebuild on
- // CanOmitOverflowClip() changes, e.g. on selection. This also avoids omitting
- // overflow clip when there is any self-painting descendant which is not
- // covered by ContentsVisualOverflowRect().
- if (block.HasLayer() && block.Layer()->FirstChild())
- return false;
// Selection may overflow.
if (block.IsSelected())
return false;
@@ -1382,15 +1447,6 @@ static bool CanOmitOverflowClip(const LayoutObject& object) {
if (block.HasControlClip() || block.ShouldPaintCarets())
return false;
- if (object.IsLayoutReplaced()) {
- const LayoutReplaced& replaced = ToLayoutReplaced(object);
- if (replaced.StyleRef().HasBorderRadius())
- return false;
- LayoutRect replaced_content_rect = replaced.ReplacedContentRect();
- return replaced_content_rect.IsEmpty() ||
- replaced.PhysicalContentBoxRect().Contains(replaced_content_rect);
- }
-
// We need OverflowClip for hit-testing if the clip rect excluding overlay
// scrollbars is different from the normal clip rect.
auto clip_rect = block.OverflowClipRect(LayoutPoint());
@@ -1398,7 +1454,19 @@ static bool CanOmitOverflowClip(const LayoutObject& object) {
LayoutPoint(), kExcludeOverlayScrollbarSizeForHitTesting);
if (clip_rect != clip_rect_excluding_overlay_scrollbars)
return false;
- return clip_rect.Contains(block.ContentsVisualOverflowRect());
+
+ // Visual overflow extending beyond the clip rect must be clipped.
+ // ContentsVisualOverflowRect() does not include self-painting descendants
+ // (see comment above |BoxOverflowModel|) so, as a simplification, do not
+ // omit the clip if there are any PaintLayer descendants.
+ if (block.HasLayer() && block.Layer()->FirstChild())
+ return false;
+ if (!clip_rect.Contains(block.ContentsVisualOverflowRect()))
+ return false;
+
+ // Content can scroll, and needs to be clipped, if the layout overflow extends
+ // beyond the clip rect.
+ return clip_rect.Contains(block.LayoutOverflowRect());
}
void FragmentPaintPropertyTreeBuilder::UpdateOverflowClip() {
@@ -1442,7 +1510,6 @@ void FragmentPaintPropertyTreeBuilder::UpdateOverflowClip() {
viewport_container.LocalToSVGParentTransform().Inverse().MapRect(
viewport_container.Viewport()));
}
-
const ClipPaintPropertyNode* existing = properties_->OverflowClip();
bool equal_ignoring_hit_test_rects =
!!existing &&
@@ -1486,7 +1553,7 @@ void FragmentPaintPropertyTreeBuilder::UpdatePerspective() {
ToLayoutSize(context_.current.paint_offset);
state.flattens_inherited_transform =
context_.current.should_flatten_inherited_transform;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
state.rendering_context_id = context_.current.rendering_context_id;
OnUpdate(properties_->UpdatePerspective(*context_.current.transform,
@@ -1535,8 +1602,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform() {
LayoutRect layout_replaced_rect = layout_image.ReplacedContentRect();
layout_replaced_rect.MoveBy(context_.current.paint_offset);
IntRect replaced_rect = PixelSnappedIntRect(layout_replaced_rect);
- scoped_refptr<Image> image = layout_image.ImageResource()->GetImage(
- LayoutSize(replaced_rect.Size()));
+ scoped_refptr<Image> image =
+ layout_image.ImageResource()->GetImage(replaced_rect.Size());
if (image && !image->IsNull()) {
IntRect src_rect = image->Rect();
if (ImageWasTransposed(layout_image, *image))
@@ -1575,18 +1642,62 @@ void FragmentPaintPropertyTreeBuilder::UpdateReplacedContentTransform() {
static MainThreadScrollingReasons GetMainThreadScrollingReasons(
const LayoutObject& object,
MainThreadScrollingReasons ancestor_reasons) {
- // The current main thread scrolling reasons implementation only changes
- // reasons at frame boundaries, so we can early-out when not at a LayoutView.
- // TODO(pdr): Need to find a solution to the style-related main thread
- // scrolling reasons such as opacity and transform which violate this.
- if (!object.IsLayoutView())
- return ancestor_reasons;
-
auto reasons = ancestor_reasons;
- if (!object.GetFrame()->GetSettings()->GetThreadedScrollingEnabled())
- reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
- if (object.GetFrameView()->HasBackgroundAttachmentFixedObjects())
- reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
+ if (!object.IsBox())
+ return reasons;
+
+ if (auto* scrollable_area = ToLayoutBox(object).GetScrollableArea()) {
+ if (scrollable_area->HorizontalScrollbar() &&
+ scrollable_area->HorizontalScrollbar()->IsCustomScrollbar()) {
+ reasons |= MainThreadScrollingReason::kCustomScrollbarScrolling;
+ } else if (scrollable_area->VerticalScrollbar() &&
+ scrollable_area->VerticalScrollbar()->IsCustomScrollbar()) {
+ reasons |= MainThreadScrollingReason::kCustomScrollbarScrolling;
+ }
+ }
+
+ if (object.IsLayoutView()) {
+ if (object.GetFrameView()->HasBackgroundAttachmentFixedObjects()) {
+ reasons |=
+ MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
+ }
+
+ // TODO(pdr): This should apply to all scrollable areas, not just the
+ // viewport. This is not a user-visible bug because the threaded scrolling
+ // setting is only for testing.
+ if (!object.GetFrame()->GetSettings()->GetThreadedScrollingEnabled())
+ reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
+
+ // LocalFrameView::HasVisibleSlowRepaintViewportConstrainedObjects depends
+ // on compositing (LayoutBoxModelObject::IsSlowRepaintConstrainedObject
+ // calls PaintLayer::GetCompositingState, and PaintLayer::SticksToScroller
+ // depends on the ancestor overflow layer) so CompositeAfterPaint cannot
+ // use LocalFrameView::HasVisibleSlowRepaintViewportConstrainedObjects.
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // Force main-thread scrolling if the frame has uncomposited position:
+ // fixed elements. Note: we care about this not only for input-scrollable
+ // frames but also for overflow: hidden frames, because script can run
+ // composited smooth-scroll animations. For this reason, we use
+ // HasOverflow instead of ScrollsOverflow (which is false for overflow:
+ // hidden).
+ if (ToLayoutBox(object).GetScrollableArea()->HasOverflow() &&
+ object.StyleRef().VisibleToHitTesting() &&
+ object.GetFrameView()
+ ->HasVisibleSlowRepaintViewportConstrainedObjects()) {
+ reasons |=
+ MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects;
+ }
+ } else {
+ // TODO(pdr): CompositeAfterPaint should use an approach like
+ // CompositingReasonFinder::RequiresCompositingForScrollDependentPosition,
+ // adding main thread reasons if compositing was not required. This has
+ // a small behavior change because main thread reasons will be added in
+ // the case where a non-scroll compositing trigger (e.g., transform)
+ // requires compositing, even though a main thread reason is not needed.
+ // CompositingReasonFinder::RequiresCompositingForScrollDependentPosition
+ // will need to be changed to not query PaintLayer::AncestorOverflowLayer.
+ }
+ }
return reasons;
}
@@ -1628,7 +1739,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
}
}
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
state.compositor_element_id = scrollable_area->GetCompositorElementId();
@@ -1643,8 +1754,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
state.snap_container_data = snap_coordinator->GetSnapContainerData(box);
}
- OnUpdate(properties_->UpdateScroll(*context_.current.scroll,
- std::move(state)));
+ OnUpdateScroll(properties_->UpdateScroll(*context_.current.scroll,
+ std::move(state)));
if (scrollable_area->VerticalScrollbar() ||
scrollable_area->HasLayerForVerticalScrollbar()) {
@@ -1674,7 +1785,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
OnClear(properties_->ClearHorizontalScrollbarEffect());
}
} else {
- OnClear(properties_->ClearScroll());
+ OnClearScroll(properties_->ClearScroll());
OnClear(properties_->ClearVerticalScrollbarEffect());
OnClear(properties_->ClearHorizontalScrollbarEffect());
}
@@ -1692,7 +1803,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateScrollAndScrollTranslation() {
context_.current.should_flatten_inherited_transform;
state.is_identity_or_2d_translation = true;
state.direct_compositing_reasons = CompositingReasonsForScroll(box);
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
state.rendering_context_id = context_.current.rendering_context_id;
}
@@ -1854,28 +1965,34 @@ static LayoutRect BoundingBoxInPaginationContainer(
&enclosing_pagination_layer);
}
- // Non-boxes paint in the space of their containing block.
- if (!object.IsBox()) {
- const LayoutBox& containining_block = *object.ContainingBlock();
- LayoutRect bounds_rect;
+ LayoutRect local_bounds;
+ const LayoutBox* local_space_object = nullptr;
+ if (object.IsBox()) {
+ local_space_object = ToLayoutBox(&object);
+ local_bounds = local_space_object->BorderBoxRect();
+ } else {
+ // Non-boxes paint in the space of their containing block.
+ local_space_object = object.ContainingBlock();
// For non-SVG we can get a more accurate result with LocalVisualRect,
// instead of falling back to the bounds of the enclosing block.
if (!object.IsSVG()) {
- bounds_rect = object.LocalVisualRect();
- containining_block.FlipForWritingMode(bounds_rect);
+ local_bounds = object.LocalVisualRect();
+ local_space_object->FlipForWritingMode(local_bounds);
} else {
- bounds_rect = LayoutRect(SVGLayoutSupport::LocalVisualRect(object));
+ local_bounds = LayoutRect(SVGLayoutSupport::LocalVisualRect(object));
}
+ }
- return MapLocalRectToAncestorLayer(containining_block, bounds_rect,
- enclosing_pagination_layer);
+ // The link highlight covers block visual overflows, continuations, etc. which
+ // may intersect with more fragments than the object itself.
+ if (NeedsLinkHighlightEffect(object)) {
+ local_bounds.Unite(UnionRect(object.PhysicalOutlineRects(
+ LayoutPoint(), NGOutlineType::kIncludeBlockVisualOverflow)));
}
// Compute the bounding box without transforms.
- // The object is guaranteed to be a box due to the logic above.
- const LayoutBox& box = ToLayoutBox(object);
- auto bounding_box = MapLocalRectToAncestorLayer(box, box.BorderBoxRect(),
- enclosing_pagination_layer);
+ auto bounding_box = MapLocalRectToAncestorLayer(
+ *local_space_object, local_bounds, enclosing_pagination_layer);
if (!IsRepeatingTableSection(object))
return bounding_box;
@@ -1966,7 +2083,7 @@ void FragmentPaintPropertyTreeBuilder::UpdatePaintOffset() {
return;
}
- if (object_.IsFloating())
+ if (object_.IsFloating() && !object_.IsInLayoutNGInlineFormattingContext())
context_.current.paint_offset = context_.paint_offset_for_float;
// Multicolumn spanners are painted starting at the multicolumn container (but
@@ -2073,7 +2190,7 @@ void FragmentPaintPropertyTreeBuilder::SetNeedsPaintPropertyUpdateIfNeeded() {
return;
// CSS mask and clip-path comes with an implicit clip to the border box.
- // Currently only SPv2 generate and take advantage of those.
+ // Currently only CAP generate and take advantage of those.
const bool box_generates_property_nodes_for_mask_and_clip_path =
box.HasMask() || box.HasClipPath();
// The overflow clip paint property depends on the border box rect through
@@ -2267,17 +2384,29 @@ void PaintPropertyTreeBuilder::InitSingleFragmentFromParent(
// should also skip any fragment clip created by the skipped pagination
// container. We also need to skip fragment clip if the object is a paint
// invalidation container which doesn't allow fragmentation.
+ // TODO(crbug.com/803649): This may also skip necessary clips under the
+ // skipped fragment clip.
if (object_.IsColumnSpanAll() ||
- (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() &&
+ (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
object_.IsPaintInvalidationContainer() &&
ToLayoutBoxModelObject(object_).Layer()->EnclosingPaginationLayer())) {
if (const auto* pagination_layer_in_tree_hierarchy =
object_.Parent()->EnclosingLayer()->EnclosingPaginationLayer()) {
- const auto* properties =
- pagination_layer_in_tree_hierarchy->GetLayoutObject()
- .FirstFragment()
- .PaintProperties();
+ const auto& clip_container =
+ pagination_layer_in_tree_hierarchy->GetLayoutObject();
+ const auto* properties = clip_container.FirstFragment().PaintProperties();
if (properties && properties->FragmentClip()) {
+ // However, because we don't allow an object's clip to escape the
+ // output clip of the object's effect, we can't skip fragment clip if
+ // between this object and the container there is any effect that has
+ // an output clip. TODO(crbug.com/803649): Fix this workaround.
+ const auto* clip_container_effect =
+ clip_container.FirstFragment().PostIsolationEffect();
+ for (const auto* effect = context_.fragments[0].current_effect;
+ effect != clip_container_effect; effect = effect->Parent()) {
+ if (effect->OutputClip())
+ return;
+ }
context_.fragments[0].current.clip =
properties->FragmentClip()->Parent();
}
@@ -2286,7 +2415,7 @@ void PaintPropertyTreeBuilder::InitSingleFragmentFromParent(
}
void PaintPropertyTreeBuilder::UpdateCompositedLayerPaginationOffset() {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
const auto* enclosing_pagination_layer =
@@ -2864,11 +2993,11 @@ bool PaintPropertyTreeBuilder::UpdateFragments() {
object_.StyleRef().ClipPath() || NeedsPaintOffsetTranslation(object_) ||
NeedsStickyTranslation(object_) || NeedsTransform(object_) ||
NeedsClipPathClip(object_) || NeedsEffect(object_) ||
- NeedsLinkHighlightEffect(object_) ||
NeedsTransformForNonRootSVG(object_) || NeedsFilter(object_) ||
NeedsCssClip(object_) || NeedsInnerBorderRadiusClip(object_) ||
NeedsOverflowClip(object_) || NeedsPerspective(object_) ||
NeedsReplacedContentTransform(object_) ||
+ NeedsLinkHighlightEffect(object_) ||
NeedsScrollOrScrollTranslation(object_);
// Need of fragmentation clip will be determined in CreateFragmentContexts().
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
index 69b19f58c75..91566f3564a 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -147,9 +147,9 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
auto* positioned_scroll_translation =
positioned_scroll_properties->ScrollTranslation();
auto* positioned_scroll_node = positioned_scroll_translation->ScrollNode();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -185,9 +185,9 @@ TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
auto* transformed_scroll_translation =
transformed_scroll_properties->ScrollTranslation();
auto* transformed_scroll_node = transformed_scroll_translation->ScrollNode();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -538,9 +538,9 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
// paint offset.
EXPECT_EQ(FloatPoint3D(250, 250, 0),
perspective_properties->Perspective()->Origin());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
perspective_properties->Perspective()->Parent());
} else {
@@ -567,9 +567,9 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
perspective_properties->Perspective()->Matrix());
EXPECT_EQ(FloatPoint3D(250, 250, 0),
perspective_properties->Perspective()->Origin());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
perspective_properties->Perspective()->Parent());
} else {
@@ -584,9 +584,9 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
perspective_properties->Perspective()->Matrix());
EXPECT_EQ(FloatPoint3D(70, 160, 0),
perspective_properties->Perspective()->Origin());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
perspective_properties->Perspective()->Parent());
} else {
@@ -619,7 +619,7 @@ TEST_P(PaintPropertyTreeBuilderTest, Transform) {
EXPECT_EQ(DocScrollTranslation(),
transform_properties->PaintOffsetTranslation()->Parent());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(
transform_properties->Transform()->HasDirectCompositingReasons());
}
@@ -664,7 +664,7 @@ TEST_P(PaintPropertyTreeBuilderTest, Preserve3D3DTransformedDescendant) {
preserve->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_TRUE(preserve_properties->Transform());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(
preserve_properties->Transform()->HasDirectCompositingReasons());
}
@@ -686,7 +686,7 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective3DTransformedDescendant) {
perspective->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_TRUE(perspective_properties->Transform());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(
perspective_properties->Transform()->HasDirectCompositingReasons());
}
@@ -694,7 +694,7 @@ TEST_P(PaintPropertyTreeBuilderTest, Perspective3DTransformedDescendant) {
TEST_P(PaintPropertyTreeBuilderTest,
TransformNodeWithActiveAnimationHasDirectCompositingReason) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
LoadTestData("transform-animation.html");
@@ -704,7 +704,24 @@ TEST_P(PaintPropertyTreeBuilderTest,
}
TEST_P(PaintPropertyTreeBuilderTest,
- OpacityAnimationCreatesTransformAndFilterNodes) {
+ OpacityAnimationDoesNotCreateTransformNode) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
+ RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ return;
+ }
+
+ LoadTestData("opacity-animation.html");
+ EXPECT_EQ(nullptr, PaintPropertiesForElement("target")->Transform());
+ EXPECT_EQ(nullptr, PaintPropertiesForElement("target")->Filter());
+}
+
+TEST_P(PaintPropertyTreeBuilderTest,
+ BGPTOpacityAnimationCreatesTransformAndFilterNodes) {
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() &&
+ !RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
+ return;
+ }
+
LoadTestData("opacity-animation.html");
// TODO(flackr): Verify that after https://crbug.com/900241 is fixed we no
// longer create transform or filter nodes for opacity animations.
@@ -714,7 +731,7 @@ TEST_P(PaintPropertyTreeBuilderTest,
TEST_P(PaintPropertyTreeBuilderTest,
EffectNodeWithActiveAnimationHasDirectCompositingReason) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
LoadTestData("opacity-animation.html");
@@ -742,14 +759,14 @@ TEST_P(PaintPropertyTreeBuilderTest, WillChangeTransform) {
transform_properties->Transform()->Matrix());
// The value is zero without a transform property that needs transform-offset.
EXPECT_EQ(FloatPoint3D(0, 0, 0), transform_properties->Transform()->Origin());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(nullptr, transform_properties->PaintOffsetTranslation());
} else {
// SPv1 creates PaintOffsetTranslation for composited layers.
EXPECT_EQ(TransformationMatrix().Translate(50, 100),
transform_properties->PaintOffsetTranslation()->Matrix());
}
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(
transform_properties->Transform()->HasDirectCompositingReasons());
}
@@ -802,9 +819,9 @@ TEST_P(PaintPropertyTreeBuilderTest, RelativePositionInline) {
inline_block->GetLayoutObject()->FirstFragment().PaintProperties();
EXPECT_EQ(TransformationMatrix().Translate(135, 490),
inline_block_properties->PaintOffsetTranslation()->Matrix());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
inline_block_properties->PaintOffsetTranslation()->Parent());
} else {
@@ -1138,9 +1155,9 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInSVG) {
EXPECT_EQ(
TransformationMatrix().Translate(70, 25),
svg_root_with3d_transform_properties->PaintOffsetTranslation()->Matrix());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
svg_root_with3d_transform_properties->PaintOffsetTranslation()
->Parent());
@@ -1231,9 +1248,9 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootPaintOffsetTransformNode) {
FloatSize(50, 25),
svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
EXPECT_EQ(nullptr, svg_properties->ReplacedContentTransform());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
svg_properties->PaintOffsetTranslation()->Parent());
} else {
@@ -1520,6 +1537,26 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGForeignObjectOverflowClip) {
EXPECT_EQ(nullptr, properties2);
}
+TEST_P(PaintPropertyTreeBuilderTest, OverflowClipWithEmptyVisualOverflow) {
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ body { margin: 0 }
+ ::-webkit-scrollbar {
+ width: 10px;
+ height: 10px;
+ }
+ </style>
+ <div id='container' style='width: 100px; height: 100px;
+ will-change: transform; overflow: scroll; background: lightblue;'>
+ <div id='forcescroll' style='width: 0; height: 400px;'></div>
+ </div>
+ )HTML");
+
+ const auto* clip = PaintPropertiesForElement("container")->OverflowClip();
+ EXPECT_NE(nullptr, clip);
+ EXPECT_EQ(FloatRect(0, 0, 90, 90), clip->ClipRect().Rect());
+}
+
TEST_P(PaintPropertyTreeBuilderTest,
PaintOffsetTranslationSVGHTMLBoundaryMulticol) {
SetBodyInnerHTML(R"HTML(
@@ -1603,9 +1640,9 @@ TEST_P(PaintPropertyTreeBuilderTest, ControlClip) {
LayoutObject& button = *GetLayoutObjectByElementId("button");
const ObjectPaintProperties* button_properties =
button.FirstFragment().PaintProperties();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(DocPreTranslation());
EXPECT_FALSE(DocScrollTranslation());
EXPECT_EQ(DocPreTranslation(),
@@ -1643,9 +1680,9 @@ TEST_P(PaintPropertyTreeBuilderTest, ControlClipInsideForeignObject) {
LayoutObject& button = *GetLayoutObjectByElementId("button");
const ObjectPaintProperties* button_properties =
button.FirstFragment().PaintProperties();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_FALSE(DocScrollTranslation());
} else {
// Always create scroll translation for layout view even the document does
@@ -1683,9 +1720,9 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
const ObjectPaintProperties* div_properties =
div.FirstFragment().PaintProperties();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_FALSE(DocScrollTranslation());
EXPECT_EQ(DocPreTranslation(),
div_properties->OverflowClip()->LocalTransformSpace());
@@ -1703,9 +1740,9 @@ TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
div_properties->OverflowClip()->ClipRect());
const ClipPaintPropertyNode* border_radius_clip =
div_properties->OverflowClip()->Parent();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
} else {
EXPECT_EQ(DocScrollTranslation(),
@@ -1802,8 +1839,8 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
EXPECT_EQ(TransformationMatrix().Translate3d(7, 7, 0),
iframe_pre_translation->Matrix());
// SPv1 composited elements always create paint offset translation,
- // where in SPv2 they don't.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ // where in CAP they don't.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(div_with_transform_properties->Transform(),
iframe_pre_translation->Parent());
} else {
@@ -1820,9 +1857,6 @@ TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
}
TEST_P(PaintPropertyTreeBuilderTest, FramesEstablishIsolation) {
- if (!RuntimeEnabledFeatures::LayoutViewIsolationNodesEnabled())
- return;
-
SetBodyInnerHTML(R"HTML(
<style>
body { margin: 0; }
@@ -2069,7 +2103,7 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_EQ(DocContentClip(),
child.FirstFragment().LocalBorderBoxProperties().Clip());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocScrollTranslation(),
child.FirstFragment().LocalBorderBoxProperties().Transform());
} else {
@@ -2119,9 +2153,9 @@ TEST_P(PaintPropertyTreeBuilderTest, TableCellLayoutLocation) {
LayoutObject& target = *GetLayoutObjectByElementId("target");
EXPECT_EQ(LayoutPoint(170, 170), target.FirstFragment().PaintOffset());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
target.FirstFragment().LocalBorderBoxProperties().Transform());
} else {
@@ -2164,9 +2198,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendant) {
const ObjectPaintProperties* clip_properties =
clip.FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), clip_properties->CssClip()->Parent());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
clip_properties->CssClip()->LocalTransformSpace());
} else {
@@ -2227,9 +2261,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) {
const ObjectPaintProperties* clip_properties =
clip->FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), clip_properties->CssClip()->Parent());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_FALSE(DocScrollTranslation());
EXPECT_EQ(DocPreTranslation(),
clip_properties->CssClip()->LocalTransformSpace());
@@ -2251,9 +2285,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) {
auto* absolute = GetLayoutObjectByElementId("absolute");
EXPECT_EQ(clip_properties->CssClip(),
absolute->FirstFragment().LocalBorderBoxProperties().Clip());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_FALSE(DocScrollTranslation());
EXPECT_EQ(DocPreTranslation(),
absolute->FirstFragment().LocalBorderBoxProperties().Transform());
@@ -2297,9 +2331,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipSubpixel) {
const ObjectPaintProperties* clip_properties =
clip->FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), clip_properties->CssClip()->Parent());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(DocPreTranslation());
EXPECT_EQ(DocPreTranslation(),
clip_properties->CssClip()->LocalTransformSpace());
@@ -2353,9 +2387,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendantNonShared) {
const ObjectPaintProperties* overflow_properties =
overflow.FirstFragment().PaintProperties();
EXPECT_EQ(DocContentClip(), overflow_properties->OverflowClip()->Parent());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(DocPreTranslation());
EXPECT_EQ(DocPreTranslation(),
overflow_properties->ScrollTranslation()->Parent()->Parent());
@@ -2905,7 +2939,7 @@ TEST_P(PaintPropertyTreeBuilderTest, Preserve3DCreatesSharedRenderingContext) {
b->FirstFragment().PaintProperties();
ASSERT_TRUE(a_properties->Transform() && b_properties->Transform());
EXPECT_NE(a_properties->Transform(), b_properties->Transform());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
EXPECT_EQ(a_properties->Transform()->RenderingContextId(),
@@ -2951,7 +2985,7 @@ TEST_P(PaintPropertyTreeBuilderTest, FlatTransformStyleEndsRenderingContext) {
// #a should participate in a rendering context (due to its parent), but its
// child #b should not.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
EXPECT_FALSE(b_properties->Transform()->HasRenderingContext());
}
@@ -2988,7 +3022,7 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedRenderingContexts) {
// child does preserve 3D, but since #a does not, #a's rendering context is
// not passed on to its children. Thus #b ends up in a separate rendering
// context rooted at its parent.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
EXPECT_NE(a_properties->Transform()->RenderingContextId(),
@@ -3364,9 +3398,9 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowClipContentsTreeState) {
clipper->FirstFragment().PaintProperties();
LayoutObject* child = GetLayoutObjectByElementId("child");
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_FALSE(DocScrollTranslation());
EXPECT_TRUE(DocPreTranslation());
EXPECT_EQ(DocPreTranslation(),
@@ -3384,18 +3418,18 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowClipContentsTreeState) {
auto contents_properties = clipper->FirstFragment().ContentsProperties();
EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
} else {
EXPECT_EQ(DocScrollTranslation(), contents_properties.Transform());
}
EXPECT_EQ(clip_properties->OverflowClip(), contents_properties.Clip());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
child->FirstFragment().LocalBorderBoxProperties().Transform());
} else {
@@ -3410,106 +3444,121 @@ TEST_P(PaintPropertyTreeBuilderTest, OverflowClipContentsTreeState) {
CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 500, 600), child, clipper);
}
-TEST_P(PaintPropertyTreeBuilderTest, ContainsPaintContentsTreeState) {
- SetBodyInnerHTML(R"HTML(
- <style>body { margin: 20px 30px; }</style>
- <div id='clipper'
- style='contain: paint; width: 300px; height: 200px;'>
- <div id='child'
- style='position: relative; width: 400px; height: 500px;'></div>
- </div>
- )HTML");
-
- LayoutBoxModelObject* clipper =
- ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper"));
- const ObjectPaintProperties* clip_properties =
- clipper->FirstFragment().PaintProperties();
- LayoutObject* child = GetLayoutObjectByElementId("child");
- const auto& clip_local_properties =
- clipper->FirstFragment().LocalBorderBoxProperties();
-
- // Verify that we created isolation nodes.
- EXPECT_TRUE(clip_properties->TransformIsolationNode());
- EXPECT_TRUE(clip_properties->EffectIsolationNode());
- EXPECT_TRUE(clip_properties->ClipIsolationNode());
-
- // Verify parenting:
-
- // Transform isolation node should be parented to the local border box
- // properties transform, which should be the paint offset translation.
- EXPECT_EQ(clip_properties->TransformIsolationNode()->Parent(),
- clip_local_properties.Transform());
- EXPECT_EQ(clip_properties->TransformIsolationNode()->Parent(),
- clip_properties->PaintOffsetTranslation());
- // Similarly, effect isolation node is parented to the local border box
- // properties effect.
- EXPECT_EQ(clip_properties->EffectIsolationNode()->Parent(),
- clip_local_properties.Effect());
- // Clip isolation node, however, is parented to the overflow clip, which is in
- // turn parented to the local border box properties clip.
- EXPECT_EQ(clip_properties->ClipIsolationNode()->Parent(),
- clip_properties->OverflowClip());
- EXPECT_EQ(clip_properties->OverflowClip()->Parent(),
- clip_local_properties.Clip());
-
- // Verify transform:
-
- // Isolation transform node should be identity.
- EXPECT_EQ(clip_properties->TransformIsolationNode()->Matrix(),
- TransformationMatrix());
-
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
- // scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- EXPECT_FALSE(DocScrollTranslation());
- EXPECT_TRUE(DocPreTranslation());
- // Isolation induces paint offset translation, so the node should be
- // different from the doc node, but its parent is the same as the doc node.
- EXPECT_EQ(DocPreTranslation(), clipper->FirstFragment()
- .LocalBorderBoxProperties()
- .Transform()
- ->Parent());
- } else {
- // Always create scroll translation for layout view even the document does
- // not scroll (not enough content).
- EXPECT_TRUE(DocScrollTranslation());
- // Isolation induces paint offset translation, so the node should be
- // different from the doc node, but its parent is the same as the doc node.
- EXPECT_EQ(DocScrollTranslation(), clipper->FirstFragment()
- .LocalBorderBoxProperties()
- .Transform()
- ->Parent());
- }
-
- // Verify clip:
-
- EXPECT_EQ(DocContentClip(),
- clipper->FirstFragment().LocalBorderBoxProperties().Clip());
- // Clip isolation node should be big enough to encompass all other clips,
- // including DocContentClip.
- EXPECT_TRUE(clip_properties->ClipIsolationNode()->ClipRect().Rect().Contains(
- DocContentClip()->ClipRect().Rect()));
+TEST_P(PaintPropertyTreeBuilderTest, ContainPaintOrStyleLayoutTreeState) {
+ for (const char* containment : {"paint", "style layout"}) {
+ SCOPED_TRACE(containment);
+ SetBodyInnerHTML(String::Format(R"HTML(
+ <style>body { margin: 20px 30px; }</style>
+ <div id='clipper'
+ style='contain: %s; width: 300px; height: 200px;'>
+ <div id='child'
+ style='position: relative; width: 400px; height: 500px;'></div>
+ </div>
+ )HTML",
+ containment));
+
+ LayoutBoxModelObject* clipper =
+ ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper"));
+ const ObjectPaintProperties* clip_properties =
+ clipper->FirstFragment().PaintProperties();
+ LayoutObject* child = GetLayoutObjectByElementId("child");
+ const auto& clip_local_properties =
+ clipper->FirstFragment().LocalBorderBoxProperties();
+
+ // Verify that we created isolation nodes.
+ EXPECT_TRUE(clip_properties->TransformIsolationNode());
+ EXPECT_TRUE(clip_properties->EffectIsolationNode());
+ EXPECT_TRUE(clip_properties->ClipIsolationNode());
+
+ // Verify parenting:
+
+ // Transform isolation node should be parented to the local border box
+ // properties transform, which should be the paint offset translation.
+ EXPECT_EQ(clip_properties->TransformIsolationNode()->Parent(),
+ clip_local_properties.Transform());
+ EXPECT_EQ(clip_properties->TransformIsolationNode()->Parent(),
+ clip_properties->PaintOffsetTranslation());
+ // Similarly, effect isolation node is parented to the local border box
+ // properties effect.
+ EXPECT_EQ(clip_properties->EffectIsolationNode()->Parent(),
+ clip_local_properties.Effect());
+ if (strcmp(containment, "paint") == 0) {
+ // If we contain paint, then clip isolation node is parented to the
+ // overflow clip, which is in turn parented to the local border box
+ // properties clip.
+ EXPECT_EQ(clip_properties->ClipIsolationNode()->Parent(),
+ clip_properties->OverflowClip());
+ EXPECT_EQ(clip_properties->OverflowClip()->Parent(),
+ clip_local_properties.Clip());
+ } else {
+ // Otherwise, the clip isolation node is parented to the local border box
+ // properties clip directly.
+ EXPECT_EQ(clip_properties->ClipIsolationNode()->Parent(),
+ clip_local_properties.Clip());
+ }
- // Verify contents properties and child properties:
+ // Verify transform:
+
+ // Isolation transform node should be identity.
+ EXPECT_EQ(clip_properties->TransformIsolationNode()->Matrix(),
+ TransformationMatrix());
+
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
+ // scrolling.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_FALSE(DocScrollTranslation());
+ EXPECT_TRUE(DocPreTranslation());
+ // Isolation induces paint offset translation, so the node should be
+ // different from the doc node, but its parent is the same as the doc
+ // node.
+ EXPECT_EQ(DocPreTranslation(), clipper->FirstFragment()
+ .LocalBorderBoxProperties()
+ .Transform()
+ ->Parent());
+ } else {
+ // Always create scroll translation for layout view even the document does
+ // not scroll (not enough content).
+ EXPECT_TRUE(DocScrollTranslation());
+ // Isolation induces paint offset translation, so the node should be
+ // different from the doc node, but its parent is the same as the doc
+ // node.
+ EXPECT_EQ(DocScrollTranslation(), clipper->FirstFragment()
+ .LocalBorderBoxProperties()
+ .Transform()
+ ->Parent());
+ }
- auto contents_properties = clipper->FirstFragment().ContentsProperties();
- // Since the clipper is isolated, its paint offset should be 0, 0.
- EXPECT_EQ(LayoutPoint(0, 0), clipper->FirstFragment().PaintOffset());
- // Ensure that the contents properties match isolation nodes.
- EXPECT_EQ(clip_properties->TransformIsolationNode(),
- contents_properties.Transform());
- EXPECT_EQ(clip_properties->ClipIsolationNode(), contents_properties.Clip());
- EXPECT_EQ(clip_properties->EffectIsolationNode(),
- contents_properties.Effect());
+ // Verify clip:
- // Child should be using isolation nodes as its local border box properties.
- EXPECT_EQ(contents_properties.Transform(),
- child->FirstFragment().LocalBorderBoxProperties().Transform());
- EXPECT_EQ(contents_properties.Clip(),
- child->FirstFragment().LocalBorderBoxProperties().Clip());
- EXPECT_EQ(contents_properties.Effect(),
- child->FirstFragment().LocalBorderBoxProperties().Effect());
- CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 400, 500), child, clipper);
+ EXPECT_EQ(DocContentClip(),
+ clipper->FirstFragment().LocalBorderBoxProperties().Clip());
+ // Clip isolation node should be big enough to encompass all other clips,
+ // including DocContentClip.
+ EXPECT_TRUE(
+ clip_properties->ClipIsolationNode()->ClipRect().Rect().Contains(
+ DocContentClip()->ClipRect().Rect()));
+
+ // Verify contents properties and child properties:
+
+ auto contents_properties = clipper->FirstFragment().ContentsProperties();
+ // Since the clipper is isolated, its paint offset should be 0, 0.
+ EXPECT_EQ(LayoutPoint(0, 0), clipper->FirstFragment().PaintOffset());
+ // Ensure that the contents properties match isolation nodes.
+ EXPECT_EQ(clip_properties->TransformIsolationNode(),
+ contents_properties.Transform());
+ EXPECT_EQ(clip_properties->ClipIsolationNode(), contents_properties.Clip());
+ EXPECT_EQ(clip_properties->EffectIsolationNode(),
+ contents_properties.Effect());
+
+ // Child should be using isolation nodes as its local border box properties.
+ EXPECT_EQ(contents_properties.Transform(),
+ child->FirstFragment().LocalBorderBoxProperties().Transform());
+ EXPECT_EQ(contents_properties.Clip(),
+ child->FirstFragment().LocalBorderBoxProperties().Clip());
+ EXPECT_EQ(contents_properties.Effect(),
+ child->FirstFragment().LocalBorderBoxProperties().Effect());
+ CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 400, 500), child, clipper);
+ }
}
TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollContentsTreeState) {
@@ -3625,9 +3674,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CssClipContentsTreeState) {
clipper->FirstFragment().PaintProperties();
LayoutObject* child = GetLayoutObjectByElementId("child");
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(DocPreTranslation());
EXPECT_EQ(DocPreTranslation(),
clipper->FirstFragment().LocalBorderBoxProperties().Transform());
@@ -3644,9 +3693,9 @@ TEST_P(PaintPropertyTreeBuilderTest, CssClipContentsTreeState) {
auto contents_properties = clipper->FirstFragment().ContentsProperties();
EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(), contents_properties.Transform());
} else {
EXPECT_EQ(DocScrollTranslation(), contents_properties.Transform());
@@ -3684,9 +3733,9 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_EQ(
paint_offset_translation,
svg_with_view_box.FirstFragment().LocalBorderBoxProperties().Transform());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(), paint_offset_translation->Parent());
} else {
EXPECT_EQ(DocScrollTranslation(), paint_offset_translation->Parent());
@@ -3766,9 +3815,9 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameOverflowHiddenScrollProperties) {
EXPECT_EQ(TransformationMatrix().Translate(0, -37),
DocScrollTranslation()->Matrix());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(nullptr, DocScrollTranslation()->ScrollNode());
EXPECT_EQ(nullptr, DocScroll());
} else {
@@ -3819,9 +3868,9 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) {
auto* scroll_a_translation =
overflow_a_scroll_properties->ScrollTranslation();
auto* overflow_a_scroll_node = scroll_a_translation->ScrollNode();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -4006,9 +4055,9 @@ TEST_P(PaintPropertyTreeBuilderTest, NestedPositionedScrollProperties) {
auto* scroll_a_translation =
overflow_a_scroll_properties->ScrollTranslation();
auto* overflow_a_scroll_node = scroll_a_translation->ScrollNode();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -4209,10 +4258,19 @@ TEST_P(PaintPropertyTreeBuilderTest,
ASSERT_TRUE(multicol_container->FirstFragment().NextFragment());
ASSERT_FALSE(
multicol_container->FirstFragment().NextFragment()->NextFragment());
- EXPECT_EQ(LayoutPoint(8, 8),
- multicol_container->FirstFragment().PaintOffset());
- EXPECT_EQ(LayoutPoint(59, -12),
- multicol_container->FirstFragment().NextFragment()->PaintOffset());
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(LayoutPoint(8, 8),
+ multicol_container->FirstFragment().PaintOffset());
+ EXPECT_EQ(
+ LayoutPoint(59, -12),
+ multicol_container->FirstFragment().NextFragment()->PaintOffset());
+ } else {
+ EXPECT_EQ(LayoutPoint(0, 0),
+ multicol_container->FirstFragment().PaintOffset());
+ EXPECT_EQ(
+ LayoutPoint(51, -20),
+ multicol_container->FirstFragment().NextFragment()->PaintOffset());
+ }
GetDocument().View()->LayoutViewport()->ScrollBy(ScrollOffset(0, 25),
kUserScroll);
@@ -4222,10 +4280,14 @@ TEST_P(PaintPropertyTreeBuilderTest,
ASSERT_FALSE(
multicol_container->FirstFragment().NextFragment()->NextFragment());
- EXPECT_EQ(LayoutPoint(8, 8),
- multicol_container->FirstFragment().PaintOffset());
- EXPECT_EQ(LayoutPoint(59, -12),
- multicol_container->FirstFragment().NextFragment()->PaintOffset());
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ EXPECT_EQ(LayoutPoint(8, 8),
+ multicol_container->FirstFragment().PaintOffset());
+ EXPECT_EQ(
+ LayoutPoint(59, -12),
+ multicol_container->FirstFragment().NextFragment()->PaintOffset());
+ } else {
+ }
}
TEST_P(PaintPropertyTreeBuilderTest, FragmentsUnderMultiColumn) {
@@ -4432,8 +4494,8 @@ TEST_P(PaintPropertyTreeBuilderTest, CompositedUnderMultiColumn) {
GetLayoutObjectByElementId("non-composited-child");
LayoutObject* composited_child =
GetLayoutObjectByElementId("composited-child");
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- // Compositing doesn't affect SPv2 fragmentation.
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
+ // Compositing doesn't affect CAP fragmentation.
EXPECT_EQ(2u, NumFragments(composited));
EXPECT_EQ(LayoutPoint(100, 100), FragmentAt(composited, 0).PaintOffset());
EXPECT_EQ(LayoutPoint(100, -200),
@@ -4838,7 +4900,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ChangePositionUpdateDescendantProperties) {
TEST_P(PaintPropertyTreeBuilderTest,
TransformNodeNotAnimatedStillHasCompositorElementId) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML("<div id='target' style='transform: translateX(2em)'></div");
@@ -4850,7 +4912,7 @@ TEST_P(PaintPropertyTreeBuilderTest,
TEST_P(PaintPropertyTreeBuilderTest,
EffectNodeNotAnimatedStillHasCompositorElementId) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML("<div id='target' style='opacity: 0.5'></div");
@@ -4865,7 +4927,7 @@ TEST_P(PaintPropertyTreeBuilderTest,
TEST_P(PaintPropertyTreeBuilderTest,
TransformNodeAnimatedHasCompositorElementId) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
LoadTestData("transform-animation.html");
@@ -4877,7 +4939,7 @@ TEST_P(PaintPropertyTreeBuilderTest,
}
TEST_P(PaintPropertyTreeBuilderTest, EffectNodeAnimatedHasCompositorElementId) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
LoadTestData("opacity-animation.html");
@@ -4906,13 +4968,17 @@ TEST_P(PaintPropertyTreeBuilderTest, FloatUnderInline) {
EXPECT_EQ(0.5f, effect->Opacity());
LayoutObject* target = GetLayoutObjectByElementId("target");
- EXPECT_EQ(LayoutPoint(66, 55), target->FirstFragment().PaintOffset());
+ if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
+ EXPECT_EQ(LayoutPoint(266, 155), target->FirstFragment().PaintOffset());
+ } else {
+ EXPECT_EQ(LayoutPoint(66, 55), target->FirstFragment().PaintOffset());
+ }
EXPECT_EQ(effect,
target->FirstFragment().LocalBorderBoxProperties().Effect());
}
TEST_P(PaintPropertyTreeBuilderTest, ScrollNodeHasCompositorElementId) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -5064,7 +5130,7 @@ TEST_P(PaintPropertyTreeBuilderTest, MaskEscapeClip) {
EXPECT_EQ(mask_clip, target_properties->Mask()->OutputClip());
const auto* absolute = GetLayoutObjectByElementId("absolute");
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(),
absolute->FirstFragment().LocalBorderBoxProperties().Transform());
} else {
@@ -5268,9 +5334,9 @@ TEST_P(PaintPropertyTreeBuilderTest, ScrollBoundsOffset) {
auto* scroll_translation = scroll_properties->ScrollTranslation();
auto* paint_offset_translation = scroll_properties->PaintOffsetTranslation();
auto* scroll_node = scroll_translation->ScrollNode();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(GetDocument()
.GetPage()
->GetVisualViewport()
@@ -5319,7 +5385,7 @@ TEST_P(PaintPropertyTreeBuilderTest, BackfaceHidden) {
ASSERT_NE(nullptr, target_properties);
const auto* paint_offset_translation =
target_properties->PaintOffsetTranslation();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(nullptr, paint_offset_translation);
EXPECT_EQ(LayoutPoint(60, 50), target->FirstFragment().PaintOffset());
} else {
@@ -5332,7 +5398,7 @@ TEST_P(PaintPropertyTreeBuilderTest, BackfaceHidden) {
}
const auto* transform = target_properties->Transform();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) {
ASSERT_NE(nullptr, transform);
EXPECT_TRUE(transform->Matrix().IsIdentity());
@@ -5370,9 +5436,9 @@ TEST_P(PaintPropertyTreeBuilderTest, FrameBorderRadius) {
radius, radius),
border_radius_clip->ClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
} else {
EXPECT_EQ(DocScrollTranslation(),
@@ -5404,9 +5470,9 @@ TEST_P(PaintPropertyTreeBuilderTest, ImageBorderRadius) {
radius),
border_radius_clip->ClipRect());
EXPECT_EQ(DocContentClip(), border_radius_clip->Parent());
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(DocPreTranslation(), border_radius_clip->LocalTransformSpace());
} else {
EXPECT_EQ(DocScrollTranslation(),
@@ -5514,22 +5580,6 @@ TEST_P(PaintPropertyTreeBuilderTest, FragmentPaintOffsetUnderOverflowScroll) {
EXPECT_EQ(LayoutRect(390, -10, 20, 20), second_fragment->VisualRect());
}
-// The following test tests that we restrict actual column count, to not run
-// into unnecessary performance problems. The code that applies this limitation
-// is in MultiColumnFragmentainerGroup::ActualColumnCount().
-TEST_P(PaintPropertyTreeBuilderTest, ShortColumnTallContent) {
- SetBodyInnerHTML(R"HTML(
- <div id="multicol" style="columns:3; column-gap:1px; width:101px; height:1px;">
- <div style="height:1000000px;"></div>
- </div>
- )HTML");
-
- const auto* flow_thread =
- GetLayoutObjectByElementId("multicol")->SlowFirstChild();
- ASSERT_TRUE(flow_thread->IsLayoutFlowThread());
- EXPECT_EQ(10u, NumFragments(flow_thread));
-}
-
TEST_P(PaintPropertyTreeBuilderTest, FragmentClipPixelSnapped) {
SetBodyInnerHTML(R"HTML(
<div id="container" style="columns: 2; column-gap: 0; width: 49.5px">
@@ -5641,16 +5691,16 @@ TEST_P(PaintPropertyTreeBuilderTest, RootHasCompositedScrolling) {
)HTML");
// When the root scrolls, there should be direct compositing reasons.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_TRUE(DocScrollTranslation()->HasDirectCompositingReasons());
// Remove scrolling from the root.
Element* force_scroll_element = GetDocument().getElementById("forceScroll");
force_scroll_element->setAttribute(html_names::kStyleAttr, "");
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- // TODO(crbug.com/732611): SPv2 invalidations are incorrect if there is
+ // TODO(crbug.com/732611): CAP invalidations are incorrect if there is
// scrolling.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_FALSE(DocScrollTranslation());
} else {
// Always create scroll translation for layout view even the document does
@@ -5669,7 +5719,7 @@ TEST_P(PaintPropertyTreeBuilderTest, IframeDoesNotRequireCompositedScrolling) {
)HTML");
UpdateAllLifecyclePhasesForTest();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_TRUE(DocScrollTranslation()->HasDirectCompositingReasons());
// When the child iframe scrolls, there should not be direct compositing
@@ -5791,7 +5841,7 @@ TEST_P(PaintPropertyTreeBuilderTest, ClipPathInheritanceWithoutMutation) {
}
TEST_P(PaintPropertyTreeBuilderTest, CompositedLayerSkipsFragmentClip) {
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -6088,52 +6138,6 @@ TEST_P(PaintPropertyTreeBuilderTest,
EXPECT_EQ(LayoutPoint(100, 85), paint_offset("float-right-rtl-vlr"));
}
-TEST_P(PaintPropertyTreeBuilderTest, ClipInvalidationForReplacedElement) {
- // Non-composited LayoutImage has a micro-optimization to embed object-fit
- // and clip to the drawing, thus not creating nodes.
- // SPv2 makes everything non-composited essentially.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
- return;
- // This test verifies clip nodes are correctly updated in response to
- // content box mutation.
- SetBodyInnerHTML(R"HTML(
- <style>
- img {
- box-sizing: border-box;
- width: 8px;
- height: 8px;
- object-fit: none;
- will-change: transform;
- }
- </style>
- <!-- An image of 10x10 white pixels. -->
- <img id="target" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAA
- AAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gcVABQvx8CBmA
- AAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFUlEQVQY02P
- 8//8/A27AxIAXjFRpAKXjAxH/0Dm5AAAAAElFTkSuQmCC"/>
- )HTML");
-
- {
- const auto* properties = PaintPropertiesForElement("target");
- ASSERT_TRUE(properties);
- ASSERT_TRUE(properties->OverflowClip());
- EXPECT_EQ(FloatRect(0, 0, 8, 8),
- properties->OverflowClip()->ClipRect().Rect());
- }
-
- GetDocument().getElementById("target")->setAttribute(
- html_names::kStyleAttr, "padding: 1px 2px 3px 4px;");
- UpdateAllLifecyclePhasesForTest();
-
- {
- const auto* properties = PaintPropertiesForElement("target");
- ASSERT_TRUE(properties);
- ASSERT_TRUE(properties->OverflowClip());
- EXPECT_EQ(FloatRect(4, 1, 2, 4),
- properties->OverflowClip()->ClipRect().Rect());
- }
-}
-
TEST_P(PaintPropertyTreeBuilderTest, SubpixelPositionedScrollNode) {
SetBodyInnerHTML(R"HTML(
<!DOCTYPE html>
@@ -6418,11 +6422,11 @@ TEST_P(PaintPropertyTreeBuilderTest, SVGRootCompositedClipPath) {
const auto* transform = properties->Transform();
ASSERT_NE(nullptr, transform);
EXPECT_EQ(properties->PaintOffsetTranslation(), transform->Parent());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled())
EXPECT_TRUE(transform->HasDirectCompositingReasons());
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_EQ(nullptr, properties->MaskClip());
const auto* clip_path_clip = properties->ClipPathClip();
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
index 9938a031839..39c20eb187f 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_property_tree_update_tests.cc
@@ -600,7 +600,7 @@ TEST_P(PaintPropertyTreeUpdateTest,
Element* target = GetDocument().getElementById("target");
const ObjectPaintProperties* properties =
target->GetLayoutObject()->FirstFragment().PaintProperties();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_TRUE(properties->Transform()->HasDirectCompositingReasons());
// Removing the animation should remove the transform node.
@@ -617,7 +617,7 @@ TEST_P(PaintPropertyTreeUpdateTest,
Element* target = GetDocument().getElementById("target");
const ObjectPaintProperties* properties =
target->GetLayoutObject()->FirstFragment().PaintProperties();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
EXPECT_TRUE(properties->Effect()->HasDirectCompositingReasons());
// Removing the animation should remove the effect node.
@@ -629,7 +629,7 @@ TEST_P(PaintPropertyTreeUpdateTest,
TEST_P(PaintPropertyTreeUpdateTest,
TransformNodeDoesNotLoseCompositorElementIdWhenAnimationRemoved) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
LoadTestData("transform-animation.html");
@@ -652,7 +652,7 @@ TEST_P(PaintPropertyTreeUpdateTest,
TEST_P(PaintPropertyTreeUpdateTest,
EffectNodeDoesNotLoseCompositorElementIdWhenAnimationRemoved) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
LoadTestData("opacity-animation.html");
@@ -1067,7 +1067,7 @@ TEST_P(PaintPropertyTreeUpdateTest, WillTransformChangeAboveFixed) {
}
TEST_P(PaintPropertyTreeUpdateTest, CompositingReasonForAnimation) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
SetBodyInnerHTML(R"HTML(
@@ -1095,7 +1095,7 @@ TEST_P(PaintPropertyTreeUpdateTest, CompositingReasonForAnimation) {
target->setAttribute(html_names::kStyleAttr, "transform: translateX(11px)");
UpdateAllLifecyclePhasesForTest();
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(transform->HasDirectCompositingReasons());
EXPECT_TRUE(transform->RequiresCompositingForAnimation());
}
@@ -1107,7 +1107,7 @@ TEST_P(PaintPropertyTreeUpdateTest, CompositingReasonForAnimation) {
"transform: translateX(11px); filter: opacity(40%)");
UpdateAllLifecyclePhasesForTest();
// The transform animation still continues.
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_TRUE(transform->HasDirectCompositingReasons());
EXPECT_TRUE(transform->RequiresCompositingForAnimation());
// The filter node should have correct direct compositing reasons, not
@@ -1409,4 +1409,153 @@ TEST_P(PaintPropertyTreeUpdateTest, ForwardReferencedSVGElementUpdate) {
svg2_properties->PaintOffsetTranslation()));
}
+TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForImage) {
+ // This test verifies clip nodes are correctly updated in response to
+ // content box mutation.
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ img {
+ box-sizing: border-box;
+ width: 8px;
+ height: 8px;
+ }
+ </style>
+ <!-- An image of 10x10 white pixels. -->
+ <img id="target" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAA
+ AAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gcVABQvx8CBmA
+ AAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFUlEQVQY02P
+ 8//8/A27AxIAXjFRpAKXjAxH/0Dm5AAAAAElFTkSuQmCC">
+ )HTML");
+
+ auto* target = GetDocument().getElementById("target");
+ const auto* properties = PaintPropertiesForElement("target");
+ // We don't need paint properties for object-fit: fill because the content
+ // never overflows.
+ EXPECT_EQ(nullptr, properties);
+
+ target->setAttribute(html_names::kStyleAttr, "object-fit: cover");
+ UpdateAllLifecyclePhasesForTest();
+ properties = PaintPropertiesForElement("target");
+ // We don't need paint properties because image painter always clip to the
+ // content box.
+ EXPECT_EQ(nullptr, properties);
+
+ target->setAttribute(html_names::kStyleAttr, "object-fit: none");
+ UpdateAllLifecyclePhasesForTest();
+ properties = PaintPropertiesForElement("target");
+ // Ditto.
+ EXPECT_EQ(nullptr, properties);
+
+ // We need overflow clip when there is border radius.
+ target->setAttribute(html_names::kStyleAttr,
+ "object-fit: none; border-radius: 2px");
+ UpdateAllLifecyclePhasesForTest();
+ properties = PaintPropertiesForElement("target");
+ ASSERT_TRUE(properties);
+ ASSERT_TRUE(properties->OverflowClip());
+ FloatSize corner(2, 2);
+ FloatRoundedRect::Radii radii(corner, corner, corner, corner);
+ EXPECT_EQ(FloatRoundedRect(FloatRect(8, 8, 8, 8), radii),
+ properties->OverflowClip()->ClipRect());
+
+ // We should update clip rect on border radius change.
+ target->setAttribute(html_names::kStyleAttr,
+ "object-fit: none; border-radius: 3px");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(properties, PaintPropertiesForElement("target"));
+ ASSERT_TRUE(properties->OverflowClip());
+ radii.Expand(1);
+ EXPECT_EQ(FloatRoundedRect(FloatRect(8, 8, 8, 8), radii),
+ properties->OverflowClip()->ClipRect());
+
+ // We should update clip rect on padding change.
+ target->setAttribute(
+ html_names::kStyleAttr,
+ "object-fit: none; border-radius: 3px; padding: 1px 2px 3px 4px");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(properties, PaintPropertiesForElement("target"));
+ ASSERT_TRUE(properties->OverflowClip());
+ // The rounded clip rect is the intersection of the rounded inner border
+ // rect and the content box rect.
+ EXPECT_EQ(
+ FloatRoundedRect(FloatRect(12, 9, 2, 4),
+ FloatRoundedRect::Radii(FloatSize(0, 2), FloatSize(1, 2),
+ FloatSize(), FloatSize(1, 0))),
+ properties->OverflowClip()->ClipRect());
+}
+
+TEST_P(PaintPropertyTreeUpdateTest, OverflowClipUpdateForVideo) {
+ // This test verifies clip nodes are correctly updated in response to
+ // content box mutation.
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ video {
+ box-sizing: border-box;
+ width: 8px;
+ height: 8px;
+ }
+ </style>
+ <video id="target"></video>
+ )HTML");
+
+ auto* target = GetDocument().getElementById("target");
+ const auto* properties = PaintPropertiesForElement("target");
+ // We always create overflow clip for video regardless of object-fit.
+ ASSERT_TRUE(properties);
+ ASSERT_TRUE(properties->OverflowClip());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 8, 8),
+ properties->OverflowClip()->ClipRect());
+
+ target->setAttribute(html_names::kStyleAttr, "object-fit: cover");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(properties, PaintPropertiesForElement("target"));
+ ASSERT_TRUE(properties->OverflowClip());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 8, 8),
+ properties->OverflowClip()->ClipRect());
+
+ // We need OverflowClip for object-fit: cover, too.
+ target->setAttribute(html_names::kStyleAttr, "object-fit: none");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(properties, PaintPropertiesForElement("target"));
+ ASSERT_TRUE(properties->OverflowClip());
+ EXPECT_EQ(FloatRoundedRect(8, 8, 8, 8),
+ properties->OverflowClip()->ClipRect());
+
+ // We should update clip rect on padding change.
+ target->setAttribute(html_names::kStyleAttr,
+ "object-fit: none; padding: 1px 2px 3px 4px");
+ UpdateAllLifecyclePhasesForTest();
+ ASSERT_EQ(properties, PaintPropertiesForElement("target"));
+ ASSERT_TRUE(properties->OverflowClip());
+ EXPECT_EQ(FloatRoundedRect(12, 9, 2, 4),
+ properties->OverflowClip()->ClipRect());
+}
+
+TEST_P(PaintPropertyTreeUpdateTest, ChangingClipPath) {
+ GetDocument().GetSettings()->SetPreferCompositingToLCDTextEnabled(false);
+ SetBodyInnerHTML(R"HTML(
+ <style>
+ #content {
+ height: 500px;
+ width: 200px;
+ overflow: scroll;
+ }
+ .aclippath { clip-path: circle(115px at 20px 20px); }
+ .bclippath { clip-path: circle(135px at 22px 20px); }
+ </style>
+ <div id="content"></div>
+ )HTML");
+ auto* content = GetDocument().getElementById("content");
+ content->setAttribute(html_names::kClassAttr, "aclippath");
+ UpdateAllLifecyclePhasesForTest();
+
+ content->setAttribute(html_names::kClassAttr, "bclippath");
+ UpdateAllLifecyclePhasesForTest();
+ // Pass if no crash.
+
+ content->removeAttribute(html_names::kClassAttr);
+ UpdateAllLifecyclePhasesForTest();
+ // Pass if no crash.
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing.cc b/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
index 5cd87b85cec..52b297b6a38 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.cc
@@ -72,14 +72,6 @@ void PaintTiming::MarkFirstContentfulPaint() {
SetFirstContentfulPaint(CurrentTimeTicks());
}
-void PaintTiming::MarkFirstTextPaint() {
- if (!first_text_paint_.is_null())
- return;
- first_text_paint_ = CurrentTimeTicks();
- SetFirstContentfulPaint(first_text_paint_);
- RegisterNotifySwapTime(PaintEvent::kFirstTextPaint);
-}
-
void PaintTiming::MarkFirstImagePaint() {
if (!first_image_paint_.is_null())
return;
@@ -98,12 +90,9 @@ void PaintTiming::SetFirstMeaningfulPaintCandidate(TimeTicks timestamp) {
}
void PaintTiming::SetFirstMeaningfulPaint(
- TimeTicks stamp,
TimeTicks swap_stamp,
FirstMeaningfulPaintDetector::HadUserInput had_input) {
- DCHECK(first_meaningful_paint_.is_null());
DCHECK(first_meaningful_paint_swap_.is_null());
- DCHECK(!stamp.is_null());
DCHECK(!swap_stamp.is_null());
TRACE_EVENT_MARK_WITH_TIMESTAMP2(
@@ -119,7 +108,6 @@ void PaintTiming::SetFirstMeaningfulPaint(
// Notify FMP for UMA only if there's no user input before FMP, so that layout
// changes caused by user interactions wouldn't be considered as FMP.
if (had_input == FirstMeaningfulPaintDetector::kNoUserInput) {
- first_meaningful_paint_ = stamp;
first_meaningful_paint_swap_ = swap_stamp;
NotifyPaintTimingChanged();
}
@@ -144,7 +132,7 @@ void PaintTiming::NotifyPaint(bool is_first_paint,
if (is_first_paint)
MarkFirstPaint();
if (text_painted)
- MarkFirstTextPaint();
+ MarkFirstContentfulPaint();
if (image_painted)
MarkFirstImagePaint();
fmp_detector_->NotifyPaint();
@@ -226,9 +214,6 @@ void PaintTiming::ReportSwapTime(PaintEvent event,
case PaintEvent::kFirstContentfulPaint:
SetFirstContentfulPaintSwap(timestamp);
return;
- case PaintEvent::kFirstTextPaint:
- SetFirstTextPaintSwap(timestamp);
- return;
case PaintEvent::kFirstImagePaint:
SetFirstImagePaintSwap(timestamp);
return;
@@ -262,14 +247,6 @@ void PaintTiming::SetFirstContentfulPaintSwap(TimeTicks stamp) {
fmp_detector_->NotifyFirstContentfulPaint(first_contentful_paint_swap_);
}
-void PaintTiming::SetFirstTextPaintSwap(TimeTicks stamp) {
- DCHECK(first_text_paint_swap_.is_null());
- first_text_paint_swap_ = stamp;
- probe::paintTiming(GetSupplementable(), "firstTextPaint",
- TimeTicksInSeconds(first_text_paint_swap_));
- NotifyPaintTimingChanged();
-}
-
void PaintTiming::SetFirstImagePaintSwap(TimeTicks stamp) {
DCHECK(first_image_paint_swap_.is_null());
first_image_paint_swap_ = stamp;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing.h b/chromium/third_party/blink/renderer/core/paint/paint_timing.h
index ea77cacbba4..ca4b35ebdff 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing.h
@@ -46,18 +46,16 @@ class CORE_EXPORT PaintTiming final
// event.
void MarkFirstPaint();
- // MarkFirstTextPaint, MarkFirstImagePaint, and MarkFirstContentfulPaint
+ // MarkFirstImagePaint, and MarkFirstContentfulPaint
// will also record first paint if first paint hasn't been recorded yet.
void MarkFirstContentfulPaint();
- // MarkFirstTextPaint and MarkFirstImagePaint will also record first
- // contentful paint if first contentful paint hasn't been recorded yet.
- void MarkFirstTextPaint();
+ // MarkFirstImagePaint will also record first contentful paint if first
+ // contentful paint hasn't been recorded yet.
void MarkFirstImagePaint();
void SetFirstMeaningfulPaintCandidate(TimeTicks timestamp);
void SetFirstMeaningfulPaint(
- TimeTicks stamp,
TimeTicks swap_stamp,
FirstMeaningfulPaintDetector::HadUserInput had_input);
void NotifyPaint(bool is_first_paint, bool text_painted, bool image_painted);
@@ -77,9 +75,6 @@ class CORE_EXPORT PaintTiming final
return first_contentful_paint_swap_;
}
- // FirstTextPaint returns the first time that text content was painted.
- TimeTicks FirstTextPaint() const { return first_text_paint_swap_; }
-
// FirstImagePaint returns the first time that image content was painted.
TimeTicks FirstImagePaint() const { return first_image_paint_swap_; }
@@ -134,7 +129,6 @@ class CORE_EXPORT PaintTiming final
void SetFirstPaintSwap(TimeTicks stamp);
void SetFirstContentfulPaintSwap(TimeTicks stamp);
void SetFirstImagePaintSwap(TimeTicks stamp);
- void SetFirstTextPaintSwap(TimeTicks stamp);
void RegisterNotifySwapTime(PaintEvent);
void ReportUserInputHistogram(
@@ -146,22 +140,15 @@ class CORE_EXPORT PaintTiming final
return first_contentful_paint_;
}
- TimeTicks FirstMeaningfulPaintRendered() const {
- return first_meaningful_paint_;
- }
-
// TODO(crbug/738235): Non first_*_swap_ variables are only being tracked to
// compute deltas for reporting histograms and should be removed once we
// confirm the deltas and discrepancies look reasonable.
TimeTicks first_paint_;
TimeTicks first_paint_swap_;
- TimeTicks first_text_paint_;
- TimeTicks first_text_paint_swap_;
TimeTicks first_image_paint_;
TimeTicks first_image_paint_swap_;
TimeTicks first_contentful_paint_;
TimeTicks first_contentful_paint_swap_;
- TimeTicks first_meaningful_paint_;
TimeTicks first_meaningful_paint_swap_;
TimeTicks first_meaningful_paint_candidate_;
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc
index 7b07edff362..23f48306296 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/paint/paint_timing_detector.h"
+#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_view.h"
@@ -17,8 +18,10 @@ namespace blink {
PaintTimingDetector::PaintTimingDetector(LocalFrameView* frame_view)
: frame_view_(frame_view),
- text_paint_timing_detector_(new TextPaintTimingDetector(frame_view)),
- image_paint_timing_detector_(new ImagePaintTimingDetector(frame_view)){};
+ text_paint_timing_detector_(
+ MakeGarbageCollected<TextPaintTimingDetector>(frame_view)),
+ image_paint_timing_detector_(
+ MakeGarbageCollected<ImagePaintTimingDetector>(frame_view)){};
void PaintTimingDetector::NotifyPrePaintFinished() {
text_paint_timing_detector_->OnPrePaintFinished();
@@ -51,6 +54,28 @@ void PaintTimingDetector::NotifyNodeRemoved(const LayoutObject& object) {
DOMNodeIds::IdForNode(object.GetNode()));
}
+void PaintTimingDetector::NotifyInputEvent(WebInputEvent::Type type) {
+ if (type == WebInputEvent::kMouseMove || type == WebInputEvent::kMouseEnter ||
+ type == WebInputEvent::kMouseLeave ||
+ WebInputEvent::IsPinchGestureEventType(type)) {
+ return;
+ }
+ text_paint_timing_detector_->StopRecordEntries();
+ image_paint_timing_detector_->StopRecordEntries();
+}
+
+void PaintTimingDetector::NotifyScroll(ScrollType scroll_type) {
+ if (scroll_type != kUserScroll && scroll_type != kCompositorScroll)
+ return;
+ text_paint_timing_detector_->StopRecordEntries();
+ image_paint_timing_detector_->StopRecordEntries();
+}
+
+bool PaintTimingDetector::NeedToNotifyInputOrScroll() {
+ return text_paint_timing_detector_->IsRecording() ||
+ image_paint_timing_detector_->IsRecording();
+}
+
void PaintTimingDetector::DidChangePerformanceTiming() {
Document* document = frame_view_->GetFrame().GetDocument();
if (!document)
diff --git a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h
index 4002f0873b2..78e24f289ca 100644
--- a/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/paint_timing_detector.h
@@ -5,8 +5,10 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_TIMING_DETECTOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_PAINT_TIMING_DETECTOR_H_
+#include "third_party/blink/public/platform/web_input_event.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/scroll/scroll_types.h"
namespace blink {
@@ -32,6 +34,9 @@ class CORE_EXPORT PaintTimingDetector
const PaintLayer& painting_layer);
void NotifyNodeRemoved(const LayoutObject& object);
void NotifyPrePaintFinished();
+ void NotifyInputEvent(WebInputEvent::Type);
+ bool NeedToNotifyInputOrScroll();
+ void NotifyScroll(ScrollType scroll_type);
void DidChangePerformanceTiming();
uint64_t CalculateVisualSize(const LayoutRect& invalidated_rect,
const PaintLayer& painting_layer) const;
diff --git a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
index d535454c767..b2fc79bf516 100644
--- a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
+++ b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -16,6 +16,8 @@
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_multi_column_spanner_placeholder.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
+#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
+#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/compositing_layer_property_updater.h"
@@ -58,16 +60,23 @@ void PrePaintTreeWalk::WalkTree(LocalFrameView& root_frame_view) {
context_storage_.pop_back();
#if DCHECK_IS_ON()
- if (!needs_tree_builder_context_update)
- return;
- if (VLOG_IS_ON(2) && root_frame_view.GetLayoutView()) {
- LOG(ERROR) << "PrePaintTreeWalk::Walk(root_frame_view=" << &root_frame_view
- << ")\nPaintLayer tree:";
- showLayerTree(root_frame_view.GetLayoutView()->Layer());
+ if (needs_tree_builder_context_update) {
+ if (VLOG_IS_ON(2) && root_frame_view.GetLayoutView()) {
+ LOG(ERROR) << "PrePaintTreeWalk::Walk(root_frame_view="
+ << &root_frame_view << ")\nPaintLayer tree:";
+ showLayerTree(root_frame_view.GetLayoutView()->Layer());
+ }
+ if (VLOG_IS_ON(1))
+ showAllPropertyTrees(root_frame_view);
}
- if (VLOG_IS_ON(1))
- showAllPropertyTrees(root_frame_view);
#endif
+
+ // If the frame is invalidated, we need to inform the frame's chrome client
+ // so that the client will initiate repaint of the contents.
+ if (needs_invalidate_chrome_client_) {
+ if (auto* client = root_frame_view.GetChromeClient())
+ client->InvalidateRect(IntRect(IntPoint(), root_frame_view.Size()));
+ }
}
void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) {
@@ -107,11 +116,6 @@ void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) {
if (context().tree_builder_context) {
PaintPropertyTreeBuilder::SetupContextForFrame(
frame_view, *context().tree_builder_context);
- }
- paint_invalidator_.InvalidatePaint(
- frame_view, base::OptionalOrNullptr(context().tree_builder_context),
- context().paint_invalidator_context);
- if (context().tree_builder_context) {
context().tree_builder_context->supports_composited_raster_invalidation =
frame_view.GetFrame().GetSettings()->GetAcceleratedCompositingEnabled();
}
@@ -131,7 +135,7 @@ void PrePaintTreeWalk::Walk(LocalFrameView& frame_view) {
#endif
}
- if (RuntimeEnabledFeatures::JankTrackingEnabled())
+ if (origin_trials::JankTrackingEnabled(frame_view.GetFrame().GetDocument()))
frame_view.GetJankTracker().NotifyPrePaintFinished();
if (RuntimeEnabledFeatures::FirstContentfulPaintPlusPlusEnabled()) {
frame_view.GetPaintTimingDetector().NotifyPrePaintFinished();
@@ -227,7 +231,7 @@ void PrePaintTreeWalk::InvalidatePaintForHitTesting(
void PrePaintTreeWalk::UpdateAuxiliaryObjectProperties(
const LayoutObject& object,
PrePaintTreeWalk::PrePaintTreeWalkContext& context) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
return;
if (!object.HasLayer())
@@ -268,7 +272,7 @@ bool PrePaintTreeWalk::NeedsTreeBuilderContextUpdate(
const LocalFrameView& frame_view,
const PrePaintTreeWalkContext& context) {
if ((RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled() ||
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) &&
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) &&
frame_view.GetFrame().IsLocalRoot() &&
frame_view.GetPage()->GetVisualViewport().NeedsPaintPropertyUpdate())
return true;
@@ -339,9 +343,10 @@ void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
// depends on the effective whitelisted touch action.
UpdateEffectiveWhitelistedTouchAction(object, context);
- paint_invalidator_.InvalidatePaint(
- object, base::OptionalOrNullptr(context.tree_builder_context),
- paint_invalidator_context);
+ if (paint_invalidator_.InvalidatePaint(
+ object, base::OptionalOrNullptr(context.tree_builder_context),
+ paint_invalidator_context))
+ needs_invalidate_chrome_client_ = true;
InvalidatePaintForHitTesting(object, context);
@@ -350,7 +355,9 @@ void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
InvalidatePaintLayerOptimizationsIfNeeded(object, context);
if (property_changed) {
- if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ object.GetFrameView()->SetPaintArtifactCompositorNeedsUpdate();
+
+ if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto* paint_invalidation_layer =
paint_invalidator_context.paint_invalidation_container->Layer();
if (!paint_invalidation_layer->NeedsRepaint()) {
@@ -370,7 +377,7 @@ void PrePaintTreeWalk::WalkInternal(const LayoutObject& object,
CompositingLayerPropertyUpdater::Update(object);
- if (RuntimeEnabledFeatures::JankTrackingEnabled()) {
+ if (origin_trials::JankTrackingEnabled(&object.GetDocument())) {
object.GetFrameView()->GetJankTracker().NotifyObjectPrePaint(
object, paint_invalidator_context.old_visual_rect,
*paint_invalidator_context.painting_layer);
diff --git a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
index 3a0f2a5792f..5dbf2e9312a 100644
--- a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
+++ b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk.h
@@ -115,6 +115,8 @@ class CORE_EXPORT PrePaintTreeWalk {
PaintInvalidator paint_invalidator_;
Vector<PrePaintTreeWalkContext> context_storage_;
+ bool needs_invalidate_chrome_client_ = false;
+
FRIEND_TEST_ALL_PREFIXES(PrePaintTreeWalkTest, ClipRects);
};
diff --git a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
index 9e7fd97d66f..542f008a395 100644
--- a/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/pre_paint_tree_walk_test.cc
@@ -4,7 +4,7 @@
#include "third_party/blink/renderer/core/paint/pre_paint_tree_walk.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/renderer/core/dom/events/event_listener.h"
+#include "third_party/blink/renderer/core/dom/events/native_event_listener.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/layout/layout_tree_as_text.h"
#include "third_party/blink/renderer/core/layout/layout_view.h"
@@ -303,14 +303,8 @@ TEST_P(PrePaintTreeWalkTest, ClipChangeHasRadius) {
}
namespace {
-class PrePaintTreeWalkMockEventListener final : public EventListener {
+class PrePaintTreeWalkMockEventListener final : public NativeEventListener {
public:
- PrePaintTreeWalkMockEventListener() : EventListener(kCPPEventListenerType) {}
-
- bool operator==(const EventListener& other) const final {
- return this == &other;
- }
-
void Invoke(ExecutionContext*, Event*) final {}
};
} // namespace
@@ -344,7 +338,7 @@ TEST_P(PrePaintTreeWalkTest, InsideBlockingTouchEventHandlerUpdate) {
EXPECT_FALSE(descendant.InsideBlockingTouchEventHandler());
PrePaintTreeWalkMockEventListener* callback =
- new PrePaintTreeWalkMockEventListener();
+ MakeGarbageCollected<PrePaintTreeWalkMockEventListener>();
auto* handler_element = GetDocument().getElementById("handler");
handler_element->addEventListener(event_type_names::kTouchstart, callback);
diff --git a/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc b/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
index c94a14b0101..363907839c7 100644
--- a/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/replaced_painter.cc
@@ -56,11 +56,8 @@ ScopedReplacedContentPaintState::ScopedReplacedContentPaintState(
property_changed = true;
}
- bool painter_implements_content_box_clip = replaced.IsLayoutImage();
- if (paint_properties->OverflowClip() &&
- (!painter_implements_content_box_clip ||
- replaced.StyleRef().HasBorderRadius())) {
- new_properties.SetClip(paint_properties->OverflowClip());
+ if (const auto* clip = paint_properties->OverflowClip()) {
+ new_properties.SetClip(clip);
property_changed = true;
}
@@ -157,9 +154,10 @@ void ReplacedPainter::Paint(const PaintInfo& paint_info) {
!layout_replaced_.IsSelected())
return;
- bool skip_clip = layout_replaced_.IsSVGRoot() &&
- !ToLayoutSVGRoot(layout_replaced_).ShouldApplyViewportClip();
- if (skip_clip || !layout_replaced_.PhysicalContentBoxRect().IsEmpty()) {
+ bool has_clip =
+ layout_replaced_.FirstFragment().PaintProperties() &&
+ layout_replaced_.FirstFragment().PaintProperties()->OverflowClip();
+ if (!has_clip || !layout_replaced_.PhysicalContentBoxRect().IsEmpty()) {
ScopedReplacedContentPaintState content_paint_state(paint_state,
layout_replaced_);
layout_replaced_.PaintReplaced(content_paint_state.GetPaintInfo(),
diff --git a/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc b/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
index 5c97cec87a4..fd362f8241c 100644
--- a/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
+++ b/chromium/third_party/blink/renderer/core/paint/scoped_svg_paint_state.cc
@@ -61,9 +61,9 @@ bool ScopedSVGPaintState::ApplyClipMaskAndFilterIfNecessary() {
DCHECK(!apply_clip_mask_and_filter_if_necessary_called_);
apply_clip_mask_and_filter_if_necessary_called_ = true;
#endif
- // In SPv2 we should early exit once the paint property state has been
+ // In CAP we should early exit once the paint property state has been
// applied, because all meta (non-drawing) display items are ignored in
- // SPv2. However we can't simply omit them because there are still
+ // CAP. However we can't simply omit them because there are still
// non-composited painting (e.g. SVG filters in particular) that rely on
// these meta display items.
ApplyPaintPropertyState();
diff --git a/chromium/third_party/blink/renderer/core/paint/stub_chrome_client_for_spv2.h b/chromium/third_party/blink/renderer/core/paint/stub_chrome_client_for_cap.h
index f16792d620f..96db31bf235 100644
--- a/chromium/third_party/blink/renderer/core/paint/stub_chrome_client_for_spv2.h
+++ b/chromium/third_party/blink/renderer/core/paint/stub_chrome_client_for_cap.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_STUB_CHROME_CLIENT_FOR_SPV2_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_STUB_CHROME_CLIENT_FOR_SPV2_H_
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_STUB_CHROME_CLIENT_FOR_CAP_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_STUB_CHROME_CLIENT_FOR_CAP_H_
#include "third_party/blink/renderer/core/loader/empty_clients.h"
#include "third_party/blink/renderer/platform/testing/layer_tree_host_embedder.h"
@@ -17,7 +17,7 @@ namespace blink {
// A simple ChromeClient implementation which forwards painted artifacts to a
// PaintArtifactCompositor attached to a testing cc::LayerTreeHost, and permits
// simple analysis of the results.
-class StubChromeClientForSPv2 : public EmptyChromeClient {
+class StubChromeClientForCAP : public EmptyChromeClient {
public:
bool HasLayer(const cc::Layer& layer) {
return layer.layer_tree_host() == layer_tree_.layer_tree_host();
@@ -34,4 +34,4 @@ class StubChromeClientForSPv2 : public EmptyChromeClient {
} // namespace blink
-#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_STUB_CHROME_CLIENT_FOR_SPV2_H_
+#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_STUB_CHROME_CLIENT_FOR_CAP_H_
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc
index d077d2e646e..0d47ef45466 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_image_painter.cc
@@ -56,16 +56,12 @@ void SVGImagePainter::Paint(const PaintInfo& paint_info) {
void SVGImagePainter::PaintForeground(const PaintInfo& paint_info) {
const LayoutImageResource* image_resource = layout_svg_image_.ImageResource();
- // TODO(fs): Reduce the number of conversions.
- // (FloatSize -> IntSize -> LayoutSize currently.)
- FloatSize float_image_viewport_size = ComputeImageViewportSize();
- float_image_viewport_size.Scale(layout_svg_image_.StyleRef().EffectiveZoom());
- IntSize image_viewport_size = ExpandedIntSize(float_image_viewport_size);
+ FloatSize image_viewport_size = ComputeImageViewportSize();
+ image_viewport_size.Scale(layout_svg_image_.StyleRef().EffectiveZoom());
if (image_viewport_size.IsEmpty())
return;
- scoped_refptr<Image> image =
- image_resource->GetImage(LayoutSize(image_viewport_size));
+ scoped_refptr<Image> image = image_resource->GetImage(image_viewport_size);
FloatRect dest_rect = layout_svg_image_.ObjectBoundingBox();
FloatRect src_rect(0, 0, image->width(), image->height());
diff --git a/chromium/third_party/blink/renderer/core/paint/svg_object_painter.cc b/chromium/third_party/blink/renderer/core/paint/svg_object_painter.cc
index e842ed1e7fd..d3fe7d5945b 100644
--- a/chromium/third_party/blink/renderer/core/paint/svg_object_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/svg_object_painter.cc
@@ -7,6 +7,7 @@
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
#include "third_party/blink/renderer/core/paint/paint_info.h"
+#include "third_party/blink/renderer/core/paint/paint_layer.h"
namespace blink {
@@ -15,7 +16,8 @@ void SVGObjectPainter::PaintResourceSubtree(GraphicsContext& context) {
PaintInfo info(context, LayoutRect::InfiniteIntRect(),
PaintPhase::kForeground, kGlobalPaintNormalPhase,
- kPaintLayerPaintingRenderingResourceSubtree);
+ kPaintLayerPaintingRenderingResourceSubtree,
+ &layout_object_.PaintingLayer()->GetLayoutObject());
layout_object_.Paint(info);
}
diff --git a/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc b/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc
index e655bdb0c9b..31e0fc3055b 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_cell_painter.cc
@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/core/paint/box_painter_base.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/paint_layer_scrollable_area.h"
#include "third_party/blink/renderer/core/paint/scoped_paint_state.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h"
@@ -61,8 +62,7 @@ void TableCellPainter::PaintBackground(const PaintInfo& paint_info,
}
BackgroundImageGeometry geometry(layout_table_cell_, &background_object);
BoxModelObjectPainter(layout_table_cell_)
- .PaintFillLayers(paint_info, c, bg_layer, paint_rect, geometry,
- kBackgroundBleedNone, SkBlendMode::kSrcOver);
+ .PaintFillLayers(paint_info, c, bg_layer, paint_rect, geometry);
}
}
@@ -76,27 +76,48 @@ void TableCellPainter::PaintBoxDecorationBackground(
!layout_table_cell_.FirstChild())
return;
+ bool is_painting_scrolling_background =
+ BoxModelObjectPainter::IsPaintingScrollingBackground(&layout_table_cell_,
+ paint_info);
+ const DisplayItemClient* client = nullptr;
+ LayoutRect paint_rect;
+ base::Optional<ScopedBoxContentsPaintState> contents_paint_state;
+ if (is_painting_scrolling_background) {
+ // See BoxPainter::PaintBoxDecorationBackground() for explanations.
+ // TODO(wangxianzhu): Perhaps we can merge them for CompositeAfterPaint.
+ paint_rect = layout_table_cell_.PhysicalLayoutOverflowRect();
+ contents_paint_state.emplace(paint_info, paint_offset, layout_table_cell_);
+ paint_rect.MoveBy(contents_paint_state->PaintOffset());
+ paint_rect.Expand(layout_table_cell_.BorderBoxOutsets());
+ client = &layout_table_cell_.GetScrollableArea()
+ ->GetScrollingBackgroundDisplayItemClient();
+ } else {
+ paint_rect = PaintRectNotIncludingVisualOverflow(paint_offset);
+ client = &layout_table_cell_;
+ }
+
bool has_background = style.HasBackground();
- bool has_box_shadow = style.BoxShadow();
- bool needs_to_paint_border =
- style.HasBorderDecoration() && !table->ShouldCollapseBorders();
- if (has_background || has_box_shadow || needs_to_paint_border) {
+ bool should_paint_box_shadow =
+ !is_painting_scrolling_background && style.BoxShadow();
+ bool should_paint_border = !is_painting_scrolling_background &&
+ style.HasBorderDecoration() &&
+ !table->ShouldCollapseBorders();
+
+ if (has_background || should_paint_box_shadow || should_paint_border) {
if (!DrawingRecorder::UseCachedDrawingIfPossible(
- paint_info.context, layout_table_cell_,
+ paint_info.context, *client,
DisplayItem::kBoxDecorationBackground)) {
// TODO(chrishtr): the pixel-snapping here is likely incorrect.
- DrawingRecorder recorder(paint_info.context, layout_table_cell_,
+ DrawingRecorder recorder(paint_info.context, *client,
DisplayItem::kBoxDecorationBackground);
- LayoutRect paint_rect = PaintRectNotIncludingVisualOverflow(paint_offset);
-
- if (has_box_shadow)
+ if (should_paint_box_shadow)
BoxPainterBase::PaintNormalBoxShadow(paint_info, paint_rect, style);
if (has_background)
PaintBackground(paint_info, paint_rect, layout_table_cell_);
- if (has_box_shadow) {
+ if (should_paint_box_shadow) {
// If the table collapses borders, the inner rect is the border box rect
// inset by inner half widths of collapsed borders (which are returned
// from the overriden BorderXXX() methods). Otherwise the following code
@@ -109,7 +130,7 @@ void TableCellPainter::PaintBoxDecorationBackground(
paint_info, inner_rect, layout_table_cell_.StyleRef());
}
- if (needs_to_paint_border) {
+ if (should_paint_border) {
BoxPainterBase::PaintBorder(
layout_table_cell_, layout_table_cell_.GetDocument(),
layout_table_cell_.GeneratingNode(), paint_info, paint_rect, style);
@@ -118,9 +139,8 @@ void TableCellPainter::PaintBoxDecorationBackground(
}
if (RuntimeEnabledFeatures::PaintTouchActionRectsEnabled()) {
- LayoutRect rect = PaintRectNotIncludingVisualOverflow(paint_offset);
BoxPainter(layout_table_cell_)
- .RecordHitTestData(paint_info, rect, layout_table_cell_);
+ .RecordHitTestData(paint_info, paint_rect, *client);
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc
index 200f2aca79f..107bf4fc03f 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_painter_test.cc
@@ -36,8 +36,7 @@ TEST_P(TablePainterTest, Background) {
InvalidateAll(RootPaintController());
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- IntRect interest_rect(0, 0, 200, 200);
- Paint(&interest_rect);
+ Paint(IntRect(0, 0, 200, 200));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -46,8 +45,7 @@ TEST_P(TablePainterTest, Background) {
IsSameId(&row1, DisplayItem::kBoxDecorationBackground)));
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
- interest_rect = IntRect(0, 300, 200, 1000);
- Paint(&interest_rect);
+ Paint(IntRect(0, 300, 200, 1000));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -81,8 +79,7 @@ TEST_P(TablePainterTest, BackgroundWithCellSpacing) {
InvalidateAll(RootPaintController());
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects cell1 and the spacing between cell1 and cell2.
- IntRect interest_rect(0, 200, 200, 150);
- Paint(&interest_rect);
+ Paint(IntRect(0, 200, 200, 150));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -93,8 +90,7 @@ TEST_P(TablePainterTest, BackgroundWithCellSpacing) {
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects the spacing only.
- interest_rect = IntRect(0, 250, 100, 100);
- Paint(&interest_rect);
+ Paint(IntRect(0, 250, 100, 100));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -104,8 +100,7 @@ TEST_P(TablePainterTest, BackgroundWithCellSpacing) {
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects cell2 only.
- interest_rect = IntRect(0, 350, 200, 150);
- Paint(&interest_rect);
+ Paint(IntRect(0, 350, 200, 150));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -137,8 +132,7 @@ TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) {
InvalidateAll(RootPaintController());
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects cell1 and the spacing between cell1 and cell2.
- IntRect interest_rect(200, 0, 200, 200);
- Paint(&interest_rect);
+ Paint(IntRect(200, 0, 200, 200));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -149,8 +143,7 @@ TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) {
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects the spacing only.
- interest_rect = IntRect(300, 0, 100, 100);
- Paint(&interest_rect);
+ Paint(IntRect(300, 0, 100, 100));
EXPECT_THAT(RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&ViewScrollingBackgroundClient(),
@@ -158,8 +151,7 @@ TEST_P(TablePainterTest, BackgroundInSelfPaintingRow) {
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects cell2 only.
- interest_rect = IntRect(450, 0, 200, 200);
- Paint(&interest_rect);
+ Paint(IntRect(450, 0, 200, 200));
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
@@ -183,12 +175,10 @@ TEST_P(TablePainterTest, CollapsedBorderAndOverflow) {
)HTML");
auto& cell = *ToLayoutTableCell(GetLayoutObjectByElementId("cell"));
-
InvalidateAll(RootPaintController());
GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint();
// Intersects the overflowing part of cell but not border box.
- IntRect interest_rect(0, 0, 100, 100);
- Paint(&interest_rect);
+ Paint(IntRect(0, 0, 100, 100));
// We should paint all display items of cell.
EXPECT_THAT(
diff --git a/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc b/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc
index 78f6d2826a8..bd02fbf4c34 100644
--- a/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/table_section_painter.cc
@@ -202,15 +202,16 @@ void TableSectionPainter::PaintObject(const PaintInfo& paint_info,
dirtied_columns.Start() >= dirtied_columns.End())
return;
- const auto& overflowing_cells = layout_table_section_.OverflowingCells();
- if (overflowing_cells.IsEmpty()) {
+ const auto& visually_overflowing_cells =
+ layout_table_section_.VisuallyOverflowingCells();
+ if (visually_overflowing_cells.IsEmpty()) {
// This path is for 2 cases:
// 1. Normal partial paint, without overflowing cells;
// 2. Full paint, for small sections or big sections with many overflowing
// cells.
// The difference between the normal partial paint and full paint is that
// whether dirtied_rows and dirtied_columns cover the whole section.
- DCHECK(!layout_table_section_.HasOverflowingCell() ||
+ DCHECK(!layout_table_section_.HasVisuallyOverflowingCell() ||
(dirtied_rows == layout_table_section_.FullSectionRowSpan() &&
dirtied_columns ==
layout_table_section_.FullTableEffectiveColumnSpan()));
@@ -235,7 +236,7 @@ void TableSectionPainter::PaintObject(const PaintInfo& paint_info,
// This is the "partial paint path" for overflowing cells referred in
// LayoutTableSection::ComputeOverflowFromDescendants().
Vector<const LayoutTableCell*> cells;
- CopyToVector(overflowing_cells, cells);
+ CopyToVector(visually_overflowing_cells, cells);
HashSet<const LayoutTableCell*> spanning_cells;
for (unsigned r = dirtied_rows.Start(); r < dirtied_rows.End(); r++) {
@@ -250,7 +251,7 @@ void TableSectionPainter::PaintObject(const PaintInfo& paint_info,
for (unsigned c = dirtied_columns.Start();
c < n_cols && c < dirtied_columns.End(); c++) {
if (const auto* cell = layout_table_section_.OriginatingCellAt(r, c)) {
- if (!overflowing_cells.Contains(cell))
+ if (!visually_overflowing_cells.Contains(cell))
cells.push_back(cell);
}
}
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
index 88adcefd481..c5baafdbca7 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.cc
@@ -45,9 +45,11 @@ void TextPaintTimingDetector::PopulateTraceValue(
TracedValue& value,
const TextRecord& first_text_paint,
unsigned candidate_index) const {
- value.SetInteger("DOMNodeId", first_text_paint.node_id);
+ value.SetInteger("DOMNodeId", static_cast<int>(first_text_paint.node_id));
+#ifndef NDEBUG
value.SetString("text", first_text_paint.text);
- value.SetInteger("size", first_text_paint.first_size);
+#endif
+ value.SetInteger("size", static_cast<int>(first_text_paint.first_size));
value.SetInteger("candidateIndex", candidate_index);
value.SetString("frame",
IdentifiersFactory::FrameId(&frame_view_->GetFrame()));
@@ -56,7 +58,7 @@ void TextPaintTimingDetector::PopulateTraceValue(
void TextPaintTimingDetector::OnLargestTextDetected(
const TextRecord& largest_text_record) {
largest_text_paint_ = largest_text_record.first_paint_time;
-
+ largest_text_paint_size_ = largest_text_record.first_size;
std::unique_ptr<TracedValue> value = TracedValue::Create();
PopulateTraceValue(*value, largest_text_record,
largest_text_candidate_index_max_++);
@@ -68,6 +70,7 @@ void TextPaintTimingDetector::OnLargestTextDetected(
void TextPaintTimingDetector::OnLastTextDetected(
const TextRecord& last_text_record) {
last_text_paint_ = last_text_record.first_paint_time;
+ last_text_paint_size_ = last_text_record.first_size;
std::unique_ptr<TracedValue> value = TracedValue::Create();
PopulateTraceValue(*value, last_text_record,
@@ -86,12 +89,16 @@ void TextPaintTimingDetector::TimerFired(TimerBase* time) {
void TextPaintTimingDetector::Analyze() {
TextRecord* largest_text_first_paint = FindLargestPaintCandidate();
bool new_candidate_detected = false;
+ DCHECK(!largest_text_first_paint ||
+ !largest_text_first_paint->first_paint_time.is_null());
if (largest_text_first_paint &&
largest_text_first_paint->first_paint_time != largest_text_paint_) {
OnLargestTextDetected(*largest_text_first_paint);
new_candidate_detected = true;
}
TextRecord* last_text_first_paint = FindLastPaintCandidate();
+ DCHECK(!last_text_first_paint ||
+ !last_text_first_paint->first_paint_time.is_null());
if (last_text_first_paint &&
last_text_first_paint->first_paint_time != last_text_paint_) {
OnLastTextDetected(*last_text_first_paint);
@@ -117,6 +124,12 @@ void TextPaintTimingDetector::OnPrePaintFinished() {
}
void TextPaintTimingDetector::NotifyNodeRemoved(DOMNodeId node_id) {
+ if (!is_recording_)
+ return;
+ for (TextRecord& record : texts_to_record_swap_time_) {
+ if (record.node_id == node_id)
+ record.node_id = kInvalidDOMNodeId;
+ }
if (recorded_text_node_ids_.find(node_id) == recorded_text_node_ids_.end())
return;
// We assume that removed nodes' id would not be recycled, and it's expensive
@@ -161,6 +174,8 @@ void TextPaintTimingDetector::ReportSwapTime(
// that only one or zero callback will be called after one OnPrePaintFinished.
DCHECK_GT(texts_to_record_swap_time_.size(), 0UL);
for (TextRecord& record : texts_to_record_swap_time_) {
+ if (record.node_id == kInvalidDOMNodeId)
+ continue;
record.first_paint_time = timestamp;
recorded_text_node_ids_.insert(record.node_id);
largest_text_heap_.push(std::make_unique<TextRecord>(record));
@@ -201,23 +216,27 @@ void TextPaintTimingDetector::RecordText(const LayoutObject& object,
size_zero_node_ids_.insert(node_id);
} else {
// Non-trivial text is found.
- TextRecord record = {node_id, rect_size, base::TimeTicks(),
- ToLayoutText(&object)->GetText()};
+ TextRecord record;
+ record.node_id = node_id;
+ record.first_size = rect_size;
+#ifndef NDEBUG
+ record.text = ToLayoutText(&object)->GetText();
+#endif
texts_to_record_swap_time_.push_back(record);
}
if (recorded_text_node_ids_.size() + size_zero_node_ids_.size() +
texts_to_record_swap_time_.size() >=
kTextNodeNumberLimit) {
- Deactivate();
+ TRACE_EVENT_INSTANT2("loading", "TextPaintTimingDetector::OverNodeLimit",
+ TRACE_EVENT_SCOPE_THREAD, "recorded_node_count",
+ recorded_text_node_ids_.size(), "size_zero_node_count",
+ size_zero_node_ids_.size());
+ StopRecordEntries();
}
}
-void TextPaintTimingDetector::Deactivate() {
- TRACE_EVENT_INSTANT2("loading", "TextPaintTimingDetector::OverNodeLimit",
- TRACE_EVENT_SCOPE_THREAD, "recorded_node_count",
- recorded_text_node_ids_.size(), "size_zero_node_count",
- size_zero_node_ids_.size());
+void TextPaintTimingDetector::StopRecordEntries() {
timer_.Stop();
is_recording_ = false;
}
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
index d009f65a73c..84034207c02 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector.h
@@ -22,7 +22,9 @@ struct TextRecord {
DOMNodeId node_id = kInvalidDOMNodeId;
uint64_t first_size = 0;
base::TimeTicks first_paint_time = base::TimeTicks();
+#ifndef NDEBUG
String text = "";
+#endif
};
// TextPaintTimingDetector contains Largest Text Paint and Last Text Paint.
@@ -62,7 +64,11 @@ class CORE_EXPORT TextPaintTimingDetector final
void NotifyNodeRemoved(DOMNodeId);
void Dispose() { timer_.Stop(); }
base::TimeTicks LargestTextPaint() const { return largest_text_paint_; }
+ uint64_t LargestTextPaintSize() const { return largest_text_paint_size_; }
base::TimeTicks LastTextPaint() const { return last_text_paint_; }
+ uint64_t LastTextPaintSize() const { return last_text_paint_size_; }
+ void StopRecordEntries();
+ bool IsRecording() const { return is_recording_; }
void Trace(blink::Visitor*);
private:
@@ -77,7 +83,6 @@ class CORE_EXPORT TextPaintTimingDetector final
void RegisterNotifySwapTime(ReportTimeCallback callback);
void OnLargestTextDetected(const TextRecord&);
void OnLastTextDetected(const TextRecord&);
- void Deactivate();
HashSet<DOMNodeId> recorded_text_node_ids_;
HashSet<DOMNodeId> size_zero_node_ids_;
@@ -100,7 +105,9 @@ class CORE_EXPORT TextPaintTimingDetector final
bool is_recording_ = true;
base::TimeTicks largest_text_paint_;
+ uint64_t largest_text_paint_size_ = 0;
base::TimeTicks last_text_paint_;
+ uint64_t last_text_paint_size_ = 0;
TaskRunnerTimer<TextPaintTimingDetector> timer_;
Member<LocalFrameView> frame_view_;
};
diff --git a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
index 2b2f395d437..496c9a76dcf 100644
--- a/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/text_paint_timing_detector_test.cc
@@ -24,6 +24,19 @@ class TextPaintTimingDetectorTest
return GetFrameView().GetPaintTimingDetector();
}
+ unsigned CountRecords() {
+ return GetPaintTimingDetector()
+ .GetTextPaintTimingDetector()
+ .recorded_text_node_ids_.size();
+ }
+
+ void InvokeCallback() {
+ TextPaintTimingDetector& detector =
+ GetPaintTimingDetector().GetTextPaintTimingDetector();
+ detector.ReportSwapTime(WebLayerTreeView::SwapResult::kDidSwap,
+ CurrentTimeTicks());
+ }
+
TimeTicks LargestPaintStoredResult() {
return GetPaintTimingDetector()
.GetTextPaintTimingDetector()
@@ -50,49 +63,103 @@ class TextPaintTimingDetectorTest
void SimulateAnalyze() {
GetPaintTimingDetector().GetTextPaintTimingDetector().Analyze();
}
+
+ Element* AppendFontElementToBody(String content) {
+ Element* element = GetDocument().CreateRawElement(html_names::kFontTag);
+ element->setAttribute(html_names::kSizeAttr, AtomicString("5"));
+ Text* text = GetDocument().createTextNode(content);
+ element->AppendChild(text);
+ GetDocument().body()->AppendChild(element);
+ return element;
+ }
+
+ Element* AppendDivElementToBody(String content, String style = "") {
+ Element* div = GetDocument().CreateRawElement(html_names::kDivTag);
+ div->setAttribute(html_names::kStyleAttr, AtomicString(style));
+ Text* text = GetDocument().createTextNode(content);
+ div->AppendChild(text);
+ GetDocument().body()->AppendChild(div);
+ return div;
+ }
+
+ DOMNodeId NodeIdOfText(Element* element) {
+ DCHECK_EQ(element->CountChildren(), 1u);
+ DCHECK(element->firstChild()->IsTextNode());
+ DCHECK(!element->firstChild()->hasChildren());
+ return DOMNodeIds::IdForNode(element->firstChild());
+ }
+
+ TextRecord* TextRecordOfLargestTextPaint() {
+ return GetPaintTimingDetector()
+ .GetTextPaintTimingDetector()
+ .FindLargestPaintCandidate();
+ }
+
+ TextRecord* TextRecordOfLastTextPaint() {
+ return GetPaintTimingDetector()
+ .GetTextPaintTimingDetector()
+ .FindLastPaintCandidate();
+ }
+
+ void SetFontSize(Element* font_element, uint8_t font_size) {
+ DCHECK_EQ(font_element->nodeName(), "FONT");
+ font_element->setAttribute(html_names::kSizeAttr,
+ AtomicString(WTF::String::Number(font_size)));
+ }
+
+ void SetElementStyle(Element* element, String style) {
+ element->setAttribute(html_names::kStyleAttr, AtomicString(style));
+ }
+
+ void RemoveElement(Element* element) {
+ element->GetLayoutObject()->Parent()->GetNode()->removeChild(element);
+ }
};
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_NoText) {
SetBodyInnerHTML(R"HTML(
- <div></div>
+ <body></body>
)HTML");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_FALSE(record);
+ EXPECT_FALSE(TextRecordOfLargestTextPaint());
}
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_OneText) {
SetBodyInnerHTML(R"HTML(
- <div>The only text</div>
+ <body></body>
)HTML");
+ Element* only_text = AppendDivElementToBody("The only text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_TRUE(record);
- EXPECT_EQ(record->text, "The only text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(only_text));
+}
+
+TEST_F(TextPaintTimingDetectorTest, NodeRemovedBeforeAssigningSwapTime) {
+ SetBodyInnerHTML(R"HTML(
+ <div id="parent">
+ <div id="remove">The only text</div>
+ </div>
+ )HTML");
+ UpdateAllLifecyclePhasesForTest();
+ GetDocument().getElementById("parent")->RemoveChild(
+ GetDocument().getElementById("remove"));
+ InvokeCallback();
+ EXPECT_EQ(CountRecords(), 0u);
}
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_LargestText) {
SetBodyInnerHTML(R"HTML(
- <div>medium text</div>
+ <body></body>
)HTML");
+ AppendDivElementToBody("medium text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- Text* larger_text = GetDocument().createTextNode("a long-long-long text");
- GetDocument().body()->AppendChild(larger_text);
+ Element* large_text = AppendDivElementToBody("a long-long-long text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- Text* tiny_text = GetDocument().createTextNode("small");
- GetDocument().body()->AppendChild(tiny_text);
+ AppendDivElementToBody("small");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_EQ(record->text, "a long-long-long text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(large_text));
}
TEST_F(TextPaintTimingDetectorTest, UpdateResultWhenCandidateChanged) {
@@ -126,26 +193,24 @@ TEST_F(TextPaintTimingDetectorTest, UpdateResultWhenCandidateChanged) {
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_ReportFirstPaintTime) {
TimeTicks time1 = CurrentTimeTicks();
SetBodyInnerHTML(R"HTML(
- <div>
- <div id='b'>size-changing block</div>
- <div>a long-long-long-long moving text</div>
- </div>
+ <body></body>
)HTML");
+ Element* size_changing_text = AppendFontElementToBody("size-changing text");
+ Element* long_text =
+ AppendFontElementToBody("a long-long-long-long moving text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
TimeTicks time2 = CurrentTimeTicks();
- GetDocument().getElementById("b")->setAttribute(html_names::kStyleAttr,
- AtomicString("height:50px"));
+ SetFontSize(size_changing_text, 50);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- GetDocument().getElementById("b")->setAttribute(html_names::kStyleAttr,
- AtomicString("height:100px"));
+ SetFontSize(long_text, 100);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
TextRecord* record = GetPaintTimingDetector()
.GetTextPaintTimingDetector()
.FindLargestPaintCandidate();
- EXPECT_EQ(record->text, "a long-long-long-long moving text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(long_text));
TimeTicks firing_time = record->first_paint_time;
EXPECT_GE(firing_time, time1);
EXPECT_GE(time2, firing_time);
@@ -173,89 +238,62 @@ TEST_F(TextPaintTimingDetectorTest,
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_IgnoreRemovedText) {
SetBodyInnerHTML(R"HTML(
- <div id='parent'>
- <div id='earlyLargeText'>(large text)(large text)(large text)(large text)(large text)(large text)</div>
- <div>small text</div>
- </div>
+ <body></body>
)HTML");
+ Element* large_text = AppendDivElementToBody(
+ "(large text)(large text)(large text)(large text)(large text)(large "
+ "text)");
+ Element* small_text = AppendDivElementToBody("small text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_TRUE(record);
- EXPECT_EQ(record->text,
- "(large text)(large text)(large text)(large text)(large "
- "text)(large text)");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(large_text));
- GetDocument().getElementById("parent")->RemoveChild(
- GetDocument().getElementById("earlyLargeText"));
+ RemoveElement(large_text);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_EQ(record->text, "small text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(small_text));
}
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_ReportLastNullCandidate) {
SetBodyInnerHTML(R"HTML(
- <div id='parent'>
- <div id='remove'>text</div>
- </div>
+ <body></body>
)HTML");
+ Element* text = AppendDivElementToBody("text to remove");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
SimulateAnalyze();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_TRUE(record);
- EXPECT_EQ(record->text, "text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(text));
EXPECT_NE(LargestPaintStoredResult(), base::TimeTicks());
- GetDocument().getElementById("parent")->RemoveChild(
- GetDocument().getElementById("remove"));
+ RemoveElement(text);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
SimulateAnalyze();
- record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_FALSE(record);
+ EXPECT_FALSE(TextRecordOfLargestTextPaint());
EXPECT_EQ(LargestPaintStoredResult(), base::TimeTicks());
}
TEST_F(TextPaintTimingDetectorTest,
LargestTextPaint_CompareVisualSizeNotActualSize) {
SetBodyInnerHTML(R"HTML(
- <div>
- <div>short</div>
- <div style="position:fixed;left:-10px">a long text</div>
- </div>
+ <body></body>
)HTML");
+ AppendDivElementToBody("a long text", "position:fixed;left:-10px");
+ Element* short_text = AppendDivElementToBody("short");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_EQ(record->text, "short");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(short_text));
}
+// Depite that the l
TEST_F(TextPaintTimingDetectorTest, LargestTextPaint_CompareSizesAtFirstPaint) {
SetBodyInnerHTML(R"HTML(
- <div>
- <div id="shorteningText">large-to-small text</div>
- <div>a medium text</div>
- </div>
+ <body></body>
)HTML");
+ Element* shortening_long_text = AppendDivElementToBody("123456789");
+ AppendDivElementToBody("12345678"); // 1 letter shorter than the above.
UpdateAllLifecyclePhasesAndSimulateSwapTime();
// The visual size becomes smaller when less portion intersecting with
// viewport.
- GetDocument()
- .getElementById("shorteningText")
- ->setAttribute(html_names::kStyleAttr,
- AtomicString("position:fixed;left:-10px"));
+ SetElementStyle(shortening_long_text, "position:fixed;left:-10px");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_EQ(record->text, "large-to-small text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id,
+ NodeIdOfText(shortening_long_text));
}
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_NoText) {
@@ -271,61 +309,49 @@ TEST_F(TextPaintTimingDetectorTest, LastTextPaint_NoText) {
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_OneText) {
SetBodyInnerHTML(R"HTML(
- <div>The only text</div>
+ <body></body>
)HTML");
+ Element* text = AppendDivElementToBody("The only text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLastPaintCandidate();
- EXPECT_EQ(record->text, "The only text");
+ EXPECT_EQ(TextRecordOfLargestTextPaint()->node_id, NodeIdOfText(text));
}
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_LastText) {
SetBodyInnerHTML(R"HTML(
<div>1st text</div>
)HTML");
+ AppendDivElementToBody("s");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- Text* larger_text = GetDocument().createTextNode("2nd text");
- GetDocument().body()->AppendChild(larger_text);
+ AppendDivElementToBody("loooooooong");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- Text* tiny_text = GetDocument().createTextNode("3rd text");
- GetDocument().body()->AppendChild(tiny_text);
+ Element* third_text = AppendDivElementToBody("medium");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLastPaintCandidate();
- EXPECT_EQ(record->text, "3rd text");
+ EXPECT_EQ(TextRecordOfLastTextPaint()->node_id, NodeIdOfText(third_text));
}
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_ReportFirstPaintTime) {
SetBodyInnerHTML(R"HTML(
- <div>
- <div id='b'>size-changing block</div>
- </div>
+ <body></body>
)HTML");
+ AppendDivElementToBody("a loooooooooooooooooooong text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
TimeTicks time1 = CurrentTimeTicks();
- Text* tiny_text = GetDocument().createTextNode("latest text");
- GetDocument().body()->AppendChild(tiny_text);
+ Element* latest_text = AppendFontElementToBody("latest text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
TimeTicks time2 = CurrentTimeTicks();
- GetDocument().getElementById("b")->setAttribute(html_names::kStyleAttr,
- AtomicString("height:50px"));
+ SetFontSize(latest_text, 50);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- GetDocument().getElementById("b")->setAttribute(html_names::kStyleAttr,
- AtomicString("height:100px"));
+ SetFontSize(latest_text, 100);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLastPaintCandidate();
- EXPECT_EQ(record->text, "latest text");
+ TextRecord* record = TextRecordOfLastTextPaint();
+ EXPECT_EQ(record->node_id, NodeIdOfText(latest_text));
TimeTicks firing_time = record->first_paint_time;
EXPECT_GE(firing_time, time1);
EXPECT_GE(time2, firing_time);
@@ -333,83 +359,53 @@ TEST_F(TextPaintTimingDetectorTest, LastTextPaint_ReportFirstPaintTime) {
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_IgnoreRemovedText) {
SetBodyInnerHTML(R"HTML(
- <body>
- <div>earliest text</div>
- </body>
+ <body></body>
)HTML");
+ Element* first_text = AppendDivElementToBody("1st text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- Text* tiny_text = GetDocument().createTextNode("latest text");
- GetDocument().body()->AppendChild(tiny_text);
+ Element* second_text = AppendDivElementToBody("2nd text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- GetDocument().body()->RemoveChild(GetDocument().body()->lastChild());
+ RemoveElement(second_text);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLastPaintCandidate();
- EXPECT_EQ(record->text, "earliest text");
+ EXPECT_EQ(TextRecordOfLastTextPaint()->node_id, NodeIdOfText(first_text));
}
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_StopRecordingOverNodeLimit) {
SetBodyInnerHTML(R"HTML(
- <body>
- </body>
+ <body></body>
)HTML");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- for (int i = 1; i <= 4999; i++) {
- Element* div = GetDocument().CreateRawElement(html_names::kDivTag);
- div->appendChild(GetDocument().createTextNode(WTF::String::Number(i)));
- div->setAttribute(html_names::kStyleAttr,
- AtomicString("position:fixed;left:0px"));
- GetDocument().body()->AppendChild(div);
- }
- UpdateAllLifecyclePhasesAndSimulateSwapTime();
+ for (int i = 1; i <= 4999; i++)
+ AppendDivElementToBody(WTF::String::Number(i), "position:fixed;left:0px");
- TextRecord* record;
- Text* text;
+ UpdateAllLifecyclePhasesAndSimulateSwapTime();
- text = GetDocument().createTextNode(WTF::String::Number(5000));
- GetDocument().body()->AppendChild(text);
+ Element* text_5000 = AppendDivElementToBody(WTF::String::Number(5000));
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLastPaintCandidate();
- EXPECT_EQ(record->text, "5000");
+ EXPECT_EQ(TextRecordOfLastTextPaint()->node_id, NodeIdOfText(text_5000));
- text = GetDocument().createTextNode(WTF::String::Number(5001));
- GetDocument().body()->AppendChild(text);
+ AppendDivElementToBody(WTF::String::Number(5001));
UpdateAllLifecyclePhasesAndSimulateSwapTime();
- record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLastPaintCandidate();
- EXPECT_EQ(record->text, "5000");
+ EXPECT_EQ(TextRecordOfLastTextPaint()->node_id, NodeIdOfText(text_5000));
}
TEST_F(TextPaintTimingDetectorTest, LastTextPaint_ReportLastNullCandidate) {
SetBodyInnerHTML(R"HTML(
- <div id='parent'>
- <div id='remove'>text</div>
- </div>
+ <body></body>
)HTML");
+ Element* text = AppendDivElementToBody("text");
UpdateAllLifecyclePhasesAndSimulateSwapTime();
SimulateAnalyze();
- TextRecord* record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_TRUE(record);
- EXPECT_EQ(record->text, "text");
+ EXPECT_EQ(TextRecordOfLastTextPaint()->node_id, NodeIdOfText(text));
EXPECT_NE(LastPaintStoredResult(), base::TimeTicks());
- GetDocument().getElementById("parent")->RemoveChild(
- GetDocument().getElementById("remove"));
+ RemoveElement(text);
UpdateAllLifecyclePhasesAndSimulateSwapTime();
SimulateAnalyze();
- record = GetPaintTimingDetector()
- .GetTextPaintTimingDetector()
- .FindLargestPaintCandidate();
- EXPECT_FALSE(record);
+ EXPECT_FALSE(TextRecordOfLastTextPaint());
EXPECT_EQ(LastPaintStoredResult(), base::TimeTicks());
}
diff --git a/chromium/third_party/blink/renderer/core/paint/video_painter.cc b/chromium/third_party/blink/renderer/core/paint/video_painter.cc
index 4ae8687d6eb..4adf6f23499 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter.cc
@@ -38,8 +38,8 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
return;
GraphicsContext& context = paint_info.context;
- LayoutRect content_rect = layout_video_.PhysicalContentBoxRect();
- content_rect.MoveBy(paint_offset);
+ LayoutRect content_box_rect = layout_video_.PhysicalContentBoxRect();
+ content_box_rect.MoveBy(paint_offset);
// Video frames are only painted in software for printing or capturing node
// images via web APIs.
@@ -48,21 +48,20 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
bool paint_with_foreign_layer =
!displaying_poster && !force_software_video_paint &&
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled();
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled();
if (paint_with_foreign_layer) {
if (cc::Layer* layer = layout_video_.MediaElement()->CcLayer()) {
- IntRect pixel_snapped_rect = PixelSnappedIntRect(content_rect);
layer->SetOffsetToTransformParent(
- gfx::Vector2dF(pixel_snapped_rect.X(), pixel_snapped_rect.Y()));
- layer->SetBounds(gfx::Size(pixel_snapped_rect.Size()));
+ gfx::Vector2dF(snapped_replaced_rect.X(), snapped_replaced_rect.Y()));
+ layer->SetBounds(gfx::Size(snapped_replaced_rect.Size()));
layer->SetIsDrawable(true);
RecordForeignLayer(context, DisplayItem::kForeignLayerVideo, layer);
+ if (layout_video_.GetFrameView())
+ layout_video_.GetFrameView()->SetPaintArtifactCompositorNeedsUpdate();
return;
}
}
- // TODO(trchen): Video rect could overflow the content rect due to object-fit.
- // Should apply a clip here like EmbeddedObjectPainter does.
DrawingRecorder recorder(context, layout_video_, paint_info.phase);
if (displaying_poster || !force_software_video_paint) {
@@ -70,7 +69,7 @@ void VideoPainter::PaintReplaced(const PaintInfo& paint_info,
// paint nothing.
DCHECK(paint_info.PaintContainer());
ImagePainter(layout_video_)
- .PaintIntoRect(context, replaced_rect, content_rect,
+ .PaintIntoRect(context, replaced_rect, content_box_rect,
paint_info.PaintContainer()->Layer());
} else {
PaintFlags video_flags = context.FillFlags();
diff --git a/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc
index 7a445402b80..1a6fe96c6f0 100644
--- a/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/video_painter_test.cc
@@ -9,12 +9,12 @@
#include "third_party/blink/public/platform/web_size.h"
#include "third_party/blink/renderer/core/html/media/html_media_element.h"
#include "third_party/blink/renderer/core/paint/paint_controller_paint_test.h"
-#include "third_party/blink/renderer/core/paint/stub_chrome_client_for_spv2.h"
+#include "third_party/blink/renderer/core/paint/stub_chrome_client_for_cap.h"
#include "third_party/blink/renderer/platform/testing/empty_web_media_player.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
-// Integration tests of video painting code (in SPv2 mode).
+// Integration tests of video painting code (in CAP mode).
namespace blink {
namespace {
@@ -58,13 +58,14 @@ class VideoStubLocalFrameClient : public EmptyLocalFrameClient {
}
};
-class VideoPainterTestForSPv2 : private ScopedSlimmingPaintV2ForTest,
- public PaintControllerPaintTestBase {
+class VideoPainterTestForCAP : private ScopedCompositeAfterPaintForTest,
+ public PaintControllerPaintTestBase {
public:
- VideoPainterTestForSPv2()
- : ScopedSlimmingPaintV2ForTest(true),
- PaintControllerPaintTestBase(new VideoStubLocalFrameClient),
- chrome_client_(new StubChromeClientForSPv2) {}
+ VideoPainterTestForCAP()
+ : ScopedCompositeAfterPaintForTest(true),
+ PaintControllerPaintTestBase(
+ MakeGarbageCollected<VideoStubLocalFrameClient>()),
+ chrome_client_(MakeGarbageCollected<StubChromeClientForCAP>()) {}
void SetUp() override {
PaintControllerPaintTestBase::SetUp();
@@ -79,12 +80,12 @@ class VideoPainterTestForSPv2 : private ScopedSlimmingPaintV2ForTest,
ChromeClient& GetChromeClient() const override { return *chrome_client_; }
private:
- Persistent<StubChromeClientForSPv2> chrome_client_;
+ Persistent<StubChromeClientForCAP> chrome_client_;
};
-TEST_F(VideoPainterTestForSPv2, VideoLayerAppearsInLayerTree) {
+TEST_F(VideoPainterTestForCAP, VideoLayerAppearsInLayerTree) {
// Insert a <video> and allow it to begin loading.
- SetBodyInnerHTML("<video width=300 height=200 src=test.ogv>");
+ SetBodyInnerHTML("<video width=300 height=300 src=test.ogv>");
test::RunPendingTasks();
// Force the page to paint.
@@ -99,7 +100,9 @@ TEST_F(VideoPainterTestForSPv2, VideoLayerAppearsInLayerTree) {
const cc::Layer* layer = player->GetCcLayer();
ASSERT_TRUE(layer);
EXPECT_TRUE(HasLayerAttached(*layer));
- EXPECT_EQ(gfx::Size(300, 200), layer->bounds());
+ // The layer bounds reflects the aspectn ratio and object-fit of the video.
+ EXPECT_EQ(gfx::Vector2dF(8, 83), layer->offset_to_transform_parent());
+ EXPECT_EQ(gfx::Size(300, 150), layer->bounds());
}
} // namespace
diff --git a/chromium/third_party/blink/renderer/core/paint/view_painter.cc b/chromium/third_party/blink/renderer/core/paint/view_painter.cc
index c81a3325fb5..dc42d8d7144 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter.cc
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter.cc
@@ -224,7 +224,7 @@ void ViewPainter::PaintBoxDecorationBackgroundInternal(
if (combined_background_color.Alpha()) {
if (!combined_background_color.HasAlpha() &&
- RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
+ RuntimeEnabledFeatures::CompositeAfterPaintEnabled())
recorder.SetKnownToBeOpaque();
context.FillRect(
background_rect, combined_background_color,
diff --git a/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc b/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc
index f217354b9a0..7a725587fec 100644
--- a/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc
+++ b/chromium/third_party/blink/renderer/core/paint/view_painter_test.cc
@@ -49,7 +49,7 @@ void ViewPainterTest::RunFixedBackgroundTest(
DocumentLifecycle::LifecycleUpdateReason::kTest);
const DisplayItem* background_display_item = nullptr;
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
const auto& display_items = RootPaintController().GetDisplayItemList();
if (prefer_compositing_to_lcd_text) {
EXPECT_THAT(
@@ -106,8 +106,6 @@ void ViewPainterTest::RunFixedBackgroundTest(
SkRect rect = static_cast<const cc::DrawRectOp*>(*it)->rect;
if (prefer_compositing_to_lcd_text) {
EXPECT_EQ(SkRect::MakeXYWH(0, 0, 800, 600), rect);
- } else if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
- EXPECT_EQ(SkRect::MakeXYWH(0, 0, 800, 600), rect);
} else {
EXPECT_EQ(SkRect::MakeXYWH(scroll_offset.Width(), scroll_offset.Height(),
800, 600),
@@ -129,7 +127,7 @@ TEST_P(ViewPainterTest, DocumentBackgroundWithScroll) {
<div style='height: 5000px'></div>
)HTML");
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_THAT(
RootPaintController().GetDisplayItemList(),
ElementsAre(IsSameId(&GetLayoutView(), DisplayItem::kScrollHitTest),
@@ -210,7 +208,7 @@ TEST_P(ViewPainterTestWithPaintTouchAction, TouchActionRectScrollingContents) {
html_hit_test_data.touch_action_rects.emplace_back(
LayoutRect(0, 0, 800, 3000));
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
HitTestData non_scrolling_hit_test_data;
non_scrolling_hit_test_data.touch_action_rects.emplace_back(
LayoutRect(0, 0, 800, 600));
@@ -282,7 +280,7 @@ TEST_P(ViewPainterTestWithPaintTouchAction,
LayoutRect(0, 0, 800, 3000));
scrolling_hit_test_data.touch_action_rects.emplace_back(
LayoutRect(0, 0, 800, 3000));
- if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
+ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
EXPECT_THAT(
RootPaintController().PaintChunks(),
ElementsAre(