Commit 707023d3 authored by Chris Harrelson's avatar Chris Harrelson Committed by Commit Bot

Fix interest rect computation for squashed layers under transform.

Instead of using one of the squashed layers as the starting point, use
the transformed ancestor, from which we have already computed an offset
to the squashing layer.

As a result, remove the squashing-prevention rule about non-translation
transforms.

Bug: 750433
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I4cf1fc5a2e34d7e40023d4c3481bb517c3b6e72f
Reviewed-on: https://chromium-review.googlesource.com/658335Reviewed-by: default avatarTien-Ren Chen <trchen@chromium.org>
Commit-Queue: Chris Harrelson <chrishtr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#501157}
parent 75074c50
......@@ -105,34 +105,22 @@ After:
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow (relative positioned) DIV class='box gray force-layer'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#808080",
"transform": 4
},
{
"name": "LayoutBlockFlow (relative positioned) DIV id='first-green-box' class='box green rotate-45deg'",
"bounds": [102, 102],
"backgroundColor": "#008000",
"transform": 6
},
{
"name": "Squashing Containment Layer",
"position": [58, 230],
"drawsContent": false
},
{
"name": "LayoutBlockFlow (relative positioned) DIV class='box green rotate-45deg'",
"bounds": [102, 102],
"backgroundColor": "#008000",
"transform": 8
"name": "LayoutBlockFlow (relative positioned) DIV class='box gray force-layer'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#808080",
"transform": 4
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV class='box green')",
"position": [18, 570],
"bounds": [152, 222]
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (relative positioned) DIV id='first-green-box' class='box green rotate-45deg')",
"position": [18, 328],
"bounds": [174, 464]
}
],
"transforms": [
......@@ -157,45 +145,6 @@ After:
},
{
"id": 3,
"transform": [
[...],
[...],
[...],
[...]
]
},
{
"id": 4,
"parent": 3,
"transform": [
[...],
[...],
[...],
[...]
]
},
{
"id": 5,
"transform": [
[...],
[...],
[...],
[...]
]
},
{
"id": 6,
"parent": 5,
"transform": [
[...],
[...],
[...],
[...]
],
"origin": [51, 51]
},
{
"id": 7,
"transform": [
[...],
[...],
......@@ -205,15 +154,14 @@ After:
"flattenInheritedTransform": false
},
{
"id": 8,
"parent": 7,
"id": 4,
"parent": 3,
"transform": [
[...],
[...],
[...],
[...]
],
"origin": [51, 51],
"flattenInheritedTransform": false
}
]
......
......@@ -18,12 +18,9 @@ onload = function() {
if (window.internals) {
var layers = JSON.parse(internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_DEBUG_INFO))["layers"];
// The scale-transform layer can't be squashed
assert_true(layers[3].compositingReasons[1] == "Layer was separately composited because it could not be squashed.");
assert_true(layers[3].squashingDisallowedReasons[0] == "Cannot squash layers with transforms that are not identity or translation.");
// ...but the translate-transform one can.
assert_true(layers[4].compositingReasons[0] == "Secondary layer, home for a group of squashable content");
// Both transformed layers squash together after the will-change layer.
assert_true(layers[2].compositingReasons[0] == "Has a will-change compositing hint");
assert_true(layers[3].compositingReasons[0] == "Secondary layer, home for a group of squashable content");
}
};
</script>
......@@ -6,28 +6,21 @@
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#0000FF",
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 3
"backgroundColor": "#0000FF",
"transform": 1
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [-1, -1],
"bounds": [281, 281]
}
],
"transforms": [
......@@ -38,28 +31,7 @@
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.707106781186548, 0.707106781186548, 0, 0],
[-0.707106781186548, 0.707106781186548, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
]
......
......@@ -7,28 +7,21 @@ CASE 1, original layer tree
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#0000FF",
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 3
"backgroundColor": "#0000FF",
"transform": 1
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [-1, -1],
"bounds": [281, 281]
}
],
"transforms": [
......@@ -39,29 +32,8 @@ CASE 1, original layer tree
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.707106781186548, 0.707106781186548, 0, 0],
[-0.707106781186548, 0.707106781186548, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
]
}
......@@ -74,6 +46,10 @@ CASE 2, hovering over the outer div
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
......@@ -82,27 +58,16 @@ CASE 2, hovering over the outer div
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#008000",
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [-1, -1],
"bounds": [281, 281],
"paintInvalidations": [
{
"object": "LayoutBlockFlow (positioned) DIV class='box middle'",
"rect": [0, 0, 100, 100],
"rect": [0, 0, 142, 142],
"reason": "style change"
}
],
"transform": 3
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
]
}
],
"transforms": [
......@@ -113,29 +78,8 @@ CASE 2, hovering over the outer div
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.707106781186548, 0.707106781186548, 0, 0],
[-0.707106781186548, 0.707106781186548, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
],
"objectPaintInvalidations": [
......@@ -154,6 +98,10 @@ CASE 3, hovering over the inner div
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
......@@ -162,32 +110,21 @@ CASE 3, hovering over the inner div
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#008000",
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [-1, -1],
"bounds": [281, 281],
"paintInvalidations": [
{
"object": "LayoutBlockFlow (positioned) DIV class='box middle'",
"rect": [0, 0, 100, 100],
"rect": [0, 0, 142, 142],
"reason": "style change"
},
{
"object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
"rect": [20, 25, 50, 50],
"rect": [32, 32, 71, 71],
"reason": "style change"
}
],
"transform": 3
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
]
}
],
"transforms": [
......@@ -198,28 +135,7 @@ CASE 3, hovering over the inner div
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.707106781186548, 0.707106781186548, 0, 0],
[-0.707106781186548, 0.707106781186548, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
],
......
......@@ -7,28 +7,21 @@ CASE 1, original layer tree
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#0000FF",
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#00FF00",
"transform": 3
"backgroundColor": "#0000FF",
"transform": 1
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [4, 4],
"bounds": [276, 276]
}
],
"transforms": [
......@@ -39,29 +32,8 @@ CASE 1, original layer tree
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.927183854566787, 0.374606593415912, 0, 0],
[-0.374606593415912, 0.927183854566787, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
]
}
......@@ -74,6 +46,10 @@ CASE 2, hovering over the outer div
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
......@@ -82,27 +58,16 @@ CASE 2, hovering over the outer div
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#008000",
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [4, 4],
"bounds": [276, 276],
"paintInvalidations": [
{
"object": "LayoutBlockFlow (positioned) DIV class='box middle'",
"rect": [0, 0, 100, 100],
"rect": [0, 0, 132, 132],
"reason": "style change"
}
],
"transform": 3
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
]
}
],
"transforms": [
......@@ -113,29 +78,8 @@ CASE 2, hovering over the outer div
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.927183854566787, 0.374606593415912, 0, 0],
[-0.374606593415912, 0.927183854566787, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
],
"objectPaintInvalidations": [
......@@ -154,6 +98,10 @@ CASE 3, hovering over the inner div
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='composited box behind'",
"bounds": [100, 100],
......@@ -162,32 +110,21 @@ CASE 3, hovering over the inner div
"transform": 1
},
{
"name": "Squashing Containment Layer",
"drawsContent": false
},
{
"name": "LayoutBlockFlow (positioned) DIV class='box middle'",
"bounds": [100, 100],
"contentsOpaque": true,
"backgroundColor": "#008000",
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box middle')",
"position": [4, 4],
"bounds": [276, 276],
"paintInvalidations": [
{
"object": "LayoutBlockFlow (positioned) DIV class='box middle'",
"rect": [0, 0, 100, 100],
"rect": [0, 0, 132, 132],
"reason": "style change"
},
{
"object": "LayoutBlockFlow (positioned) DIV class='smallbox'",
"rect": [12, 17, 66, 66],
"rect": [19, 21, 85, 86],
"reason": "style change"
}
],
"transform": 3
},
{
"name": "Squashing Layer (first squashed layer: LayoutBlockFlow (positioned) DIV class='box top')",
"position": [180, 180],
"bounds": [100, 100]
]
}
],
"transforms": [
......@@ -198,28 +135,7 @@ CASE 3, hovering over the inner div
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, 100, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[20, 20, 0, 1]
],
"flattenInheritedTransform": false
},
{
"id": 3,
"parent": 2,
"transform": [
[0.927183854566787, 0.374606593415912, 0, 0],
[-0.374606593415912, 0.927183854566787, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
],
"origin": [50, 50],
"flattenInheritedTransform": false
}
],
......
......@@ -3182,28 +3182,24 @@ IntRect CompositedLayerMapping::RecomputeInterestRect(
const GraphicsLayer* graphics_layer) const {
FloatRect graphics_layer_bounds(FloatPoint(), graphics_layer->Size());
IntSize offset_from_anchor_layout_object;
FloatSize offset_from_anchor_layout_object;
const LayoutBoxModelObject* anchor_layout_object;
if (graphics_layer == squashing_layer_.get()) {
// TODO(chrishtr): this is a speculative fix for crbug.com/561306. However,
// it should never be the case that m_squashingLayer exists,
// yet m_squashedLayers.size() == 0. There must be a bug elsewhere.
if (squashed_layers_.size() == 0)
return IntRect();
// 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 = &squashed_layers_[0].paint_layer->GetLayoutObject();
anchor_layout_object =
&owning_layer_.EnclosingTransformedAncestor()->GetLayoutObject();
offset_from_anchor_layout_object =
squashed_layers_[0].offset_from_layout_object;
ToFloatSize(FloatPoint(SquashingOffsetFromTransformedAncestor()));
} else {
DCHECK(graphics_layer == graphics_layer_.get() ||
graphics_layer == scrolling_contents_layer_.get());
anchor_layout_object = &owning_layer_.GetLayoutObject();
offset_from_anchor_layout_object = graphics_layer->OffsetFromLayoutObject();
AdjustForCompositedScrolling(graphics_layer,
offset_from_anchor_layout_object);
IntSize offset = graphics_layer->OffsetFromLayoutObject();
AdjustForCompositedScrolling(graphics_layer, offset);
offset_from_anchor_layout_object = FloatSize(offset);
}
// Start with the bounds of the graphics layer in the space of the anchor
......@@ -3226,12 +3222,12 @@ IntRect CompositedLayerMapping::RecomputeInterestRect(
FloatRect visible_content_rect(graphics_layer_bounds_in_root_view_space);
root_view->GetFrameView()->ClipPaintRect(&visible_content_rect);
IntRect enclosing_graphics_layer_bounds(
FloatRect enclosing_graphics_layer_bounds(
EnclosingIntRect(graphics_layer_bounds));
// Map the visible content rect from root view space to local graphics layer
// space.
IntRect local_interest_rect;
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()) {
......@@ -3257,7 +3253,7 @@ IntRect CompositedLayerMapping::RecomputeInterestRect(
local_interest_rect.Inflate(kPixelDistanceToRecord);
local_interest_rect.Intersect(enclosing_graphics_layer_bounds);
}
return local_interest_rect;
return EnclosingIntRect(local_interest_rect);
}
static const int kMinimumDistanceBeforeRepaint = 512;
......
......@@ -278,7 +278,7 @@ class CORE_EXPORT CompositedLayerMapping final : public GraphicsLayerClient {
LayoutSize ContentOffsetInCompositingLayer() const;
LayoutPoint SquashingOffsetFromTransformedAncestor() {
LayoutPoint SquashingOffsetFromTransformedAncestor() const {
return squashing_layer_offset_from_transformed_ancestor_;
}
......
......@@ -184,9 +184,6 @@ CompositingLayerAssigner::GetReasonsPreventingSquashing(
if (layer->TransformAncestor() != squashing_layer.TransformAncestor())
return kSquashingDisallowedReasonTransformAncestorMismatch;
if (layer->Transform() && !layer->Transform()->IsIdentityOrTranslation())
return kSquashingDisallowedReasonNonTranslationTransform;
if (layer->RenderingContextRoot() != squashing_layer.RenderingContextRoot())
return kSquashingDisallowedReasonRenderingContextMismatch;
......
......@@ -62,10 +62,6 @@ const SquashingDisallowedReasonStringMap kSquashingDisallowedReasonStringMap[] =
{kSquashingDisallowedReasonRenderingContextMismatch,
"squashingLayerRenderingContextMismatch",
"Cannot squash layers with different 3D contexts."},
{kSquashingDisallowedReasonNonTranslationTransform,
"SquashingDisallowedReasonNonTranslationTransform",
"Cannot squash layers with transforms that are not identity or "
"translation."},
{kSquashingDisallowedReasonFragmentedContent,
"SquashingDisallowedReasonFragmentedContent",
"Cannot squash layers that are inside fragmentation contexts."},
......
......@@ -28,8 +28,7 @@ enum SquashingDisallowedReason {
kSquashingDisallowedReasonScrollChildWithCompositedDescendants = 1 << 12,
kSquashingDisallowedReasonSquashingLayerIsAnimating = 1 << 13,
kSquashingDisallowedReasonRenderingContextMismatch = 1 << 14,
kSquashingDisallowedReasonNonTranslationTransform = 1 << 15,
kSquashingDisallowedReasonFragmentedContent = 1 << 16,
kSquashingDisallowedReasonFragmentedContent = 1 << 15,
};
typedef unsigned SquashingDisallowedReasons;
......
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