Commit 800e5135 authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Fork UpdateVisualRect loop for when selected

As Finch indicated pre-paint is slower in NG, this patch
splits the loop to compute VisualRect for fragments for when
there's a selection for the LayoutObject and for when not.

By splitting the loop, not only reducing the work within the
loop, we could try to apply simplication of VisualRect for
inline fragments as legacy does.

For the branch when there is a selection, yoichio@ will look
into it after the end of January.

Bug: 636993
Change-Id: Ia06ad95e0cd7e0e9f2d663d26ee2fc7702c05908
Reviewed-on: https://chromium-review.googlesource.com/c/1405948Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Emil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#622078}
parent 7d0e7076
...@@ -162,8 +162,7 @@ LayoutRect PaintInvalidator::ComputeVisualRect( ...@@ -162,8 +162,7 @@ LayoutRect PaintInvalidator::ComputeVisualRect(
static LayoutRect ComputeFragmentLocalSelectionRect( static LayoutRect ComputeFragmentLocalSelectionRect(
const NGPaintFragment& fragment) { const NGPaintFragment& fragment) {
if (!fragment.PhysicalFragment().IsText()) DCHECK(fragment.PhysicalFragment().IsText());
return LayoutRect();
const FrameSelection& frame_selection = const FrameSelection& frame_selection =
fragment.GetLayoutObject()->GetFrame()->Selection(); fragment.GetLayoutObject()->GetFrame()->Selection();
const LayoutSelectionStatus status = const LayoutSelectionStatus status =
...@@ -342,26 +341,46 @@ void PaintInvalidator::UpdateVisualRect(const LayoutObject& object, ...@@ -342,26 +341,46 @@ void PaintInvalidator::UpdateVisualRect(const LayoutObject& object,
// VisualRect for each fragment from |new_visual_rect|. // VisualRect for each fragment from |new_visual_rect|.
auto fragments = NGPaintFragment::InlineFragmentsFor(&object); auto fragments = NGPaintFragment::InlineFragmentsFor(&object);
if (fragments.IsInLayoutNGInlineFormattingContext()) { if (fragments.IsInLayoutNGInlineFormattingContext()) {
for (NGPaintFragment* fragment : fragments) { bool has_selection_in_this_object =
LayoutRect local_selection_rect = object.IsText() && ToLayoutText(object).IsSelected();
ComputeFragmentLocalSelectionRect(*fragment); if (!has_selection_in_this_object) {
LayoutRect local_visual_rect = for (NGPaintFragment* fragment : fragments) {
UnionRect(fragment->SelfInkOverflow(), local_selection_rect); LayoutRect local_visual_rect = fragment->SelfInkOverflow();
fragment->SetVisualRect(MapFragmentLocalRectToVisualRect( fragment->SetVisualRect(MapFragmentLocalRectToVisualRect(
local_visual_rect, object, *fragment, context)); local_visual_rect, object, *fragment, context));
LayoutRect selection_visual_rect = MapFragmentLocalRectToVisualRect( if (UNLIKELY(!fragment->SelectionVisualRect().IsEmpty())) {
local_selection_rect, object, *fragment, context); context.painting_layer->SetNeedsRepaint();
const bool should_invalidate = ObjectPaintInvalidator(object).InvalidateDisplayItemClient(
object.ShouldInvalidateSelection() || *fragment, PaintInvalidationReason::kSelection);
selection_visual_rect != fragment->SelectionVisualRect(); fragment->SetSelectionVisualRect(LayoutRect());
const bool rect_exists = !selection_visual_rect.IsEmpty() || }
!fragment->SelectionVisualRect().IsEmpty(); }
if (should_invalidate && rect_exists) { } else {
context.painting_layer->SetNeedsRepaint(); // TODO(kojii): It's not clear why we need to pre-compute selection rect
ObjectPaintInvalidator(object).InvalidateDisplayItemClient( // for all fragments when legacy can handle it as needed. yoichio will
*fragment, PaintInvalidationReason::kSelection); // look into this.
fragment->SetSelectionVisualRect(selection_visual_rect); 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);
}
} }
} }
} }
......
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