Skip to content

Commit

Permalink
Compute a fragmented offset for control clips of input boxes.
Browse files Browse the repository at this point in the history
Boxes without control clips don't necessarily have PaintLayers,
so in the current code are not necessarily fragmented. (*)
Such boxes should only end up in one fragment, because fragmenting
input elements or buttons doesn't make sense.

This patch computes the position of that fragment, and places
the control clip at that location.

(*) This is being changed in another much bigger patch, but
this bugfix is needed for M63.

TBR=chrishtr@chromium.org

(cherry picked from commit 945b31d)

Bug: 772850
Change-Id: I187d3dcf9c0dea2b7703dd759bf8b5f2886d4e2e
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Reviewed-on: https://chromium-review.googlesource.com/720200
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Reviewed-by: Tien-Ren Chen <trchen@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#508952}
Reviewed-on: https://chromium-review.googlesource.com/721759
Reviewed-by: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/branch-heads/3239@{#11}
Cr-Branched-From: adb61db-refs/heads/master@{#508578}
  • Loading branch information
chrishtr committed Oct 16, 2017
1 parent d20475e commit 800203e
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,8 @@ Bug(none) images/cross-fade-invalidation.html [ Crash Failure Pass ]
Bug(none) paint/pagination/pagination-change-clip-crash.html [ Failure ]
Bug(none) paint/selection/text-selection-newline-mixed-ltr-rtl.html [ Failure ]

Bug(none) fast/multicol/input-with-overflow-second-column.html [ Failure ]

# Less invalidations or different invalidations without pixel failures.
# Some might be good. Some might be under-invalidations for which under-invalidation
# checking failed.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
layer at (0,0) size 800x600
LayoutView at (0,0) size 800x600
layer at (0,0) size 800x58
LayoutBlockFlow {HTML} at (0,0) size 800x58
LayoutBlockFlow {BODY} at (8,8) size 784x42
LayoutBlockFlow (anonymous) at (0,0) size 784x20
LayoutText {#text} at (0,0) size 663x19
text run at (0,0) width 663: "Passes if there is some \"testtest..\" content inside of an input box, shifted to the right into a second column."
layer at (8,28) size 784x22
LayoutBlockFlow {DIV} at (0,20) size 784x22
LayoutMultiColumnSet (anonymous) at (0,0) size 784x22
layer at (8,28) size 117x88
LayoutMultiColumnFlowThread (anonymous) at (0,0) size 117.33x88
LayoutBlockFlow {DIV} at (0,0) size 117.33x50
LayoutBlockFlow (anonymous) at (0,66) size 117.33x22
LayoutTextControl {INPUT} at (0,0) size 64x22 [bgcolor=#FFFFFF] [border: (2px inset #EEEEEE)]
LayoutText {#text} at (0,0) size 0x0
layer at (10,97) size 60x16 scrollWidth 111
LayoutBlockFlow {DIV} at (2,3) size 60x16
LayoutText {#text} at (0,0) size 110x16
text run at (0,0) width 110: "testtesttesttesttest"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!doctype HTML>
Passes if there is some "testtest.." content inside of an input box,
shifted to the right into a second column.
<div style="column-width: 100px;">
<div style="height: 50px;"></div>
<input type="text" value='testtesttesttesttest' size=5/>
</div>


Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 84 additions & 31 deletions third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,11 @@ static bool NeedsOverflowClip(const LayoutObject& object) {
return object.IsBox() && ToLayoutBox(object).ShouldClipOverflow();
}

static bool NeedsControlClipFragmentationAdjustment(const LayoutBox& box) {
return box.HasControlClip() && !box.Layer() &&
box.PaintingLayer()->EnclosingPaginationLayer();
}

void PaintPropertyTreeBuilder::UpdateOverflowClip(
const LayoutObject& object,
ObjectPaintProperties& properties,
Expand All @@ -951,6 +956,33 @@ void PaintPropertyTreeBuilder::UpdateOverflowClip(
if (context.fragment_clip_context) {
clip_rect =
box.OverflowClipRect(context.fragment_clip_context->paint_offset);
} else if (NeedsControlClipFragmentationAdjustment(box)) {
PaintLayer* painting_layer = box.PaintingLayer();
// TODO(chrishtr): remove this workaround once non-PaintLayers can
// fragment.
LayoutRect object_bounding_box_in_flow_thread =
box.OverflowClipRect(LayoutPoint());
object_bounding_box_in_flow_thread.Move(
object.OffsetFromAncestorContainer(
&painting_layer->EnclosingPaginationLayer()
->GetLayoutObject()));

const LayoutFlowThread& flow_thread = ToLayoutFlowThread(
painting_layer->EnclosingPaginationLayer()->GetLayoutObject());
FragmentainerIterator iterator(flow_thread,
object_bounding_box_in_flow_thread);

LayoutPoint offset = context.current.paint_offset;
if (!iterator.AtEnd()) {
offset = object_bounding_box_in_flow_thread.Location();
offset.Move(iterator.PaginationOffset());
offset.MoveBy(painting_layer->EnclosingPaginationLayer()
->VisualOffsetFromAncestor(
context.current.paint_offset_root->Layer()));
iterator.Advance();
}

clip_rect = box.OverflowClipRect(offset);
} else {
clip_rect = box.OverflowClipRect(context.current.paint_offset);
}
Expand Down Expand Up @@ -1312,6 +1344,57 @@ static inline LayoutPoint VisualOffsetFromPaintOffsetRoot(
return result;
}

static void SetNeedsPaintPropertyUpdateIfNeeded(const LayoutObject& object) {
if (!object.IsBoxModelObject())
return;

const LayoutBoxModelObject& box_model_object = ToLayoutBoxModelObject(object);
if (box_model_object.Layer() &&
box_model_object.Layer()->ShouldFragmentCompositedBounds()) {
// Always force-update properties for fragmented content.
// TODO(chrishtr): find ways to optimize this in the future.
// It may suffice to compare previous and current visual overflow,
// but we do not currenly cache that on the LayoutObject or PaintLayer.
object.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
return;
}

if (!object.IsBox())
return;

const LayoutBox& box = ToLayoutBox(object);

// Always force-update properties for fragmented content. Boxes with
// control clip have a fragment-aware offset.
if (NeedsControlClipFragmentationAdjustment(box)) {
box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
return;
}

if (box.Size() == box.PreviousSize())
return;

// CSS mask and clip-path comes with an implicit clip to the border box.
// Currently only SPv2 generate and take advantage of those.
const bool box_generates_property_nodes_for_mask_and_clip_path =
RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
(box.HasMask() || box.HasClipPath());
// The overflow clip paint property depends on the border box rect through
// overflowClipRect(). The border box rect's size equals the frame rect's
// size so we trigger a paint property update when the frame rect changes.
if (box.ShouldClipOverflow() ||
// The used value of CSS clip may depend on size of the box, e.g. for
// clip: rect(auto auto auto -5px).
box.HasClip() ||
// Relative lengths (e.g., percentage values) in transform, perspective,
// transform-origin, and perspective-origin can depend on the size of the
// frame rect, so force a property update if it changes. TODO(pdr): We
// only need to update properties if there are relative lengths.
box.StyleRef().HasTransform() || box.StyleRef().HasPerspective() ||
box_generates_property_nodes_for_mask_and_clip_path)
box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
}

void PaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
const LayoutObject& object,
const LayoutObject* container_for_absolute_position,
Expand Down Expand Up @@ -1371,31 +1454,7 @@ void PaintPropertyTreeBuilder::UpdateForObjectLocationAndSize(
if (paint_offset_translation)
context.current.paint_offset_root = &ToLayoutBoxModelObject(object);

if (!object.IsBox())
return;
const LayoutBox& box = ToLayoutBox(object);
if (box.Size() == box.PreviousSize())
return;

// CSS mask and clip-path comes with an implicit clip to the border box.
// Currently only SPv2 generate and take advantage of those.
const bool box_generates_property_nodes_for_mask_and_clip_path =
RuntimeEnabledFeatures::SlimmingPaintV175Enabled() &&
(box.HasMask() || box.HasClipPath());
// The overflow clip paint property depends on the border box rect through
// overflowClipRect(). The border box rect's size equals the frame rect's
// size so we trigger a paint property update when the frame rect changes.
if (box.ShouldClipOverflow() ||
// The used value of CSS clip may depend on size of the box, e.g. for
// clip: rect(auto auto auto -5px).
box.HasClip() ||
// Relative lengths (e.g., percentage values) in transform, perspective,
// transform-origin, and perspective-origin can depend on the size of the
// frame rect, so force a property update if it changes. TODO(pdr): We
// only need to update properties if there are relative lengths.
box.StyleRef().HasTransform() || box.StyleRef().HasPerspective() ||
box_generates_property_nodes_for_mask_and_clip_path)
box.GetMutableForPainting().SetNeedsPaintPropertyUpdate();
SetNeedsPaintPropertyUpdateIfNeeded(object);
}

// Match |fragment_clip| against an intersecting one from the parent contexts,
Expand Down Expand Up @@ -1480,12 +1539,6 @@ void PaintPropertyTreeBuilder::UpdateFragments(
PaintLayer* enclosing_pagination_layer =
paint_layer->EnclosingPaginationLayer();

// Always force-update properties for fragmented content.
// TODO(chrishtr): find ways to optimize this in the future.
// It may suffice to compare previous and current visual overflow,
// but we do not currenly cache that on the LayoutObject or PaintLayer.
object.GetMutableForPainting().SetNeedsPaintPropertyUpdate();

LayoutPoint offset_within_paginated_layer;
paint_layer->ConvertToLayerCoords(enclosing_pagination_layer,
offset_within_paginated_layer);
Expand Down

0 comments on commit 800203e

Please sign in to comment.