All layers with raster cache should use integer CTM (flutter/engine#33981)

This commit is contained in:
Matej Knopp 2022-06-13 19:43:03 +02:00 committed by GitHub
parent 462ca5e5ce
commit 12613fdb21
11 changed files with 270 additions and 135 deletions

View File

@ -59,6 +59,9 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{layer->paint_bounds(), clip_paint,
nullptr, 2}},
@ -150,6 +153,9 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},
@ -232,6 +238,9 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{
1, MockCanvas::ClipRectData{layer_bounds, SkClipOp::kIntersect,
MockCanvas::kSoft_ClipEdgeStyle}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
1,
MockCanvas::SaveLayerData{child_bounds, clip_paint, nullptr, 2}},

View File

@ -479,6 +479,11 @@ TEST_F(ClipPathLayerTest, OpacityInheritanceSaveLayerPainting) {
/* ClipRectLayer::Paint() */ {
expected_builder.save();
expected_builder.clipPath(layer_clip, SkClipOp::kIntersect, true);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
/* ClipShapeLayer::Paint() Integer CTM */
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
#endif
expected_builder.setColor(opacity_alpha << 24);
expected_builder.saveLayer(&children_bounds, true);
/* child layer1 paint */ {

View File

@ -469,6 +469,11 @@ TEST_F(ClipRectLayerTest, OpacityInheritanceSaveLayerPainting) {
/* ClipRectLayer::Paint() */ {
expected_builder.save();
expected_builder.clipRect(clip_rect, SkClipOp::kIntersect, true);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
/* ClipShapeLayer::Paint() Integer CTM */
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
#endif
expected_builder.setColor(opacity_alpha << 24);
expected_builder.saveLayer(&children_bounds, true);
/* child layer1 paint */ {

View File

@ -479,6 +479,11 @@ TEST_F(ClipRRectLayerTest, OpacityInheritanceSaveLayerPainting) {
/* ClipRectLayer::Paint() */ {
expected_builder.save();
expected_builder.clipRRect(clip_r_rect, SkClipOp::kIntersect, true);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
/* ClipShapeLayer::Paint() Integer CTM */
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
#endif
expected_builder.setColor(opacity_alpha << 24);
expected_builder.saveLayer(&children_bounds, true);
/* child layer1 paint */ {

View File

@ -31,6 +31,12 @@ class ClipShapeLayer : public ContainerLayer {
context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer));
}
}
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
if (UsesSaveLayer()) {
context->SetTransform(
RasterCache::GetIntegralTransCTM(context->GetTransform()));
}
#endif
if (context->PushCullRect(clip_shape_bounds())) {
DiffChildren(context, prev);
}
@ -61,7 +67,11 @@ class ClipShapeLayer : public ContainerLayer {
if (UsesSaveLayer()) {
context->subtree_can_inherit_opacity = true;
if (render_count_ >= kMinimumRendersBeforeCachingLayer) {
TryToPrepareRasterCache(context, this, matrix,
SkMatrix child_matrix(matrix);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
#endif
TryToPrepareRasterCache(context, this, child_matrix,
RasterCacheLayerStrategy::kLayer);
} else {
render_count_++;
@ -83,6 +93,11 @@ class ClipShapeLayer : public ContainerLayer {
return;
}
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif
AutoCachePaint cache_paint(context);
if (context.raster_cache &&
context.raster_cache->Draw(this, *context.leaf_nodes_canvas,

View File

@ -19,6 +19,11 @@ void ColorFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
}
}
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context->SetTransform(
RasterCache::GetIntegralTransCTM(context->GetTransform()));
#endif
DiffChildren(context, prev);
context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
@ -34,12 +39,17 @@ void ColorFilterLayer::Preroll(PrerollContext* context,
// can always apply opacity in those cases.
context->subtree_can_inherit_opacity = true;
SkMatrix child_matrix(matrix);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
#endif
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
TryToPrepareRasterCache(context, this, matrix,
TryToPrepareRasterCache(context, this, child_matrix,
RasterCacheLayerStrategy::kLayer);
} else {
render_count_++;
TryToPrepareRasterCache(context, this, matrix,
TryToPrepareRasterCache(context, this, child_matrix,
RasterCacheLayerStrategy::kLayerChildren);
}
}
@ -50,6 +60,11 @@ void ColorFilterLayer::Paint(PaintContext& context) const {
AutoCachePaint cache_paint(context);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif
if (context.raster_cache) {
if (context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
RasterCacheLayerStrategy::kLayer,

View File

@ -63,14 +63,17 @@ TEST_F(ColorFilterLayerTest, EmptyFilter) {
SkPaint filter_paint;
filter_paint.setColorFilter(nullptr);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ColorFilterLayerTest, SimpleFilter) {
@ -93,14 +96,17 @@ TEST_F(ColorFilterLayerTest, SimpleFilter) {
SkPaint filter_paint;
filter_paint.setColorFilter(layer_filter);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ColorFilterLayerTest, MultipleChildren) {
@ -135,16 +141,19 @@ TEST_F(ColorFilterLayerTest, MultipleChildren) {
SkPaint filter_paint;
filter_paint.setColorFilter(layer_filter);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds,
filter_paint, nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, filter_paint,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ColorFilterLayerTest, Nested) {
@ -187,20 +196,26 @@ TEST_F(ColorFilterLayerTest, Nested) {
filter_paint1.setColorFilter(layer_filter1);
filter_paint2.setColorFilter(layer_filter2);
layer1->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds,
filter_paint1, nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(),
filter_paint2, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(),
filter_paint2, nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ColorFilterLayerTest, Readback) {
@ -356,19 +371,22 @@ TEST_F(ColorFilterLayerTest, OpacityInheritance) {
SkMatrix::Translate(offset.fX, offset.fY));
#endif
DisplayListBuilder expected_builder;
/* opacity_layer::Paint() */ {
/* OpacityLayer::Paint() */ {
expected_builder.save();
{
expected_builder.translate(offset.fX, offset.fY);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
/* Integer CTM in ColorFilterLayer::Paint() */
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
#endif
/* image_filter_layer::Paint() */ {
/* ColorFilterLayer::Paint() */ {
expected_builder.setColor(opacity_alpha << 24);
expected_builder.setColorFilter(&layer_filter);
expected_builder.saveLayer(&child_path.getBounds(), true);
/* mock_layer::Paint() */ {
/* MockLayer::Paint() */ {
expected_builder.setColor(0xFF000000);
expected_builder.setColorFilter(nullptr);
expected_builder.drawPath(child_path);

View File

@ -21,6 +21,11 @@ void ImageFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
}
}
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context->SetTransform(
RasterCache::GetIntegralTransCTM(context->GetTransform()));
#endif
if (filter_) {
auto filter = filter_->makeWithLocalMatrix(context->GetTransform());
if (filter) {
@ -62,13 +67,18 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
set_paint_bounds(child_bounds);
SkMatrix child_matrix(matrix);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
#endif
transformed_filter_ = nullptr;
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
// We have rendered this same ImageFilterLayer object enough
// times to consider its properties and children to be stable
// from frame to frame so we try to cache the layer itself
// for maximum performance.
TryToPrepareRasterCache(context, this, matrix,
TryToPrepareRasterCache(context, this, child_matrix,
RasterCacheLayerStrategy::kLayer);
} else {
// This ImageFilterLayer is not yet considered stable so we
@ -83,7 +93,7 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
// instances can do this operation on some transforms and some
// (filters or transforms) cannot. We can only cache the children
// and apply the filter on the fly if this operation succeeds.
transformed_filter_ = filter_->makeWithLocalMatrix(matrix);
transformed_filter_ = filter_->makeWithLocalMatrix(child_matrix);
if (transformed_filter_) {
// With a modified SkImageFilter we can now try to cache the
// children to avoid their rendering costs if they remain
@ -102,6 +112,11 @@ void ImageFilterLayer::Paint(PaintContext& context) const {
AutoCachePaint cache_paint(context);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif
if (context.raster_cache) {
if (context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
RasterCacheLayerStrategy::kLayer,

View File

@ -63,6 +63,9 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) {
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
@ -98,6 +101,9 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) {
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
@ -133,6 +139,9 @@ TEST_F(ImageFilterLayerTest, SimpleFilterBounds) {
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
@ -177,16 +186,19 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) {
SkPaint filter_paint;
filter_paint.setImageFilter(layer_filter);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds,
filter_paint, nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, filter_paint,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ImageFilterLayerTest, Nested) {
@ -238,11 +250,18 @@ TEST_F(ImageFilterLayerTest, Nested) {
layer1->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(),
filter_paint2, nullptr, 2}},
@ -407,19 +426,22 @@ TEST_F(ImageFilterLayerTest, OpacityInheritance) {
#endif
auto dl_image_filter = DlImageFilter::From(layer_filter);
DisplayListBuilder expected_builder;
/* opacity_layer::Paint() */ {
/* OpacityLayer::Paint() */ {
expected_builder.save();
{
expected_builder.translate(offset.fX, offset.fY);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
/* Integer CTM in ImageFilterLayer::Paint() */
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
#endif
/* image_filter_layer::Paint() */ {
/* ImageFilterLayer::Paint() */ {
expected_builder.setColor(opacity_alpha << 24);
expected_builder.setImageFilter(dl_image_filter.get());
expected_builder.saveLayer(&child_path.getBounds(), true);
/* mock_layer::Paint() */ {
/* MockLayer::Paint() */ {
expected_builder.setColor(child_paint.getColor());
expected_builder.setImageFilter(nullptr);
expected_builder.drawPath(child_path);

View File

@ -25,6 +25,11 @@ void ShaderMaskLayer::Diff(DiffContext* context, const Layer* old_layer) {
}
}
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context->SetTransform(
RasterCache::GetIntegralTransCTM(context->GetTransform()));
#endif
DiffChildren(context, prev);
context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
@ -39,8 +44,13 @@ void ShaderMaskLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
// so we can always apply opacity in any of those cases.
context->subtree_can_inherit_opacity = true;
SkMatrix child_matrix(matrix);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
child_matrix = RasterCache::GetIntegralTransCTM(child_matrix);
#endif
if (render_count_ >= kMinimumRendersBeforeCachingFilterLayer) {
TryToPrepareRasterCache(context, this, matrix,
TryToPrepareRasterCache(context, this, child_matrix,
RasterCacheLayerStrategy::kLayer);
} else {
render_count_++;
@ -53,6 +63,11 @@ void ShaderMaskLayer::Paint(PaintContext& context) const {
AutoCachePaint cache_paint(context);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif
if (context.raster_cache &&
context.raster_cache->Draw(this, *context.leaf_nodes_canvas,
RasterCacheLayerStrategy::kLayer,

View File

@ -71,20 +71,22 @@ TEST_F(ShaderMaskLayerTest, EmptyFilter) {
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, SkPaint(),
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{
1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(
layer_bounds.width(),
layer_bounds.height()),
filter_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0,
MockCanvas::SaveLayerData{child_bounds, SkPaint(), nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(layer_bounds.width(),
layer_bounds.height()),
filter_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ShaderMaskLayerTest, SimpleFilter) {
@ -112,20 +114,22 @@ TEST_F(ShaderMaskLayerTest, SimpleFilter) {
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, SkPaint(),
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{
1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(
layer_bounds.width(),
layer_bounds.height()),
filter_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0,
MockCanvas::SaveLayerData{child_bounds, SkPaint(), nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(layer_bounds.width(),
layer_bounds.height()),
filter_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ShaderMaskLayerTest, MultipleChildren) {
@ -165,22 +169,24 @@ TEST_F(ShaderMaskLayerTest, MultipleChildren) {
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, SkPaint(),
nullptr, 1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{
1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(
layer_bounds.width(),
layer_bounds.height()),
filter_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), nullptr,
1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(layer_bounds.width(),
layer_bounds.height()),
filter_paint}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ShaderMaskLayerTest, Nested) {
@ -230,35 +236,37 @@ TEST_F(ShaderMaskLayerTest, Nested) {
layer1->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector(
{MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), nullptr,
1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(), SkPaint(),
nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{2,
MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
2,
MockCanvas::DrawRectData{
SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()),
filter_paint2}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1,
MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1,
MockCanvas::DrawRectData{
SkRect::MakeWH(layer_bounds.width(), layer_bounds.height()),
filter_paint1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
std::vector({
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, SkPaint(), nullptr,
1}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkM44()}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(), SkPaint(),
nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{2, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
2, MockCanvas::DrawRectData{SkRect::MakeWH(layer_bounds.width(),
layer_bounds.height()),
filter_paint2}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{SkM44::Translate(
layer_bounds.fLeft, layer_bounds.fTop)}},
MockCanvas::DrawCall{
1, MockCanvas::DrawRectData{SkRect::MakeWH(layer_bounds.width(),
layer_bounds.height()),
filter_paint1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}
TEST_F(ShaderMaskLayerTest, Readback) {
@ -354,6 +362,9 @@ TEST_F(ShaderMaskLayerTest, OpacityInheritance) {
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
/* Integer CTM in ShaderMaskLayer::Paint() */
expected_builder.transformReset();
expected_builder.transform(opacity_integer_transform);
#endif
/* ShaderMaskLayer::Paint() */ {
expected_builder.setColor(opacity_alpha << 24);