Commit 91c206e0 authored by Xianzhu Wang's avatar Xianzhu Wang Committed by Chromium LUCI CQ

Revert "Add CullRect::ApplyPaintProperties()"

This reverts commit 6f895b07.

Reason for revert: The reverted CL is supposed not to affect
production, but it seems to cause crbug.com/1166540.

Original change's description:
> Add CullRect::ApplyPaintProperties()
>
> It will be called to map a cull rect from parent space to local space
> in cull rect update during PrePaint. The purpose is to mark PaintLayers
> needing repaint on cull rect changes before paint, instead of checking
> interest rect / cull rect changes during paint, to avoid setting
> PaintLayer needing repaint unnecessarily, especially for CAP during
> composited scrolling.
>
> Besides the original features of CullRect::ApplyTransforms() which is
> used in cull rect mapping for CompositeAfterPaint, it also implements
> the following features to be on par with CompositedLayerMapping::
> ReComputeInterestRect():
>
> - Considering clips in additional to scroll clips,
> - Clipping expanded cull rect by scrolling contents rect for composited
>   scroll translations,
> - Clamping extreme geometry values,
> - Adaptive expansion distance for composited transforms.
>
> The next steps are:
> 1. Add CullRectUpdater which updates cull rects during PrePaint when
>    runtime feature CullRectUpdate is enabled.
> 2. Use the updated cull rect to replace interest rect in pre-CAP and
>    cull rect in CAP and pre-CAP, still behind the runtime feature.
> 3. Enable CullRectUpdate for CAP
> 4. Enable CullRectUpdate for pre-CAP.
> 5. Remove old interest rect / cull rect code.
>
> Bug: 1046544
> Change-Id: I6e7e9f85bc0b4640e67de1732744e647b6f7e230
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2620090
> Reviewed-by: Philip Rogers <pdr@chromium.org>
> Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#843304}

TBR=szager@chromium.org,wangxianzhu@chromium.org,pdr@chromium.org,chromium-scoped@luci-project-accounts.iam.gserviceaccount.com

Change-Id: Idc3374d3d426b9f571e417b1acbbc18227fdf274
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 1046544, 1166540
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2628021Reviewed-by: default avatarXianzhu Wang <wangxianzhu@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#843592}
parent d36ee928
......@@ -421,14 +421,19 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
EXPECT_THAT(ContentDisplayItems(),
ElementsAre(VIEW_SCROLLING_BACKGROUND_DISPLAY_ITEM,
IsSameId(content1, kBackgroundType)));
EXPECT_EQ(IntRect(0, 0, 800, 4600), target_layer->PreviousCullRect().Rect());
auto chunks = ContentPaintChunks();
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());
// |target| still created subsequence (cached).
EXPECT_SUBSEQUENCE_FROM_CHUNK(*target_layer, chunks.begin() + 1, 2);
EXPECT_THAT(chunks, ElementsAre(VIEW_SCROLLING_BACKGROUND_CHUNK_COMMON,
IsPaintChunk(1, 1), IsPaintChunk(1, 2)));
} else {
EXPECT_EQ(CullRect(IntRect(0, 0, 800, 4600)),
target_layer->PreviousCullRect());
EXPECT_THAT(ContentDisplayItems(),
ElementsAre(VIEW_SCROLLING_BACKGROUND_DISPLAY_ITEM,
IsSameId(content1, kBackgroundType)));
......@@ -454,9 +459,12 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
EXPECT_THAT(ContentDisplayItems(),
ElementsAre(VIEW_SCROLLING_BACKGROUND_DISPLAY_ITEM,
IsSameId(content1, kBackgroundType)));
EXPECT_EQ(IntRect(0, 0, 800, 4600), target_layer->PreviousCullRect().Rect());
chunks = ContentPaintChunks();
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());
EXPECT_THAT(ContentDisplayItems(),
ElementsAre(VIEW_SCROLLING_BACKGROUND_DISPLAY_ITEM,
IsSameId(content1, kBackgroundType)));
......@@ -465,6 +473,8 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
EXPECT_THAT(chunks, ElementsAre(VIEW_SCROLLING_BACKGROUND_CHUNK_COMMON,
IsPaintChunk(1, 1), IsPaintChunk(1, 2)));
} else {
EXPECT_EQ(CullRect(IntRect(0, 0, 800, 4600)),
target_layer->PreviousCullRect());
// |target| still created subsequence (cached).
EXPECT_SUBSEQUENCE_FROM_CHUNK(*target_layer, chunks.begin() + 1, 1);
EXPECT_THAT(chunks, ElementsAre(VIEW_SCROLLING_BACKGROUND_CHUNK_COMMON,
......@@ -491,14 +501,19 @@ TEST_P(PaintLayerPainterTest, CachedSubsequenceRetainsPreviousPaintResult) {
ElementsAre(VIEW_SCROLLING_BACKGROUND_DISPLAY_ITEM,
IsSameId(content1, kBackgroundType),
IsSameId(content2, kBackgroundType)));
EXPECT_EQ(IntRect(0, 0, 800, 7600), target_layer->PreviousCullRect().Rect());
chunks = ContentPaintChunks();
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, -1000, 8800, 8600)),
target_layer->PreviousCullRect());
// |target| still created subsequence (repainted).
EXPECT_SUBSEQUENCE_FROM_CHUNK(*target_layer, chunks.begin() + 1, 2);
EXPECT_THAT(chunks, ElementsAre(VIEW_SCROLLING_BACKGROUND_CHUNK_COMMON,
IsPaintChunk(1, 1), IsPaintChunk(1, 3)));
} else {
EXPECT_EQ(CullRect(IntRect(0, 0, 800, 7600)),
target_layer->PreviousCullRect());
// |target| still created subsequence (repainted).
EXPECT_SUBSEQUENCE_FROM_CHUNK(*target_layer, chunks.begin() + 1, 1);
EXPECT_THAT(chunks, ElementsAre(VIEW_SCROLLING_BACKGROUND_CHUNK_COMMON,
......@@ -1042,9 +1057,8 @@ TEST_P(PaintLayerPainterTestCAP, TallLayerCullRect) {
</div>
)HTML");
// Viewport rect (0, 0, 800, 600) expanded by 4000 for scrolling then clipped
// by the contents rect.
EXPECT_EQ(IntRect(0, 0, 800, 4600),
// Viewport rect (0, 0, 800, 600) expanded by 4000 for scrolling.
EXPECT_EQ(IntRect(-4000, -4000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1056,7 +1070,7 @@ TEST_P(PaintLayerPainterTestCAP, WideLayerCullRect) {
)HTML");
// Same as TallLayerCullRect.
EXPECT_EQ(IntRect(0, 0, 4800, 600),
EXPECT_EQ(IntRect(-4000, -4000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1066,29 +1080,28 @@ TEST_P(PaintLayerPainterTestCAP, TallScrolledLayerCullRect) {
</div>
)HTML");
// Viewport rect (0, 0, 800, 600) expanded by 4000 for scrolling then clipped
// by the contents rect.
EXPECT_EQ(IntRect(0, 0, 800, 4600),
// Viewport rect (0, 0, 800, 600) expanded by 4000.
EXPECT_EQ(IntRect(-4000, -4000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, 4000), mojom::blink::ScrollType::kProgrammatic);
ScrollOffset(0, 6000), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
EXPECT_EQ(IntRect(0, 0, 800, 8600),
EXPECT_EQ(IntRect(-4000, 2000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, 4500), mojom::blink::ScrollType::kProgrammatic);
ScrollOffset(0, 6500), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Used the previous cull rect because the scroll amount is small.
EXPECT_EQ(IntRect(0, 0, 800, 8600),
EXPECT_EQ(IntRect(-4000, 2000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
GetDocument().View()->LayoutViewport()->SetScrollOffset(
ScrollOffset(0, 4600), mojom::blink::ScrollType::kProgrammatic);
ScrollOffset(0, 6600), mojom::blink::ScrollType::kProgrammatic);
UpdateAllLifecyclePhasesForTest();
// Used new cull rect.
EXPECT_EQ(IntRect(0, 600, 800, 8600),
EXPECT_EQ(IntRect(-4000, 2600, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1123,7 +1136,7 @@ TEST_P(PaintLayerPainterTestCAP, WholeDocumentCullRect) {
// Cull rect is normal for contents below scroll other than the viewport.
EXPECT_EQ(
IntRect(0, 0, 200, 4200),
IntRect(-4000, -4000, 8200, 8200),
GetPaintLayerByElementId("below-scroll")->PreviousCullRect().Rect());
EXPECT_THAT(ContentDisplayItems(),
......@@ -1161,30 +1174,22 @@ TEST_P(PaintLayerPainterTestCAP, VerticalRightLeftWritingModeDocument) {
// A scroll by -5000px is equivalent to a scroll by (10000 - 5000 - 800)px =
// 4200px in non-RTL mode. Expanding the resulting rect by 4000px in each
// direction and clipping by the contents rect yields this result.
EXPECT_EQ(IntRect(200, 0, 8800, 600),
// direction yields this result.
EXPECT_EQ(IntRect(200, -4000, 8800, 8600),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
// TODO(wangxianzhu): These tests should correspond to the tests in
// CompositedLayerMapping testing interest rects. However, for now because in
// CompositeAfterPaint we expand cull rect for composited scrollers only, so
// the tests are modified to use composited scrolling. Will change these back to
// their original version when we support expansion for all composited layers.
// Will be done in CullRectUpdate.
TEST_P(PaintLayerPainterTestCAP, ScaledCullRect) {
GetDocument().GetSettings()->SetPreferCompositingToLCDTextEnabled(true);
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
transform: scaleX(2) scaleY(0.5)'>
<div id='target' style='height: 400px; position: relative'></div>
<div style='width: 10000px; height: 10000px'></div>
</div>
)HTML");
// The scale doesn't affect the cull rect.
// TODO(wangxianzhu): actually it should.
EXPECT_EQ(IntRect(0, 0, 4200, 4300),
EXPECT_EQ(IntRect(-4000, -4000, 8200, 8300),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1193,15 +1198,12 @@ TEST_P(PaintLayerPainterTestCAP, ScaledAndRotatedCullRect) {
SetBodyInnerHTML(R"HTML(
<div style='width: 200px; height: 300px; overflow: scroll;
transform: scaleX(2) scaleY(0.5) rotateZ(45deg)'>
<div id='target' style='height: 400px; position: relative;
will-change: transform'></div>
<div style='width: 10000px; height: 10000px'></div>
<div id='target' style='height: 400px; position: relative'></div>
</div>
)HTML");
// The scale and the rotation don't affect the cull rect.
// TODO(wangxianzhu): actually they should.
EXPECT_EQ(IntRect(0, 0, 4200, 4300),
EXPECT_EQ(IntRect(-4000, -4000, 8200, 8300),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1211,13 +1213,12 @@ TEST_P(PaintLayerPainterTestCAP, 3DRotated90DegreesCullRect) {
<div style='width: 200px; height: 300px; overflow: scroll;
transform: rotateY(90deg)'>
<div id='target' style='height: 400px; position: relative'></div>
<div style='width: 10000px; height: 10000px'></div>
</div>
)HTML");
// It's rotated 90 degrees about the X axis, which means its visual content
// rect is empty, we fall back to the 4000px cull rect padding amount.
EXPECT_EQ(IntRect(0, 0, 4200, 4300),
EXPECT_EQ(IntRect(-4000, -4000, 8200, 8300),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1227,7 +1228,6 @@ TEST_P(PaintLayerPainterTestCAP, 3DRotatedNear90DegreesCullRect) {
<div style='width: 200px; height: 300px; overflow: scroll;
transform: rotateY(89.9999deg)'>
<div id='target' style='height: 400px; position: relative'></div>
<div style='width: 10000px; height: 10000px'></div>
</div>
)HTML");
......@@ -1235,7 +1235,7 @@ TEST_P(PaintLayerPainterTestCAP, 3DRotatedNear90DegreesCullRect) {
// leads to a reverse-projected rect that is much much larger than the
// original layer size in certain dimensions. In such cases, we often fall
// back to the 4000px cull rect padding amount.
EXPECT_EQ(IntRect(0, 0, 4200, 4300),
EXPECT_EQ(IntRect(-4000, -4000, 8200, 8300),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1280,11 +1280,10 @@ TEST_P(PaintLayerPainterTestCAP, LayerOffscreenNearCullRect) {
<div style='width: 200px; height: 300px; overflow: scroll;
position: absolute; top: 3000px; left: 0px;'>
<div id='target' style='height: 500px; position: relative'></div>
<div style='width: 10000px; height: 10000px'></div>
</div>
)HTML");
EXPECT_EQ(IntRect(0, 0, 4200, 4300),
EXPECT_EQ(IntRect(-4000, -4000, 8200, 8300),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......@@ -1294,7 +1293,6 @@ TEST_P(PaintLayerPainterTestCAP, LayerOffscreenFarCullRect) {
<div style='width: 200px; height: 300px; overflow: scroll;
position: absolute; top: 9000px'>
<div id='target' style='height: 500px; position: relative'></div>
<div style='width: 10000px; height: 10000px'></div>
</div>
)HTML");
......@@ -1320,9 +1318,8 @@ TEST_P(PaintLayerPainterTestCAP, ScrollingLayerCullRect) {
// of 'target', scrollbar and root margin).
// Applying the viewport clip of the root has no effect because
// the clip is already small. Mapping it down into the graphics layer
// space yields (0, 0, 195, 193). This is then expanded by 4000px and clipped
// by the contents rect.
EXPECT_EQ(IntRect(0, 0, 195, 4193),
// space yields (0, 0, 195, 193). This is then expanded by 4000px.
EXPECT_EQ(IntRect(-4000, -4000, 8195, 8193),
GetPaintLayerByElementId("target")->PreviousCullRect().Rect());
}
......
......@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h"
#include "base/containers/adapters.h"
#include "third_party/blink/renderer/platform/geometry/float_rect.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h"
......@@ -15,30 +14,6 @@
namespace blink {
static constexpr int kReasonablePixelLimit =
std::numeric_limits<int>::max() / 2;
// Returns the number of pixels to expand the cull rect for composited scroll
// and transform.
static int LocalPixelDistanceToExpand(
const TransformPaintPropertyNode& root_transform,
const TransformPaintPropertyNode& local_transform) {
// Number of pixels to expand in root coordinates for cull rect under
// composited scroll translation or other composited transform.
static constexpr int kPixelDistanceToExpand = 4000;
FloatRect rect(0, 0, 1, 1);
GeometryMapper::SourceToDestinationRect(root_transform, local_transform,
rect);
// Now rect.Size() is the size of a screen pixel in local coordinates.
float scale = std::max(rect.Width(), rect.Height());
// A very big scale may be caused by non-invertable near non-invertable
// transforms. Fallback to scale 1. The limit is heuristic.
if (scale > kReasonablePixelLimit / kPixelDistanceToExpand)
return kPixelDistanceToExpand;
return scale * kPixelDistanceToExpand;
}
bool CullRect::Intersects(const IntRect& rect) const {
return IsInfinite() || rect.Intersects(rect_);
}
......@@ -75,54 +50,51 @@ void CullRect::Move(const FloatSize& offset) {
rect_ = EnclosingIntRect(float_rect);
}
void CullRect::ApplyTransform(const TransformPaintPropertyNode& transform) {
if (transform.ScrollNode()) {
DCHECK(!RuntimeEnabledFeatures::CullRectUpdateEnabled());
// TODO(wangxianzhu): Remove this code path for CullRectUpdate.
ApplyScrollTranslation(transform, transform);
static void MapRect(const TransformPaintPropertyNode& transform,
IntRect& rect) {
if (transform.IsIdentityOr2DTranslation()) {
FloatRect float_rect(rect);
float_rect.Move(-transform.Translation2D());
rect = EnclosingIntRect(float_rect);
} else {
ApplyTransformWithoutExpansion(transform);
rect = transform.MatrixWithOriginApplied().Inverse().MapRect(rect);
}
}
void CullRect::ApplyTransformWithoutExpansion(
CullRect::ApplyTransformResult CullRect::ApplyTransformInternal(
const TransformPaintPropertyNode& transform) {
if (IsInfinite())
return;
DCHECK(transform.Parent());
GeometryMapper::SourceToDestinationRect(*transform.Parent(), transform,
rect_);
}
CullRect::ApplyTransformResult CullRect::ApplyScrollTranslation(
const TransformPaintPropertyNode& root_transform,
const TransformPaintPropertyNode& scroll_translation) {
const auto* scroll = scroll_translation.ScrollNode();
DCHECK(scroll);
rect_.Intersect(scroll->ContainerRect());
if (rect_.IsEmpty())
return kNotExpanded;
ApplyTransformWithoutExpansion(scroll_translation);
// Don't expand for non-composited scrolling.
if (!scroll_translation.HasDirectCompositingReasons())
return kNotExpanded;
// We create scroll node for the root scroller even it's not scrollable.
// Don't expand in the case.
if (scroll->ContainerRect().Width() >= scroll->ContentsSize().Width() &&
scroll->ContainerRect().Height() >= scroll->ContentsSize().Height())
return kNotExpanded;
if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) {
if (const auto* scroll = transform.ScrollNode()) {
rect_.Intersect(scroll->ContainerRect());
if (rect_.IsEmpty())
return kNotExpanded;
MapRect(transform, rect_);
// Don't expand for non-composited scrolling.
if (!transform.HasDirectCompositingReasons())
return kNotExpanded;
// We create scroll node for the root scroller even it's not scrollable.
// Don't expand in the case.
if (scroll->ContainerRect().Width() >= scroll->ContentsSize().Width() &&
scroll->ContainerRect().Height() >= scroll->ContentsSize().Height())
return kNotExpanded;
// Expand the cull rect for scrolling contents for composited scrolling.
static const int kPixelDistanceToExpand = 4000;
rect_.Inflate(kPixelDistanceToExpand);
// Don't clip the cull rect by contents size to let ChangedEnough() work
// even if the new cull rect exceeds the bounds of contents rect.
return rect_.Contains(IntRect(IntPoint(), scroll->ContentsSize()))
? kExpandedForWholeScrollingContents
: kExpandedForPartialScrollingContents;
}
}
// Expand the cull rect for scrolling contents for composited scrolling.
rect_.Inflate(LocalPixelDistanceToExpand(root_transform, scroll_translation));
IntRect contents_rect(IntPoint(), scroll->ContentsSize());
rect_.Intersect(contents_rect);
return rect_ == contents_rect ? kExpandedForWholeScrollingContents
: kExpandedForPartialScrollingContents;
if (!IsInfinite())
MapRect(transform, rect_);
return kNotExpanded;
}
void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
......@@ -153,7 +125,7 @@ void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
*last_transform, *scroll_translation->Parent(), rect_);
}
last_scroll_translation_result =
ApplyScrollTranslation(source, *scroll_translation);
ApplyTransformInternal(*scroll_translation);
last_transform = scroll_translation;
}
......@@ -163,202 +135,25 @@ void CullRect::ApplyTransforms(const TransformPaintPropertyNode& source,
}
if (last_scroll_translation_result == kExpandedForPartialScrollingContents &&
old_cull_rect &&
!ChangedEnough(*old_cull_rect,
&last_transform->ScrollNode()->ContentsSize())) {
rect_ = old_cull_rect->Rect();
}
}
void CullRect::ApplyPaintPropertiesWithoutExpansion(
const PropertyTreeState& source,
const PropertyTreeState& destination) {
FloatClipRect clip_rect =
GeometryMapper::LocalToAncestorClipRect(destination, source);
if (!clip_rect.IsInfinite())
rect_.Intersect(EnclosingIntRect(clip_rect.Rect()));
if (!IsInfinite()) {
GeometryMapper::SourceToDestinationRect(source.Transform(),
destination.Transform(), rect_);
}
}
void CullRect::ApplyPaintProperties(
const PropertyTreeState& root,
const PropertyTreeState& source,
const PropertyTreeState& destination,
const base::Optional<CullRect>& old_cull_rect) {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::CullRectUpdateEnabled());
Vector<const TransformPaintPropertyNode*, 4> scroll_translations;
Vector<const ClipPaintPropertyNode*, 4> clips;
bool abnormal_hierarchy = false;
for (const auto* t = &destination.Transform(); t != &source.Transform();
t = t->UnaliasedParent()) {
DCHECK(t);
if (t == &root.Transform()) {
abnormal_hierarchy = true;
break;
}
if (t->ScrollNode())
scroll_translations.push_back(t);
}
if (!abnormal_hierarchy) {
for (const auto* c = &destination.Clip(); c != &source.Clip();
c = c->UnaliasedParent()) {
DCHECK(c);
if (c == &root.Clip()) {
abnormal_hierarchy = true;
break;
}
clips.push_back(c);
}
}
if (abnormal_hierarchy) {
// Either the transform or the clip of |source| is not an ancestor of
// |destination|. Map infinite rect from the root.
*this = Infinite();
ApplyPaintProperties(root, root, destination, old_cull_rect);
return;
}
// These are either the source transform/clip or the last scroll
// translation's transform/clip.
const auto* last_transform = &source.Transform();
const auto* last_clip = &source.Clip();
auto last_scroll_translation_result = kNotExpanded;
// For now effects (especially pixel-moving filters) are not considered in
// this class. The client has to use infinite cull rect in the case.
// TODO(wangxianzhu): support clip rect expansion for pixel-moving filters.
const auto& effect_root = EffectPaintPropertyNode::Root();
auto scroll_translation_it = scroll_translations.rbegin();
for (const auto* clip : base::Reversed(clips)) {
if (scroll_translation_it == scroll_translations.rend())
break;
const auto* scroll_translation = *scroll_translation_it++;
if (&clip->LocalTransformSpace() != scroll_translation->Parent())
continue;
ApplyPaintPropertiesWithoutExpansion(
PropertyTreeState(*last_transform, *last_clip, effect_root),
PropertyTreeState(*scroll_translation->UnaliasedParent(), *clip,
effect_root));
last_scroll_translation_result =
ApplyScrollTranslation(root.Transform(), *scroll_translation);
last_transform = scroll_translation;
last_clip = clip;
}
ApplyPaintPropertiesWithoutExpansion(
PropertyTreeState(*last_transform, *last_clip, effect_root), destination);
// Since the cull rect mapping above can produce extremely large numbers in
// cases of perspective, try our best to "normalize" the result by ensuring
// that none of the rect dimensions exceed some large, but reasonable, limit.
// Note that by clamping X and Y, we are effectively moving the rect right /
// down. However, this will at most make us paint more content, which is
// better than erroneously deciding that the rect produced here is far
// offscreen.
if (rect_.X() < -kReasonablePixelLimit)
rect_.SetX(-kReasonablePixelLimit);
if (rect_.Y() < -kReasonablePixelLimit)
rect_.SetY(-kReasonablePixelLimit);
if (rect_.MaxX() > kReasonablePixelLimit)
rect_.ShiftMaxXEdgeTo(kReasonablePixelLimit);
if (rect_.MaxY() > kReasonablePixelLimit)
rect_.ShiftMaxYEdgeTo(kReasonablePixelLimit);
const IntSize* expansion_bounds = nullptr;
bool expanded = false;
if (last_scroll_translation_result == kExpandedForPartialScrollingContents &&
last_clip == &destination.Clip()) {
DCHECK(last_transform->ScrollNode());
expansion_bounds = &last_transform->ScrollNode()->ContentsSize();
expanded = true;
} else if (!IsInfinite() && last_transform != &destination.Transform() &&
destination.Transform().HasDirectCompositingReasons()) {
// Direct compositing reasons such as will-change transform can cause the
// content to move arbitrarily, so there is no exact cull rect. Instead of
// using an infinite rect, we use a heuristic of expanding by
// |pixel_distance_to_expand|. To avoid extreme expansion in the presence
// of nested composited transforms, the heuristic is skipped for rects that
// are already very large.
int pixel_distance_to_expand =
LocalPixelDistanceToExpand(root.Transform(), destination.Transform());
if (rect_.Width() < pixel_distance_to_expand) {
rect_.InflateX(pixel_distance_to_expand);
expanded = true;
}
if (rect_.Height() < pixel_distance_to_expand) {
rect_.InflateY(pixel_distance_to_expand);
expanded = true;
}
}
if (expanded && old_cull_rect &&
!ChangedEnough(*old_cull_rect, expansion_bounds))
old_cull_rect && !ChangedEnough(*old_cull_rect))
rect_ = old_cull_rect->Rect();
}
bool CullRect::ChangedEnough(const CullRect& old_cull_rect,
const IntSize* expansion_bounds) const {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled() ||
RuntimeEnabledFeatures::CullRectUpdateEnabled());
bool CullRect::ChangedEnough(const CullRect& old_cull_rect) const {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
const auto& new_rect = Rect();
const auto& old_rect = old_cull_rect.Rect();
if (old_rect.Contains(new_rect))
return false;
if (old_rect.IsEmpty() && new_rect.IsEmpty())
if (old_rect == new_rect || (old_rect.IsEmpty() && new_rect.IsEmpty()))
return false;
if (old_rect.IsEmpty())
return true;
static constexpr int kChangedEnoughMinimumDistance = 512;
auto expanded_old_rect = old_rect;
static const int kChangedEnoughMinimumDistance = 512;
expanded_old_rect.Inflate(kChangedEnoughMinimumDistance);
if (!expanded_old_rect.Contains(new_rect))
return true;
// The following edge checking logic applies only when the bounds (which were
// used to clip the cull rect) are known.
if (!expansion_bounds)
return false;
// The cull rect must have been clipped by *expansion_bounds.
DCHECK(IntRect(IntPoint(), *expansion_bounds).Contains(rect_));
// Even if the new cull rect doesn't include enough new area to satisfy
// the condition above, update anyway if it touches the edge of the scrolling
// contents that is not touched by the existing cull rect. Because it's
// impossible to expose more area in the direction, update cannot be deferred
// until the exposed new area satisfies the condition above.
// For example,
// scroller contents dimensions: 100x1000
// old cull rect: 0,100 100x8000
// A new rect of 0,0 100x8000 will not be |kChangedEnoughMinimumDistance|
// pixels away from the current rect. Without additional logic for this case,
// we will continue using the old cull rect.
if (rect_.X() == 0 && old_cull_rect.Rect().X() != 0)
return true;
if (rect_.Y() == 0 && old_cull_rect.Rect().Y() != 0)
return true;
if (rect_.MaxX() == expansion_bounds->Width() &&
old_cull_rect.Rect().MaxX() != expansion_bounds->Width())
return true;
if (rect_.MaxY() == expansion_bounds->Height() &&
old_cull_rect.Rect().MaxY() != expansion_bounds->Height())
return true;
return false;
return !expanded_old_rect.Contains(new_rect);
}
} // namespace blink
......@@ -18,7 +18,6 @@ class AffineTransform;
class FloatRect;
class LayoutRect;
class LayoutUnit;
class PropertyTreeState;
class TransformPaintPropertyNode;
class PLATFORM_EXPORT CullRect {
......@@ -48,9 +47,9 @@ class PLATFORM_EXPORT CullRect {
// 1. it's clipped by the container rect,
// 2. transformed by inverse of the scroll translation,
// 3. expanded by thousands of pixels for composited scrolling.
// 4. clipped by the contents rect.
// TODO(wangxianzhu): Remove this function for CullRectUpdate.
void ApplyTransform(const TransformPaintPropertyNode&);
void ApplyTransform(const TransformPaintPropertyNode& transform) {
ApplyTransformInternal(transform);
}
// For CompositeAfterPaint only. Applies transforms from |source| (not
// included) to |destination| (included). For each scroll translation, the
......@@ -59,21 +58,10 @@ class PLATFORM_EXPORT CullRect {
// doesn't cover the whole scrolling contents, and the new cull rect doesn't
// change enough (by hundreds of pixels) from |old_cull_rect|, the cull rect
// will be set to |old_cull_rect| to avoid repaint on each composited scroll.
// TODO(wangxianzhu): Remove this function for CullRectUpdate.
void ApplyTransforms(const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
const base::Optional<CullRect>& old_cull_rect);
// For CullRectUpdate only. Similar to the above but also applies clips and
// expands for all directly composited transforms (including scrolling and
// non-scrolling ones). |root| is used to calculate the expansion distance in
// the local space, to make the expansion distance approximately the same in
// the root space.
void ApplyPaintProperties(const PropertyTreeState& root,
const PropertyTreeState& source,
const PropertyTreeState& destination,
const base::Optional<CullRect>& old_cull_rect);
const IntRect& Rect() const { return rect_; }
String ToString() const { return rect_.ToString(); }
......@@ -94,17 +82,10 @@ class PLATFORM_EXPORT CullRect {
// doesn't cover the whole scrolling contents.
kExpandedForPartialScrollingContents,
};
ApplyTransformResult ApplyScrollTranslation(
const TransformPaintPropertyNode& root_transform,
const TransformPaintPropertyNode& scroll_translation);
void ApplyTransformWithoutExpansion(const TransformPaintPropertyNode&);
void ApplyPaintPropertiesWithoutExpansion(
const PropertyTreeState& source,
const PropertyTreeState& destination);
ApplyTransformResult ApplyTransformInternal(
const TransformPaintPropertyNode&);
bool ChangedEnough(const CullRect& old_cull_rect,
const IntSize* bounds) const;
bool ChangedEnough(const CullRect& old_cull_rect) const;
IntRect rect_;
};
......
......@@ -21,27 +21,14 @@ class CullRectTest : public testing::Test {
const CullRect::ApplyTransformResult kExpandedForWholeScrollingContents =
CullRect::kExpandedForWholeScrollingContents;
// Tests only transforms without clips.
void ApplyTransforms(CullRect& cull_rect,
const TransformPaintPropertyNode& source,
const TransformPaintPropertyNode& destination,
const base::Optional<CullRect>& old_cull_rect) {
PropertyTreeState source_state(source, c0(), e0());
PropertyTreeState destination_state(destination, c0(), e0());
cull_rect.ApplyPaintProperties(PropertyTreeState::Root(), source_state,
destination_state, old_cull_rect);
}
CullRect::ApplyTransformResult ApplyScrollTranslation(
CullRect::ApplyTransformResult ApplyTransform(
CullRect& cull_rect,
const TransformPaintPropertyNode& t) {
return cull_rect.ApplyScrollTranslation(t, t);
return cull_rect.ApplyTransformInternal(t);
}
bool ChangedEnough(const IntRect& old_rect,
const IntRect& new_rect,
const IntSize* bounds = nullptr) {
return CullRect(new_rect).ChangedEnough(CullRect(old_rect), bounds);
bool ChangedEnough(const IntRect& old_rect, const IntRect& new_rect) {
return CullRect(new_rect).ChangedEnough(CullRect(old_rect));
}
};
......@@ -104,7 +91,7 @@ TEST_F(CullRectTest, ApplyTransform) {
CullRect cull_rect(IntRect(1, 1, 50, 50));
auto transform =
CreateTransform(t0(), TransformationMatrix().Translate(1, 1));
cull_rect.ApplyTransform(*transform);
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *transform));
EXPECT_EQ(IntRect(0, 0, 50, 50), cull_rect.Rect());
}
......@@ -113,12 +100,13 @@ TEST_F(CullRectTest, ApplyTransformInfinite) {
CullRect cull_rect = CullRect::Infinite();
auto transform =
CreateTransform(t0(), TransformationMatrix().Translate(1, 1));
cull_rect.ApplyTransform(*transform);
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *transform));
EXPECT_TRUE(cull_rect.IsInfinite());
}
TEST_F(CullRectTest, ApplyScrollTranslationPartialScrollingContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
......@@ -130,25 +118,24 @@ TEST_F(CullRectTest, ApplyScrollTranslationPartialScrollingContents) {
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kExpandedForPartialScrollingContents,
ApplyScrollTranslation(cull_rect, *scroll_translation));
ApplyTransform(cull_rect, *scroll_translation));
// Clipped: (20, 10, 30, 50)
// Inverse transformed: (3020, 5010, 30, 50)
// Expanded: (-980, 1010, 8030, 8050)
// Then clipped by the contents rect.
EXPECT_EQ(IntRect(0, 1010, 7050, 6990), cull_rect.Rect());
EXPECT_EQ(IntRect(-980, 1010, 8030, 8050), cull_rect.Rect());
cull_rect = CullRect::Infinite();
EXPECT_EQ(kExpandedForPartialScrollingContents,
ApplyScrollTranslation(cull_rect, *scroll_translation));
// This result differs from the above result in height (7050 vs 7060)
ApplyTransform(cull_rect, *scroll_translation));
// This result differs from the above result in height (8040 vs 8030)
// because it's not clipped by the infinite input cull rect.
EXPECT_EQ(IntRect(0, 1010, 7060, 6990), cull_rect.Rect());
EXPECT_EQ(IntRect(-980, 1010, 8040, 8050), cull_rect.Rect());
}
TEST_F(CullRectTest,
ApplyNonCompositedScrollTranslationPartialScrollingContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
......@@ -159,23 +146,21 @@ TEST_F(CullRectTest,
CreateScrollTranslation(t0(), -3000, -5000, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kNotExpanded,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
// Clipped: (20, 10, 30, 50)
// Inverse transformed: (3020, 5010, 30, 50)
EXPECT_EQ(IntRect(3020, 5010, 30, 50), cull_rect.Rect());
cull_rect = CullRect::Infinite();
EXPECT_EQ(kNotExpanded,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
// This result differs from the above result in height (40 vs 30)
// because it's not clipped by the infinite input cull rect.
EXPECT_EQ(IntRect(3020, 5010, 40, 50), cull_rect.Rect());
}
TEST_F(CullRectTest, ApplyScrollTranslationNoIntersectionWithContainerRect) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(200, 100, 40, 50);
......@@ -186,14 +171,13 @@ TEST_F(CullRectTest, ApplyScrollTranslationNoIntersectionWithContainerRect) {
CreateCompositedScrollTranslation(t0(), -10, -15, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kNotExpanded,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
EXPECT_TRUE(cull_rect.Rect().IsEmpty());
}
TEST_F(CullRectTest,
ApplyNonCompositedScrollTranslationNoIntersectionWithContainerRect) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(200, 100, 40, 50);
......@@ -203,13 +187,12 @@ TEST_F(CullRectTest,
auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kNotExpanded,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
EXPECT_TRUE(cull_rect.Rect().IsEmpty());
}
TEST_F(CullRectTest, ApplyScrollTranslationWholeScrollingContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
......@@ -221,23 +204,24 @@ TEST_F(CullRectTest, ApplyScrollTranslationWholeScrollingContents) {
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kExpandedForWholeScrollingContents,
ApplyScrollTranslation(cull_rect, *scroll_translation));
ApplyTransform(cull_rect, *scroll_translation));
// Clipped: (20, 10, 30, 50)
// Inverse transformed: (30, 25, 30, 50)
// Expanded: (-3970, -3975, 8030, 8050)
// Then clipped by the contents rect.
EXPECT_EQ(IntRect(0, 0, 2000, 2000), cull_rect.Rect());
EXPECT_EQ(IntRect(-3970, -3975, 8030, 8050), cull_rect.Rect());
cull_rect = CullRect::Infinite();
EXPECT_EQ(kExpandedForWholeScrollingContents,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(IntRect(0, 0, 2000, 2000), cull_rect.Rect());
ApplyTransform(cull_rect, *scroll_translation));
// This result differs from the above result in height (8040 vs 8030)
// because it's not clipped by the infinite input cull rect.
EXPECT_EQ(IntRect(-3970, -3975, 8040, 8050), cull_rect.Rect());
}
TEST_F(CullRectTest,
ApplyNonCompositedScrollTranslationWholeScrollingContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
......@@ -247,23 +231,21 @@ TEST_F(CullRectTest,
auto scroll_translation = CreateScrollTranslation(t0(), -10, -15, *scroll);
CullRect cull_rect(IntRect(0, 0, 50, 100));
EXPECT_EQ(kNotExpanded,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
// Clipped: (20, 10, 30, 50)
// Inverse transformed: (30, 25, 30, 50)
EXPECT_EQ(IntRect(30, 25, 30, 50), cull_rect.Rect());
cull_rect = CullRect::Infinite();
EXPECT_EQ(kNotExpanded,
ApplyScrollTranslation(cull_rect, *scroll_translation));
EXPECT_EQ(kNotExpanded, ApplyTransform(cull_rect, *scroll_translation));
// This result differs from the above result in height (40 vs 30)
// because it's not clipped by the infinite input cull rect.
EXPECT_EQ(IntRect(30, 25, 40, 50), cull_rect.Rect());
}
TEST_F(CullRectTest, ChangedEnoughEmpty) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
EXPECT_FALSE(ChangedEnough(IntRect(), IntRect()));
EXPECT_FALSE(ChangedEnough(IntRect(1, 1, 0, 0), IntRect(2, 2, 0, 0)));
EXPECT_TRUE(ChangedEnough(IntRect(), IntRect(0, 0, 1, 1)));
......@@ -271,7 +253,7 @@ TEST_F(CullRectTest, ChangedEnoughEmpty) {
}
TEST_F(CullRectTest, ChangedNotEnough) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
IntRect old_rect(100, 100, 100, 100);
EXPECT_FALSE(ChangedEnough(old_rect, old_rect));
EXPECT_FALSE(ChangedEnough(old_rect, IntRect(100, 100, 90, 90)));
......@@ -279,8 +261,8 @@ TEST_F(CullRectTest, ChangedNotEnough) {
EXPECT_FALSE(ChangedEnough(old_rect, IntRect(1, 1, 200, 200)));
}
TEST_F(CullRectTest, ChangedEnoughOnMovement) {
ScopedCullRectUpdateForTest cull_rect_update(true);
TEST_F(CullRectTest, ChangedEnoughScrollScenarios) {
ScopedCompositeAfterPaintForTest cap(true);
IntRect old_rect(100, 100, 100, 100);
IntRect new_rect(old_rect);
new_rect.Move(500, 0);
......@@ -293,351 +275,241 @@ TEST_F(CullRectTest, ChangedEnoughOnMovement) {
EXPECT_TRUE(ChangedEnough(old_rect, new_rect));
}
TEST_F(CullRectTest, ChangedEnoughNewRectTouchingEdge) {
ScopedCullRectUpdateForTest cull_rect_update(true);
IntSize bounds(500, 500);
IntRect old_rect(100, 100, 100, 100);
// Top edge.
EXPECT_FALSE(ChangedEnough(old_rect, IntRect(100, 50, 100, 200), &bounds));
EXPECT_TRUE(ChangedEnough(old_rect, IntRect(100, 0, 100, 200), &bounds));
// Left edge.
EXPECT_FALSE(ChangedEnough(old_rect, IntRect(50, 100, 200, 100), &bounds));
EXPECT_TRUE(ChangedEnough(old_rect, IntRect(0, 100, 200, 100), &bounds));
// Bottom edge.
EXPECT_FALSE(ChangedEnough(old_rect, IntRect(100, 100, 100, 350), &bounds));
EXPECT_TRUE(ChangedEnough(old_rect, IntRect(100, 100, 100, 400), &bounds));
// Right edge.
EXPECT_FALSE(ChangedEnough(old_rect, IntRect(100, 100, 350, 100), &bounds));
EXPECT_TRUE(ChangedEnough(old_rect, IntRect(100, 100, 400, 100), &bounds));
}
TEST_F(CullRectTest, ChangedEnoughOldRectTouchingEdge) {
ScopedCullRectUpdateForTest cull_rect_update(true);
IntSize bounds(500, 500);
IntRect new_rect(100, 100, 300, 300);
// Top edge.
EXPECT_FALSE(ChangedEnough(IntRect(100, 0, 100, 100), new_rect, &bounds));
// Left edge.
EXPECT_FALSE(ChangedEnough(IntRect(0, 100, 100, 100), new_rect, &bounds));
// Bottom edge.
EXPECT_FALSE(ChangedEnough(IntRect(300, 400, 100, 100), new_rect, &bounds));
// Right edge.
EXPECT_FALSE(ChangedEnough(IntRect(400, 300, 100, 100), new_rect, &bounds));
}
TEST_F(CullRectTest, ApplyPaintPropertiesSameState) {
ScopedCullRectUpdateForTest cull_rect_update(true);
TEST_F(CullRectTest, ApplyTransformsSameTransform) {
ScopedCompositeAfterPaintForTest cap(true);
auto transform =
CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
auto clip = CreateClip(c0(), t0(), FloatRoundedRect(1, 2, 3, 4));
PropertyTreeState root = PropertyTreeState::Root();
PropertyTreeState state(*transform, *clip, e0());
CullRect cull_rect1(IntRect(1, 1, 50, 50));
cull_rect1.ApplyPaintProperties(state, state, state, base::nullopt);
EXPECT_EQ(IntRect(1, 1, 50, 50), cull_rect1.Rect());
cull_rect1.ApplyPaintProperties(root, state, state, base::nullopt);
cull_rect1.ApplyTransforms(*transform, *transform, base::nullopt);
EXPECT_EQ(IntRect(1, 1, 50, 50), cull_rect1.Rect());
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect2(IntRect(1, 1, 50, 50));
// Should ignore old_cull_rect.
cull_rect2.ApplyPaintProperties(state, state, state, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect2);
cull_rect2.ApplyPaintProperties(root, state, state, old_cull_rect);
cull_rect2.ApplyTransforms(*transform, *transform, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect2);
CullRect infinite = CullRect::Infinite();
infinite.ApplyPaintProperties(state, state, state, base::nullopt);
EXPECT_TRUE(infinite.IsInfinite());
infinite.ApplyPaintProperties(root, state, state, base::nullopt);
infinite.ApplyTransforms(*transform, *transform, base::nullopt);
EXPECT_TRUE(infinite.IsInfinite());
}
TEST_F(CullRectTest, ApplyPaintPropertiesWithoutClipScroll) {
ScopedCullRectUpdateForTest cull_rect_update(true);
TEST_F(CullRectTest, ApplyTransformsWithoutScroll) {
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
auto t2 = CreateTransform(*t1, TransformationMatrix().Translate(10, 20));
PropertyTreeState root = PropertyTreeState::Root();
PropertyTreeState state1(*t1, c0(), e0());
PropertyTreeState state2(*t2, c0(), e0());
CullRect cull_rect1(IntRect(1, 1, 50, 50));
cull_rect1.ApplyPaintProperties(root, state1, state2, base::nullopt);
cull_rect1.ApplyTransforms(*t1, *t2, base::nullopt);
EXPECT_EQ(IntRect(-9, -19, 50, 50), cull_rect1.Rect());
CullRect cull_rect2(IntRect(1, 1, 50, 50));
cull_rect2.ApplyPaintProperties(root, root, state2, base::nullopt);
cull_rect2.ApplyTransforms(t0(), *t2, base::nullopt);
EXPECT_EQ(IntRect(-10, -21, 50, 50), cull_rect2.Rect());
CullRect old_cull_rect = cull_rect2;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect3(IntRect(1, 1, 50, 50));
// Should ignore old_cull_rect.
cull_rect3.ApplyPaintProperties(root, root, state2, old_cull_rect);
cull_rect3.ApplyTransforms(t0(), *t2, old_cull_rect);
EXPECT_EQ(cull_rect2, cull_rect3);
CullRect infinite = CullRect::Infinite();
infinite.ApplyPaintProperties(root, root, state2, base::nullopt);
infinite.ApplyTransforms(t0(), *t2, base::nullopt);
EXPECT_TRUE(infinite.IsInfinite());
}
TEST_F(CullRectTest, ApplyTransformsSingleScrollWholeScrollingContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
PropertyTreeState state1(*t1, c0(), e0());
auto ref_scroll_translation_state = CreateCompositedScrollTranslationState(
state1, -10, -15, IntRect(20, 10, 40, 50), IntSize(2000, 2000));
auto scroll_translation_state =
ref_scroll_translation_state.GetPropertyTreeState().Unalias();
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
scroll_state.contents_size = IntSize(2000, 2000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
auto scroll_translation =
CreateCompositedScrollTranslation(*t1, -10, -15, *scroll);
// Same as ApplyScrollTranslationWholeScrollingContents.
CullRect cull_rect1(IntRect(0, 0, 50, 100));
cull_rect1.ApplyPaintProperties(state1, state1, scroll_translation_state,
base::nullopt);
EXPECT_EQ(IntRect(0, 0, 2000, 2000), cull_rect1.Rect());
cull_rect1.ApplyTransforms(*t1, *scroll_translation, base::nullopt);
EXPECT_EQ(IntRect(-3970, -3975, 8030, 8050), cull_rect1.Rect());
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect2(IntRect(0, 0, 50, 100));
// Should ignore old_cull_rect.
cull_rect2.ApplyPaintProperties(state1, state1, scroll_translation_state,
old_cull_rect);
cull_rect2.ApplyTransforms(*t1, *scroll_translation, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect2);
CullRect cull_rect3 = CullRect::Infinite();
cull_rect3.ApplyPaintProperties(state1, state1, scroll_translation_state,
base::nullopt);
EXPECT_EQ(IntRect(0, 0, 2000, 2000), cull_rect3.Rect());
cull_rect3.ApplyTransforms(*t1, *scroll_translation, base::nullopt);
// This result differs from the first result in height (8040 vs 8030)
// because it's not clipped by the infinite input cull rect.
EXPECT_EQ(IntRect(-3970, -3975, 8040, 8050), cull_rect3.Rect());
}
TEST_F(CullRectTest, ApplyTransformsWithOrigin) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
auto t2 = CreateTransform(*t1, TransformationMatrix().Scale(0.5),
FloatPoint3D(50, 100, 0));
PropertyTreeState root = PropertyTreeState::Root();
PropertyTreeState state1(*t1, c0(), e0());
PropertyTreeState state2(*t2, c0(), e0());
CullRect cull_rect1(IntRect(0, 0, 50, 200));
cull_rect1.ApplyPaintProperties(root, state1, state2, base::nullopt);
cull_rect1.ApplyTransforms(*t1, *t2, base::nullopt);
EXPECT_EQ(IntRect(-50, -100, 100, 400), cull_rect1.Rect());
}
TEST_F(CullRectTest, ApplyTransformsSingleScrollPartialScrollingContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
PropertyTreeState state1(*t1, c0(), e0());
auto ref_scroll_translation_state = CreateCompositedScrollTranslationState(
state1, -3000, -5000, IntRect(20, 10, 40, 50), IntSize(8000, 8000));
auto scroll_translation_state =
ref_scroll_translation_state.GetPropertyTreeState().Unalias();
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
scroll_state.contents_size = IntSize(8000, 8000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
auto scroll_translation =
CreateCompositedScrollTranslation(*t1, -3000, -5000, *scroll);
// Same as ApplyScrollTranslationPartialScrollingContents.
CullRect cull_rect1(IntRect(0, 0, 50, 100));
cull_rect1.ApplyPaintProperties(state1, state1, scroll_translation_state,
base::nullopt);
EXPECT_EQ(IntRect(0, 1010, 7050, 6990), cull_rect1.Rect());
cull_rect1.ApplyTransforms(*t1, *scroll_translation, base::nullopt);
EXPECT_EQ(IntRect(-980, 1010, 8030, 8050), cull_rect1.Rect());
CullRect old_cull_rect(IntRect(0, 1100, 7050, 6900));
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect2(IntRect(0, 0, 50, 100));
// Use old_cull_rect if the new cull rect didn't change enough.
cull_rect2.ApplyPaintProperties(state1, state1, scroll_translation_state,
old_cull_rect);
cull_rect2.ApplyTransforms(*t1, *scroll_translation, old_cull_rect);
EXPECT_EQ(old_cull_rect, cull_rect2);
old_cull_rect.Move(IntSize(1000, 1000));
CullRect cull_rect3(IntRect(0, 0, 50, 100));
// Use the new cull rect if it changed enough.
cull_rect3.ApplyPaintProperties(state1, state1, scroll_translation_state,
old_cull_rect);
cull_rect3.ApplyTransforms(*t1, *scroll_translation, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect3);
CullRect cull_rect4 = CullRect::Infinite();
cull_rect4.ApplyPaintProperties(state1, state1, scroll_translation_state,
base::nullopt);
// This result differs from the first result in height (7050 vs 7060)
cull_rect4.ApplyTransforms(*t1, *scroll_translation, base::nullopt);
// This result differs from the first result in height (8040 vs 8030)
// because it's not clipped by the infinite input cull rect.
EXPECT_EQ(IntRect(0, 1010, 7060, 6990), cull_rect4.Rect());
EXPECT_EQ(IntRect(-980, 1010, 8040, 8050), cull_rect4.Rect());
}
TEST_F(CullRectTest, ApplyTransformsEscapingScroll) {
ScopedCullRectUpdateForTest cull_rect_update(true);
PropertyTreeState root = PropertyTreeState::Root();
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(111, 222, 333, 444));
PropertyTreeState state1(*t1, *c1, e0());
auto ref_scroll_translation_state = CreateCompositedScrollTranslationState(
state1, -3000, -5000, IntRect(20, 10, 40, 50), IntSize(8000, 8000));
auto scroll_translation_state =
ref_scroll_translation_state.GetPropertyTreeState().Unalias();
auto t2 = CreateTransform(scroll_translation_state.Transform(),
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = IntRect(20, 10, 40, 50);
scroll_state.contents_size = IntSize(8000, 8000);
auto scroll = ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(),
std::move(scroll_state));
auto scroll_translation =
CreateCompositedScrollTranslation(*t1, -3000, -5000, *scroll);
auto t2 = CreateTransform(*scroll_translation,
TransformationMatrix().Translate(100, 200));
PropertyTreeState state2(*t2, scroll_translation_state.Clip(), e0());
CullRect cull_rect1(IntRect(0, 0, 50, 100));
// Ignore the current cull rect, and apply paint properties from root to
// state1 on infinite cull rect instead.
cull_rect1.ApplyPaintProperties(root, state2, state1, base::nullopt);
EXPECT_EQ(IntRect(110, 220, 333, 444), cull_rect1.Rect());
// Just apply tranforms without clipping and expansion for scroll translation.
cull_rect1.ApplyTransforms(*t2, *t1, base::nullopt);
EXPECT_EQ(IntRect(-2900, -4800, 50, 100), cull_rect1.Rect());
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect2(IntRect(0, 0, 50, 100));
// Should ignore old_cull_rect.
cull_rect2.ApplyPaintProperties(root, state2, state1, old_cull_rect);
cull_rect2.ApplyTransforms(*t2, *t1, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect2);
CullRect cull_rect3 = CullRect::Infinite();
cull_rect3.ApplyPaintProperties(root, state2, state1, base::nullopt);
EXPECT_EQ(cull_rect1, cull_rect3);
CullRect infinite = CullRect::Infinite();
infinite.ApplyTransforms(*t2, *t1, base::nullopt);
EXPECT_TRUE(infinite.IsInfinite());
}
TEST_F(CullRectTest, ApplyTransformsSmallScrollContentsAfterBigScrollContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
PropertyTreeState state1(*t1, c0(), e0());
auto ref_scroll_translation_state1 = CreateCompositedScrollTranslationState(
state1, -10, -15, IntRect(20, 10, 40, 50), IntSize(8000, 8000));
auto scroll_translation_state1 =
ref_scroll_translation_state1.GetPropertyTreeState().Unalias();
ScrollPaintPropertyNode::State scroll_state1;
scroll_state1.container_rect = IntRect(20, 10, 40, 50);
scroll_state1.contents_size = IntSize(8000, 8000);
auto scroll1 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state1));
auto scroll_translation1 =
CreateCompositedScrollTranslation(*t1, -10, -15, *scroll1);
auto t2 = CreateTransform(scroll_translation_state1.Transform(),
auto t2 = CreateTransform(*scroll_translation1,
TransformationMatrix().Translate(2000, 3000));
PropertyTreeState state2(*t2, scroll_translation_state1.Clip(), e0());
auto ref_scroll_translation_state2 = CreateCompositedScrollTranslationState(
state2, -10, -15, IntRect(30, 20, 100, 200), IntSize(200, 400));
auto scroll_translation_state2 =
ref_scroll_translation_state2.GetPropertyTreeState().Unalias();
ScrollPaintPropertyNode::State scroll_state2;
scroll_state2.container_rect = IntRect(30, 20, 100, 200);
scroll_state2.contents_size = IntSize(200, 400);
auto scroll2 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state2));
auto scroll_translation2 =
CreateCompositedScrollTranslation(*t2, -10, -15, *scroll2);
CullRect cull_rect1(IntRect(0, 0, 50, 100));
cull_rect1.ApplyPaintProperties(state1, state1, scroll_translation_state2,
base::nullopt);
EXPECT_EQ(IntRect(0, 0, 200, 400), cull_rect1.Rect());
cull_rect1.ApplyTransforms(*t1, *scroll_translation2, base::nullopt);
EXPECT_EQ(IntRect(-3960, -3965, 8100, 8200), cull_rect1.Rect());
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect2(IntRect(0, 0, 50, 100));
// Should ignore old_cull_rect.
cull_rect2.ApplyPaintProperties(state1, state1, scroll_translation_state2,
old_cull_rect);
cull_rect2.ApplyTransforms(*t1, *scroll_translation2, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect2);
}
TEST_F(CullRectTest, ApplyTransformsBigScrollContentsAfterSmallScrollContents) {
ScopedCullRectUpdateForTest cull_rect_update(true);
ScopedCompositeAfterPaintForTest cap(true);
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(1, 2));
PropertyTreeState state1(*t1, c0(), e0());
auto ref_scroll_translation_state1 = CreateCompositedScrollTranslationState(
state1, -10, -15, IntRect(30, 20, 100, 200), IntSize(200, 400));
auto scroll_translation_state1 =
ref_scroll_translation_state1.GetPropertyTreeState().Unalias();
ScrollPaintPropertyNode::State scroll_state1;
scroll_state1.container_rect = IntRect(30, 20, 100, 200);
scroll_state1.contents_size = IntSize(200, 400);
auto scroll1 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state1));
auto scroll_translation1 =
CreateCompositedScrollTranslation(*t1, -10, -15, *scroll1);
auto t2 = CreateTransform(scroll_translation_state1.Transform(),
auto t2 = CreateTransform(*scroll_translation1,
TransformationMatrix().Translate(10, 20));
PropertyTreeState state2(*t2, scroll_translation_state1.Clip(), e0());
auto ref_scroll_translation_state2 = CreateCompositedScrollTranslationState(
state2, -3000, -5000, IntRect(20, 10, 50, 100), IntSize(10000, 20000));
auto scroll_translation_state2 =
ref_scroll_translation_state2.GetPropertyTreeState().Unalias();
ScrollPaintPropertyNode::State scroll_state2;
scroll_state2.container_rect = IntRect(20, 10, 50, 100);
scroll_state2.contents_size = IntSize(10000, 20000);
auto scroll2 = ScrollPaintPropertyNode::Create(
ScrollPaintPropertyNode::Root(), std::move(scroll_state2));
auto scroll_translation2 =
CreateCompositedScrollTranslation(*t2, -3000, -5000, *scroll2);
CullRect cull_rect1(IntRect(0, 0, 100, 200));
cull_rect1.ApplyPaintProperties(state1, state1, scroll_translation_state2,
base::nullopt);
cull_rect1.ApplyTransforms(*t1, *scroll_translation2, base::nullopt);
// After the first scroll: (-3960, -3965, 8070, 8180)
// After t2: (-3980, -3975, 8070, 8180)
// Clipped by the container rect of the second scroll: (20, 10, 50, 100)
// After the second scroll offset: (3020, 5010, 50, 100)
// Expanded: (-980, 1010, 8050, 8100)
// Then clipped by the contents rect.
EXPECT_EQ(IntRect(0, 1010, 7070, 8100), cull_rect1.Rect());
EXPECT_EQ(IntRect(-980, 1010, 8050, 8100), cull_rect1.Rect());
CullRect old_cull_rect(IntRect(0, 1100, 7070, 8100));
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(1, 1));
CullRect cull_rect2(IntRect(0, 0, 100, 200));
// Use old_cull_rect if the new cull rect didn't change enough.
cull_rect2.ApplyPaintProperties(state1, state1, scroll_translation_state2,
old_cull_rect);
cull_rect2.ApplyTransforms(*t1, *scroll_translation2, old_cull_rect);
EXPECT_EQ(old_cull_rect, cull_rect2);
old_cull_rect.Move(IntSize(1000, 1000));
CullRect cull_rect3(IntRect(0, 0, 100, 200));
// Use the new cull rect if it changed enough.
cull_rect3.ApplyPaintProperties(state1, state1, scroll_translation_state2,
old_cull_rect);
cull_rect3.ApplyTransforms(*t1, *scroll_translation2, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect3);
}
TEST_F(CullRectTest, NonCompositedTransformUnderClip) {
ScopedCullRectUpdateForTest cull_rect_update(true);
PropertyTreeState root = PropertyTreeState::Root();
auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(100, 200, 300, 400));
auto t1 = CreateTransform(t0(), TransformationMatrix().Translate(10, 20));
PropertyTreeState state1(*t1, *c1, e0());
CullRect cull_rect1(IntRect(0, 0, 300, 500));
cull_rect1.ApplyPaintProperties(root, root, state1, base::nullopt);
// Clip by c1, then transformed by t1.
EXPECT_EQ(IntRect(90, 180, 200, 300), cull_rect1.Rect());
CullRect cull_rect2(IntRect(0, 0, 300, 500));
CullRect old_cull_rect(IntRect(133, 244, 333, 444));
// Should ignore old_cull_rect.
cull_rect2.ApplyPaintProperties(root, root, state1, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect2);
CullRect cull_rect3 = CullRect::Infinite();
cull_rect3.ApplyPaintProperties(root, root, state1, base::nullopt);
EXPECT_EQ(IntRect(90, 180, 300, 400), cull_rect3.Rect());
}
TEST_F(CullRectTest, CompositedTranslationUnderClip) {
ScopedCullRectUpdateForTest cull_rect_update(true);
PropertyTreeState root = PropertyTreeState::Root();
auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(100, 200, 300, 400));
auto t1 = CreateTransform(
t0(), TransformationMatrix().Translate(10, 20).Scale3d(2, 3, 1),
FloatPoint3D(), CompositingReason::kWillChangeTransform);
PropertyTreeState state1(*t1, *c1, e0());
CullRect cull_rect1(IntRect(0, 0, 300, 500));
cull_rect1.ApplyPaintProperties(root, root, state1, base::nullopt);
// The result in NonCompositedTransformUnderClip expanded by 2000 (scaled by
// maximum of 1/2 and 1/3).
EXPECT_EQ(IntRect(-1955, -1940, 4100, 4100), cull_rect1.Rect());
CullRect cull_rect2(IntRect(0, 0, 300, 500));
CullRect old_cull_rect = cull_rect1;
old_cull_rect.Move(IntSize(200, 200));
// Use old_cull_rect if the new cull rect didn't change enough.
cull_rect2.ApplyPaintProperties(root, root, state1, old_cull_rect);
EXPECT_EQ(old_cull_rect, cull_rect2);
CullRect cull_rect3(IntRect(0, 0, 300, 500));
old_cull_rect.Move(IntSize(1000, 1000));
// Use the new cull rect if it changed enough.
cull_rect3.ApplyPaintProperties(root, root, state1, old_cull_rect);
EXPECT_EQ(cull_rect1, cull_rect3);
CullRect cull_rect4 = CullRect::Infinite();
cull_rect4.ApplyPaintProperties(root, root, state1, base::nullopt);
EXPECT_EQ(IntRect(-1955, -1940, 4150, 4134), cull_rect4.Rect());
}
TEST_F(CullRectTest, IntersectsVerticalRange) {
CullRect cull_rect(IntRect(0, 0, 50, 100));
......
......@@ -653,9 +653,6 @@
name: "CSSVariables2TransformValues",
status: "test",
},
{
name: "CullRectUpdate",
},
{
name: "CustomElementDefaultStyle",
status: "experimental",
......
......@@ -8,7 +8,6 @@
#include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h"
#include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h"
#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h"
#include "third_party/blink/renderer/platform/graphics/paint/ref_counted_property_tree_state.h"
#include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h"
#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h"
......@@ -24,9 +23,6 @@ inline const ClipPaintPropertyNode& c0() {
inline const EffectPaintPropertyNode& e0() {
return EffectPaintPropertyNode::Root();
}
inline const ScrollPaintPropertyNode& s0() {
return ScrollPaintPropertyNode::Root();
}
constexpr int c0_id = 1;
constexpr int e0_id = 1;
......@@ -221,28 +217,6 @@ inline scoped_refptr<TransformPaintPropertyNode> CreateScrollTranslation(
return TransformPaintPropertyNode::Create(parent, std::move(state));
}
inline scoped_refptr<TransformPaintPropertyNode> CreateScrollTranslation(
const TransformPaintPropertyNodeOrAlias& parent,
float offset_x,
float offset_y,
const IntRect& container_rect,
const IntSize& contents_size,
CompositingReasons compositing_reasons = CompositingReason::kNone) {
const auto* parent_scroll_translation = &parent.Unalias();
while (!parent_scroll_translation->ScrollNode())
parent_scroll_translation = parent_scroll_translation->UnaliasedParent();
ScrollPaintPropertyNode::State scroll_state;
scroll_state.container_rect = container_rect;
scroll_state.contents_size = contents_size;
TransformPaintPropertyNode::State translation_state{
FloatSize(offset_x, offset_y)};
translation_state.direct_compositing_reasons = compositing_reasons;
translation_state.scroll = ScrollPaintPropertyNode::Create(
*parent_scroll_translation->ScrollNode(), std::move(scroll_state));
return TransformPaintPropertyNode::Create(parent,
std::move(translation_state));
}
inline scoped_refptr<TransformPaintPropertyNode>
CreateCompositedScrollTranslation(
const TransformPaintPropertyNodeOrAlias& parent,
......@@ -253,46 +227,6 @@ CreateCompositedScrollTranslation(
CompositingReason::kOverflowScrolling);
}
inline scoped_refptr<TransformPaintPropertyNode>
CreateCompositedScrollTranslation(
const TransformPaintPropertyNodeOrAlias& parent,
float offset_x,
float offset_y,
const IntRect& container_rect,
const IntSize& contents_size) {
return CreateScrollTranslation(parent, offset_x, offset_y, container_rect,
contents_size,
CompositingReason::kOverflowScrolling);
}
inline RefCountedPropertyTreeState CreateScrollTranslationState(
const PropertyTreeState& parent_state,
float offset_x,
float offset_y,
const IntRect& container_rect,
const IntSize& contents_size,
CompositingReasons compositing_reasons = CompositingReason::kNone) {
return RefCountedPropertyTreeState(PropertyTreeState(
*CreateScrollTranslation(parent_state.Transform(), offset_x, offset_y,
container_rect, contents_size,
compositing_reasons),
*CreateClip(parent_state.Clip(), parent_state.Transform(),
FloatRoundedRect(container_rect)),
e0()));
}
inline RefCountedPropertyTreeState CreateCompositedScrollTranslationState(
const PropertyTreeState& parent_state,
float offset_x,
float offset_y,
const IntRect& container_rect,
const IntSize& contents_size,
CompositingReasons compositing_reasons = CompositingReason::kNone) {
return CreateScrollTranslationState(parent_state, offset_x, offset_y,
container_rect, contents_size,
CompositingReason::kOverflowScrolling);
}
inline PropertyTreeState DefaultPaintChunkProperties() {
return PropertyTreeState::Root();
}
......
......@@ -7,11 +7,29 @@ Layer tree when the fixed elements are out-of-view (should have just a root laye
"contentsOpaque": true,
"backgroundColor": "#FFFFFF"
},
{
"name": "LayoutNGBlockFlow (positioned) DIV id='fixed1'",
"bounds": [10, 10],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 1
},
{
"name": "VerticalScrollbar",
"position": [785, 0],
"bounds": [15, 600]
}
],
"transforms": [
{
"id": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, -100, 0, 1]
]
}
]
}
......
......@@ -13,6 +13,20 @@
"backgroundColor": "#C0C0C0",
"transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 2
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 3
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
......@@ -34,6 +48,24 @@
[0, 0, 1, 0],
[8, 1013, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, -100, 0, 1]
]
},
{
"id": 3,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
]
}
]
}
......
......@@ -29,6 +29,13 @@ Not scaled:
"backgroundColor": "#C0C0C0",
"transform": 4
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 5
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
......@@ -56,7 +63,7 @@ Not scaled:
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 1008, 0, 1]
[8, -100, 0, 1]
]
},
{
......@@ -66,12 +73,22 @@ Not scaled:
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
[8, 1008, 0, 1]
]
},
{
"id": 4,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
]
},
{
"id": 5,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
......@@ -113,6 +130,13 @@ Scale=0.5:
"backgroundColor": "#C0C0C0",
"transform": 4
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 5
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
......@@ -140,7 +164,7 @@ Scale=0.5:
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 1008, 0, 1]
[8, -100, 0, 1]
]
},
{
......@@ -150,12 +174,22 @@ Scale=0.5:
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
[8, 1008, 0, 1]
]
},
{
"id": 4,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
]
},
{
"id": 5,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
......@@ -197,6 +231,13 @@ Scale=1.5:
"backgroundColor": "#C0C0C0",
"transform": 4
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 5
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
......@@ -224,7 +265,7 @@ Scale=1.5:
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, 1008, 0, 1]
[8, -100, 0, 1]
]
},
{
......@@ -234,12 +275,22 @@ Scale=1.5:
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
[8, 1008, 0, 1]
]
},
{
"id": 4,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
]
},
{
"id": 5,
"parent": 1,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
......
......@@ -11,6 +11,16 @@
"bounds": [10, 10],
"transform": 1
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"transform": 2
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10],
"transform": 3
},
{
"name": "LayoutNGBlockFlow (positioned) DIV class='fixed'",
"bounds": [10, 10]
......@@ -30,6 +40,24 @@
[0, 0, 1, 0],
[8, 1013, 0, 1]
]
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[8, -100, 0, 1]
]
},
{
"id": 3,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[1000, 0, 0, 1]
]
}
]
}
......
......@@ -9,11 +9,18 @@
},
{
"name": "LayoutNGBlockFlow (positioned) DIV",
"bounds": [99, 99],
"bounds": [88, 88],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 2
},
{
"name": "LayoutNGBlockFlow (positioned) DIV",
"bounds": [99, 99],
"contentsOpaque": true,
"backgroundColor": "#C0C0C0",
"transform": 3
},
{
"name": "VerticalScrollbar",
"position": [785, 0],
......@@ -32,6 +39,15 @@
},
{
"id": 2,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[100, -300, 0, 1]
]
},
{
"id": 3,
"transform": [
[1, 0, 0, 0],
[0, 1, 0, 0],
......
......@@ -6,9 +6,8 @@
"contentsOpaque": true,
"backgroundColor": "#FFFFFF",
"invalidations": [
[450, 0, 218, 236],
[0, 0, 668, 236],
[704, 0, 214, 232],
[0, 0, 214, 232],
[700, 217, 4, 19]
]
},
......
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