Commit 6c4ebf12 authored by Philip Rogers's avatar Philip Rogers Committed by Commit Bot

Ensure line box hit testing is invalidated on compositing changes

LayoutNG paints hit test display items with NGPhysicalLineBoxFragment
display item clients in NGBoxFragmentPainter::PaintLineBox. With this
patch, these line box fragments are now invalidated via the block flow
invalidation. This fixes touch-rect-crash-on-unpromote-layer.html with
CompositeAfterPaint.

Change-Id: Id1c1961d2acdfe5638134f9b3e44dcaeae6a65cc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1984874Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728189}
parent 039980d1
...@@ -674,7 +674,20 @@ TEST_P(ScrollingTest, touchActionOnInline) { ...@@ -674,7 +674,20 @@ TEST_P(ScrollingTest, touchActionOnInline) {
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction( cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
TouchAction::kNone); TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 80, 50)); EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 120, 50));
}
TEST_P(ScrollingTest, touchActionOnText) {
RegisterMockedHttpURLLoad("touch-action-on-text.html");
NavigateTo(base_url_ + "touch-action-on-text.html");
LoadAhem();
ForceFullCompositingUpdate();
const auto* cc_layer = MainFrameScrollingContentsLayer();
cc::Region region = cc_layer->touch_action_region().GetRegionForTouchAction(
TouchAction::kNone);
EXPECT_EQ(region.bounds(), gfx::Rect(8, 8, 160, 30));
} }
TEST_P(ScrollingTest, touchActionWithVerticalRLWritingMode) { TEST_P(ScrollingTest, touchActionWithVerticalRLWritingMode) {
......
...@@ -58,18 +58,32 @@ void BlockFlowPaintInvalidator::InvalidateDisplayItemClients( ...@@ -58,18 +58,32 @@ void BlockFlowPaintInvalidator::InvalidateDisplayItemClients(
reason == PaintInvalidationReason::kSelection) reason == PaintInvalidationReason::kSelection)
return; return;
// It's the RootInlineBox that paints the ::first-line background. Note that
// since it may be expensive to figure out if the first line is affected by
// any ::first-line selectors at all, we just invalidate it unconditionally
// which is typically cheaper.
if (RootInlineBox* line = block_flow_.FirstRootBox()) { if (RootInlineBox* line = block_flow_.FirstRootBox()) {
// It's the RootInlineBox that paints the ::first-line background. Note that
// since it may be expensive to figure out if the first line is affected by
// any ::first-line selectors at all, we just invalidate it unconditionally
// which is typically cheaper.
if (line->IsFirstLineStyle()) { if (line->IsFirstLineStyle()) {
object_paint_invalidator.InvalidateDisplayItemClient(*line, reason); object_paint_invalidator.InvalidateDisplayItemClient(*line, reason);
} }
} else if (paint_fragment) { } else if (paint_fragment) {
NGPaintFragment* line = paint_fragment->FirstLineBox(); // The first line NGLineBoxFragment paints the ::first-line background.
if (line && line->PhysicalFragment().UsesFirstLineStyle()) { // Because it may be expensive to figure out if the first line is affected
object_paint_invalidator.InvalidateDisplayItemClient(*line, reason); // by any ::first-line selectors at all, we just invalidate unconditionally
// which is typically cheaper.
if (NGPaintFragment* line = paint_fragment->FirstLineBox()) {
if (line->PhysicalFragment().UsesFirstLineStyle())
object_paint_invalidator.InvalidateDisplayItemClient(*line, reason);
}
// Line boxes paint hit test display items (see:
// NGBoxFragmentPainter::PaintLineBox) and should be invalidated if they
// change.
if (block_flow_.HasEffectiveAllowedTouchAction()) {
for (NGPaintFragment* line : paint_fragment->Children()) {
if (line->PhysicalFragment().IsLineBox())
object_paint_invalidator.InvalidateDisplayItemClient(*line, reason);
}
} }
} }
......
...@@ -193,6 +193,27 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonBasic) { ...@@ -193,6 +193,27 @@ TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonBasic) {
box, visual_rect, visual_rect.Location() + IntSize(10, 20))); box, visual_rect, visual_rect.Location() + IntSize(10, 20)));
} }
TEST_P(BoxPaintInvalidatorTest,
InvalidateLineBoxHitTestOnCompositingStyleChange) {
ScopedPaintUnderInvalidationCheckingForTest under_invalidation_checking(true);
SetBodyInnerHTML(R"HTML(
<style>
#target {
width: 100px;
height: 100px;
touch-action: none;
}
</style>
<div id="target" style="will-change: transform;">a<br>b</div>
)HTML");
UpdateAllLifecyclePhasesForTest();
auto& target = *GetDocument().getElementById("target");
target.setAttribute(html_names::kStyleAttr, "");
UpdateAllLifecyclePhasesForTest();
// This test passes if no underinvalidation occurs.
}
TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOtherCases) { TEST_P(BoxPaintInvalidatorTest, ComputePaintInvalidationReasonOtherCases) {
SetUpHTML(); SetUpHTML();
auto& target = *GetDocument().getElementById("target"); auto& target = *GetDocument().getElementById("target");
......
...@@ -1043,8 +1043,8 @@ void NGBoxFragmentPainter::PaintInlineItems(const PaintInfo& paint_info, ...@@ -1043,8 +1043,8 @@ void NGBoxFragmentPainter::PaintInlineItems(const PaintInfo& paint_info,
} }
} }
// Paint a line box. This function paints only background of `::first-line`. In // Paint a line box. This function paints hit tests and backgrounds of
// all other cases, the container box paints background. // `::first-line`. In all other cases, the container box paints background.
inline void NGBoxFragmentPainter::PaintLineBox( inline void NGBoxFragmentPainter::PaintLineBox(
const NGPhysicalFragment& line_box_fragment, const NGPhysicalFragment& line_box_fragment,
const DisplayItemClient& display_item_client, const DisplayItemClient& display_item_client,
...@@ -1060,15 +1060,12 @@ inline void NGBoxFragmentPainter::PaintLineBox( ...@@ -1060,15 +1060,12 @@ inline void NGBoxFragmentPainter::PaintLineBox(
RecordHitTestDataForLine(paint_info, child_offset, line_box_fragment, RecordHitTestDataForLine(paint_info, child_offset, line_box_fragment,
display_item_client); display_item_client);
} }
if (NGLineBoxFragmentPainter::NeedsPaint(line_box_fragment)) {
// Line boxes don't paint anything, except when its ::first-line style has NGLineBoxFragmentPainter line_box_painter(
// a background. line_box_fragment, line_box_paint_fragment, line_box_item,
if (!NGLineBoxFragmentPainter::NeedsPaint(line_box_fragment)) PhysicalFragment(), paint_fragment_);
return; line_box_painter.PaintBackgroundBorderShadow(paint_info, child_offset);
NGLineBoxFragmentPainter line_box_painter( }
line_box_fragment, line_box_paint_fragment, line_box_item,
PhysicalFragment(), paint_fragment_);
line_box_painter.PaintBackgroundBorderShadow(paint_info, child_offset);
} }
void NGBoxFragmentPainter::PaintLineBoxChildren( void NGBoxFragmentPainter::PaintLineBoxChildren(
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
<style> <style>
div { width: 10px; height: 50px; touch-action: none; font: 10px Ahem; } div { width: 10px; height: 50px; touch-action: none; font: 10px Ahem; }
</style> </style>
<div>aaaaaaaa</div> <div>aaaa<span>aaaaaaaa</span></div>
<!DOCTYPE html>
<style>
div { width: 10px; height: 20px; touch-action: none; font: 10px Ahem; }
</style>
<div>aaaaaaaa<br>aaaa<br>aaaaaaaaaaaaaaaa</div>
...@@ -124,9 +124,6 @@ paint/invalidation/compositing/should-invoke-deferred-compositing.html [ Failure ...@@ -124,9 +124,6 @@ paint/invalidation/compositing/should-invoke-deferred-compositing.html [ Failure
paint/invalidation/scroll/overflow-hidden-yet-scrolled-with-custom-scrollbar.html [ Failure ] paint/invalidation/scroll/overflow-hidden-yet-scrolled-with-custom-scrollbar.html [ Failure ]
paint/invalidation/scroll/overflow-hidden-yet-scrolled.html [ Failure ] paint/invalidation/scroll/overflow-hidden-yet-scrolled.html [ Failure ]
# Under-invalidation
fast/events/touch/touch-rect-crash-on-unpromote-layer.html [ Crash ]
# "Missing" raster invalidation because composited layers are re-created. # "Missing" raster invalidation because composited layers are re-created.
crbug.com/842356 paint/invalidation/compositing/containing-block-added-individual.html [ Failure ] crbug.com/842356 paint/invalidation/compositing/containing-block-added-individual.html [ Failure ]
crbug.com/842356 paint/invalidation/compositing/containing-block-added.html [ Failure ] crbug.com/842356 paint/invalidation/compositing/containing-block-added.html [ Failure ]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment