Skip to content

Commit 7aa8484

Browse files
authored
All layers with raster cache should use integer CTM (flutter#33981)
1 parent d2b31e7 commit 7aa8484

11 files changed

+270
-135
lines changed

flow/layers/checkerboard_layertree_unittests.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) {
5959
MockCanvas::DrawCall{
6060
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
6161
MockCanvas::kSoft_ClipEdgeStyle}},
62+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
63+
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
64+
#endif
6265
MockCanvas::DrawCall{
6366
1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint,
6467
nullptr, 2}},
@@ -150,6 +153,9 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) {
150153
MockCanvas::DrawCall{
151154
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
152155
MockCanvas::kSoft_ClipEdgeStyle}},
156+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
157+
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
158+
#endif
153159
MockCanvas::DrawCall{
154160
1,
155161
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},
@@ -232,6 +238,9 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) {
232238
MockCanvas::DrawCall{
233239
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
234240
MockCanvas::kSoft_ClipEdgeStyle}},
241+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
242+
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
243+
#endif
235244
MockCanvas::DrawCall{
236245
1,
237246
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},

flow/layers/clip_path_layer_unittests.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,11 @@ TEST_F(ClipPathLayerTest, OpacityInheritanceSaveLayerPainting) {
479479
/* ClipRectLayer::Paint() */ {
480480
expected_builder.save();
481481
expected_builder.clipPath(layer_clip, SkClipOp::kIntersect, true);
482+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
483+
/* ClipShapeLayer::Paint() Integer CTM */
484+
expected_builder.transformReset();
485+
expected_builder.transform(opacity_integer_transform);
486+
#endif
482487
expected_builder.setColor(opacity_alpha << 24);
483488
expected_builder.saveLayer(&children_bounds, true);
484489
/* child layer1 paint */ {

flow/layers/clip_rect_layer_unittests.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ TEST_F(ClipRectLayerTest, OpacityInheritanceSaveLayerPainting) {
469469
/* ClipRectLayer::Paint() */ {
470470
expected_builder.save();
471471
expected_builder.clipRect(clip_rect, SkClipOp::kIntersect, true);
472+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
473+
/* ClipShapeLayer::Paint() Integer CTM */
474+
expected_builder.transformReset();
475+
expected_builder.transform(opacity_integer_transform);
476+
#endif
472477
expected_builder.setColor(opacity_alpha << 24);
473478
expected_builder.saveLayer(&children_bounds, true);
474479
/* child layer1 paint */ {

flow/layers/clip_rrect_layer_unittests.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,11 @@ TEST_F(ClipRRectLayerTest, OpacityInheritanceSaveLayerPainting) {
479479
/* ClipRectLayer::Paint() */ {
480480
expected_builder.save();
481481
expected_builder.clipRRect(clip_r_rect, SkClipOp::kIntersect, true);
482+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
483+
/* ClipShapeLayer::Paint() Integer CTM */
484+
expected_builder.transformReset();
485+
expected_builder.transform(opacity_integer_transform);
486+
#endif
482487
expected_builder.setColor(opacity_alpha << 24);
483488
expected_builder.saveLayer(&children_bounds, true);
484489
/* child layer1 paint */ {

flow/layers/clip_shape_layer.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ class ClipShapeLayer : public ContainerLayer {
3131
context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer));
3232
}
3333
}
34+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
35+
if (UsesSaveLayer()) {
36+
context->SetTransform(
37+
RasterCache::GetIntegralTransCTM(context->GetTransform()));
38+
}
39+
#endif
3440
if (context->PushCullRect(clip_shape_bounds())) {
3541
DiffChildren(context, prev);
3642
}
@@ -61,7 +67,11 @@ class ClipShapeLayer : public ContainerLayer {
6167
if (UsesSaveLayer()) {
6268
context->subtree_can_inherit_opacity = true;
6369
if (render_count_ >= kMinimumRendersBeforeCachingLayer) {
64-
TryToPrepareRasterCache(context, this, matrix,
70+
SkMatrix child_matrix(matrix);
71+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
72+
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
73+
#endif
74+
TryToPrepareRasterCache(context, this, child_matrix,
6575
RasterCacheLayerStrategy::kLayer);
6676
} else {
6777
render_count_++;
@@ -83,6 +93,11 @@ class ClipShapeLayer : public ContainerLayer {
8393
return;
8494
}
8595

96+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
97+
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
98+
context.leaf_nodes_canvas->getTotalMatrix()));
99+
#endif
100+
86101
AutoCachePaint cache_paint(context);
87102
if (context.raster_cache &&
88103
context.raster_cache->Draw(this, *context.leaf_nodes_canvas,

flow/layers/color_filter_layer.cc

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ void ColorFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
1919
}
2020
}
2121

22+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
23+
context->SetTransform(
24+
RasterCache::GetIntegralTransCTM(context->GetTransform()));
25+
#endif
26+
2227
DiffChildren(context, prev);
2328

2429
context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
@@ -34,12 +39,17 @@ void ColorFilterLayer::Preroll(PrerollContext* context,
3439
// can always apply opacity in those cases.
3540
context->subtree_can_inherit_opacity = true;
3641

42+
SkMatrix child_matrix(matrix);
43+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
44+
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
45+
#endif
46+
3747
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
38-
TryToPrepareRasterCache(context, this, matrix,
48+
TryToPrepareRasterCache(context, this, child_matrix,
3949
RasterCacheLayerStrategy::kLayer);
4050
} else {
4151
render_count_++;
42-
TryToPrepareRasterCache(context, this, matrix,
52+
TryToPrepareRasterCache(context, this, child_matrix,
4353
RasterCacheLayerStrategy::kLayerChildren);
4454
}
4555
}
@@ -50,6 +60,11 @@ void ColorFilterLayer::Paint(PaintContext& context) const {
5060

5161
AutoCachePaint cache_paint(context);
5262

63+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
64+
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
65+
context.leaf_nodes_canvas->getTotalMatrix()));
66+
#endif
67+
5368
if (context.raster_cache) {
5469
if (context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
5570
RasterCacheLayerStrategy::kLayer,

flow/layers/color_filter_layer_unittests.cc

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,17 @@ TEST_F(ColorFilterLayerTest, EmptyFilter) {
6363
SkPaint filter_paint;
6464
filter_paint.setColorFilter(nullptr);
6565
layer->Paint(paint_context());
66-
EXPECT_EQ(
67-
mock_canvas().draw_calls(),
68-
std::vector({MockCanvas::DrawCall{
69-
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
70-
nullptr, 1}},
71-
MockCanvas::DrawCall{
72-
1, MockCanvas::DrawPathData{child_path, child_paint}},
73-
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
66+
EXPECT_EQ(mock_canvas().draw_calls(),
67+
std::vector({
68+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
69+
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
70+
#endif
71+
MockCanvas::DrawCall{
72+
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
73+
nullptr, 1}},
74+
MockCanvas::DrawCall{
75+
1, MockCanvas::DrawPathData{child_path, child_paint}},
76+
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
7477
}
7578

7679
TEST_F(ColorFilterLayerTest, SimpleFilter) {
@@ -93,14 +96,17 @@ TEST_F(ColorFilterLayerTest, SimpleFilter) {
9396
SkPaint filter_paint;
9497
filter_paint.setColorFilter(layer_filter);
9598
layer->Paint(paint_context());
96-
EXPECT_EQ(
97-
mock_canvas().draw_calls(),
98-
std::vector({MockCanvas::DrawCall{
99-
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
100-
nullptr, 1}},
101-
MockCanvas::DrawCall{
102-
1, MockCanvas::DrawPathData{child_path, child_paint}},
103-
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
99+
EXPECT_EQ(mock_canvas().draw_calls(),
100+
std::vector({
101+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
102+
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
103+
#endif
104+
MockCanvas::DrawCall{
105+
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
106+
nullptr, 1}},
107+
MockCanvas::DrawCall{
108+
1, MockCanvas::DrawPathData{child_path, child_paint}},
109+
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
104110
}
105111

106112
TEST_F(ColorFilterLayerTest, MultipleChildren) {
@@ -135,16 +141,19 @@ TEST_F(ColorFilterLayerTest, MultipleChildren) {
135141
SkPaint filter_paint;
136142
filter_paint.setColorFilter(layer_filter);
137143
layer->Paint(paint_context());
138-
EXPECT_EQ(
139-
mock_canvas().draw_calls(),
140-
std::vector({MockCanvas::DrawCall{
141-
0, MockCanvas::SaveLayerData{children_bounds,
142-
filter_paint, nullptr, 1}},
143-
MockCanvas::DrawCall{
144-
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
145-
MockCanvas::DrawCall{
146-
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
147-
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
144+
EXPECT_EQ(mock_canvas().draw_calls(),
145+
std::vector({
146+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
147+
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
148+
#endif
149+
MockCanvas::DrawCall{
150+
0, MockCanvas::SaveLayerData{children_bounds, filter_paint,
151+
nullptr, 1}},
152+
MockCanvas::DrawCall{
153+
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
154+
MockCanvas::DrawCall{
155+
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
156+
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
148157
}
149158

150159
TEST_F(ColorFilterLayerTest, Nested) {
@@ -187,20 +196,26 @@ TEST_F(ColorFilterLayerTest, Nested) {
187196
filter_paint1.setColorFilter(layer_filter1);
188197
filter_paint2.setColorFilter(layer_filter2);
189198
layer1->Paint(paint_context());
190-
EXPECT_EQ(
191-
mock_canvas().draw_calls(),
192-
std::vector({MockCanvas::DrawCall{
193-
0, MockCanvas::SaveLayerData{children_bounds,
194-
filter_paint1, nullptr, 1}},
195-
MockCanvas::DrawCall{
196-
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
197-
MockCanvas::DrawCall{
198-
1, MockCanvas::SaveLayerData{child_path2.getBounds(),
199-
filter_paint2, nullptr, 2}},
200-
MockCanvas::DrawCall{
201-
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
202-
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
203-
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
199+
EXPECT_EQ(mock_canvas().draw_calls(),
200+
std::vector({
201+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
202+
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
203+
#endif
204+
MockCanvas::DrawCall{
205+
0, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
206+
nullptr, 1}},
207+
MockCanvas::DrawCall{
208+
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
209+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
210+
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
211+
#endif
212+
MockCanvas::DrawCall{
213+
1, MockCanvas::SaveLayerData{child_path2.getBounds(),
214+
filter_paint2, nullptr, 2}},
215+
MockCanvas::DrawCall{
216+
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
217+
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
218+
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
204219
}
205220

206221
TEST_F(ColorFilterLayerTest, Readback) {
@@ -356,19 +371,22 @@ TEST_F(ColorFilterLayerTest, OpacityInheritance) {
356371
SkMatrix::Translate(offset.fX, offset.fY));
357372
#endif
358373
DisplayListBuilder expected_builder;
359-
/* opacity_layer::Paint() */ {
374+
/* OpacityLayer::Paint() */ {
360375
expected_builder.save();
361376
{
362377
expected_builder.translate(offset.fX, offset.fY);
363378
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
364379
expected_builder.transformReset();
365380
expected_builder.transform(opacity_integer_transform);
381+
/* Integer CTM in ColorFilterLayer::Paint() */
382+
expected_builder.transformReset();
383+
expected_builder.transform(opacity_integer_transform);
366384
#endif
367-
/* image_filter_layer::Paint() */ {
385+
/* ColorFilterLayer::Paint() */ {
368386
expected_builder.setColor(opacity_alpha << 24);
369387
expected_builder.setColorFilter(&layer_filter);
370388
expected_builder.saveLayer(&child_path.getBounds(), true);
371-
/* mock_layer::Paint() */ {
389+
/* MockLayer::Paint() */ {
372390
expected_builder.setColor(0xFF000000);
373391
expected_builder.setColorFilter(nullptr);
374392
expected_builder.drawPath(child_path);

flow/layers/image_filter_layer.cc

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ void ImageFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
2121
}
2222
}
2323

24+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
25+
context->SetTransform(
26+
RasterCache::GetIntegralTransCTM(context->GetTransform()));
27+
#endif
28+
2429
if (filter_) {
2530
auto filter = filter_->makeWithLocalMatrix(context->GetTransform());
2631
if (filter) {
@@ -62,13 +67,18 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
6267

6368
set_paint_bounds(child_bounds);
6469

70+
SkMatrix child_matrix(matrix);
71+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
72+
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
73+
#endif
74+
6575
transformed_filter_ = nullptr;
6676
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
6777
// We have rendered this same ImageFilterLayer object enough
6878
// times to consider its properties and children to be stable
6979
// from frame to frame so we try to cache the layer itself
7080
// for maximum performance.
71-
TryToPrepareRasterCache(context, this, matrix,
81+
TryToPrepareRasterCache(context, this, child_matrix,
7282
RasterCacheLayerStrategy::kLayer);
7383
} else {
7484
// This ImageFilterLayer is not yet considered stable so we
@@ -83,7 +93,7 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
8393
// instances can do this operation on some transforms and some
8494
// (filters or transforms) cannot. We can only cache the children
8595
// and apply the filter on the fly if this operation succeeds.
86-
transformed_filter_ = filter_->makeWithLocalMatrix(matrix);
96+
transformed_filter_ = filter_->makeWithLocalMatrix(child_matrix);
8797
if (transformed_filter_) {
8898
// With a modified SkImageFilter we can now try to cache the
8999
// children to avoid their rendering costs if they remain
@@ -102,6 +112,11 @@ void ImageFilterLayer::Paint(PaintContext& context) const {
102112

103113
AutoCachePaint cache_paint(context);
104114

115+
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
116+
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
117+
context.leaf_nodes_canvas->getTotalMatrix()));
118+
#endif
119+
105120
if (context.raster_cache) {
106121
if (context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
107122
RasterCacheLayerStrategy::kLayer,

0 commit comments

Comments
 (0)