Skip to content

Commit

Permalink
Revert "Remove layer integral offset snapping (flutter#17712)" (flutt…
Browse files Browse the repository at this point in the history
…er#17785)

This reverts commit 99f8d00.

I found some problems. Will revise and reland later, and put more details about the problems in the new PR.

TBR: @chinmaygarde @flar
  • Loading branch information
liyuqian authored Apr 17, 2020
1 parent fb208b4 commit b5aedb3
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 33 deletions.
9 changes: 9 additions & 0 deletions flow/layers/image_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
if (!context->has_platform_view && context->raster_cache &&
SkRect::Intersects(context->cull_rect, paint_bounds())) {
SkMatrix ctm = matrix;
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
ctm = RasterCache::GetIntegralTransCTM(ctm);
#endif
context->raster_cache->Prepare(context, this, ctm);
}
}
Expand All @@ -39,6 +42,12 @@ void ImageFilterLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ImageFilterLayer::Paint");
FML_DCHECK(needs_painting());

#ifndef SUPPORT_FRACTIONAL_TRANSLATION
SkAutoCanvasRestore save(context.leaf_nodes_canvas, true);
context.leaf_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif

if (context.raster_cache) {
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
RasterCacheResult layer_cache =
Expand Down
68 changes: 43 additions & 25 deletions flow/layers/image_filter_layer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,14 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) {
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 2}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
}));
}
Expand Down Expand Up @@ -93,11 +96,14 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) {
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 2}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
}));
}
Expand Down Expand Up @@ -126,11 +132,14 @@ TEST_F(ImageFilterLayerTest, SimpleFilterBounds) {
layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}},
1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 2}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path, child_paint}},
2, MockCanvas::DrawPathData{child_path, child_paint}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
}));
}
Expand Down Expand Up @@ -168,16 +177,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(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{children_bounds, filter_paint,
nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(ImageFilterLayerTest, Nested) {
Expand Down Expand Up @@ -225,16 +237,22 @@ TEST_F(ImageFilterLayerTest, Nested) {
layer1->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
nullptr, 1}},
1, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
nullptr, 2}},
MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path1, child_paint1}},
2, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{2, MockCanvas::SaveData{3}},
MockCanvas::DrawCall{3, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(),
filter_paint2, nullptr, 2}},
3, MockCanvas::SaveLayerData{child_path2.getBounds(),
filter_paint2, nullptr, 4}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child_path2, child_paint2}},
4, MockCanvas::DrawPathData{child_path2, child_paint2}},
MockCanvas::DrawCall{4, MockCanvas::RestoreData{3}},
MockCanvas::DrawCall{3, MockCanvas::RestoreData{2}},
MockCanvas::DrawCall{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
}));
Expand Down
11 changes: 10 additions & 1 deletion flow/layers/opacity_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
if (!context->has_platform_view && context->raster_cache &&
SkRect::Intersects(context->cull_rect, paint_bounds())) {
SkMatrix ctm = child_matrix;
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
ctm = RasterCache::GetIntegralTransCTM(ctm);
#endif
context->raster_cache->Prepare(context, container, ctm);
}
}
Expand All @@ -66,6 +69,11 @@ void OpacityLayer::Paint(PaintContext& context) const {
SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->translate(offset_.fX, offset_.fY);

#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context.internal_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif

if (context.raster_cache) {
ContainerLayer* container = GetChildContainer();
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
Expand All @@ -79,7 +87,8 @@ void OpacityLayer::Paint(PaintContext& context) const {
// Skia may clip the content with saveLayerBounds (although it's not a
// guaranteed clip). So we have to provide a big enough saveLayerBounds. To do
// so, we first remove the offset from paint bounds since it's already in the
// matrix. Then we round out the bounds.
// matrix. Then we round out the bounds because of our
// RasterCache::GetIntegralTransCTM optimization.
//
// Note that the following lines are only accessible when the raster cache is
// not available (e.g., when we're using the software backend in golden
Expand Down
39 changes: 39 additions & 0 deletions flow/layers/opacity_layer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ TEST_F(OpacityLayerTest, FullyOpaque) {
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f);
const SkMatrix layer_transform =
SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
const SkMatrix integral_layer_transform = RasterCache::GetIntegralTransCTM(
SkMatrix::Concat(initial_transform, layer_transform));
#endif
const SkPaint child_paint = SkPaint(SkColors::kGreen);
const SkRect expected_layer_bounds =
layer_transform.mapRect(child_path.getBounds());
Expand All @@ -82,6 +86,10 @@ TEST_F(OpacityLayerTest, FullyOpaque) {
auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer_transform}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr,
2}},
Expand All @@ -99,6 +107,10 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f);
const SkMatrix layer_transform =
SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
const SkMatrix integral_layer_transform = RasterCache::GetIntegralTransCTM(
SkMatrix::Concat(initial_transform, layer_transform));
#endif
const SkPaint child_paint = SkPaint(SkColors::kGreen);
const SkRect expected_layer_bounds =
layer_transform.mapRect(child_path.getBounds());
Expand All @@ -121,6 +133,10 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer_transform}},
#endif
MockCanvas::DrawCall{1, MockCanvas::SaveData{2}},
MockCanvas::DrawCall{
2, MockCanvas::ClipRectData{kEmptyRect, SkClipOp::kIntersect,
Expand All @@ -139,6 +155,10 @@ TEST_F(OpacityLayerTest, HalfTransparent) {
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f);
const SkMatrix layer_transform =
SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
const SkMatrix integral_layer_transform = RasterCache::GetIntegralTransCTM(
SkMatrix::Concat(initial_transform, layer_transform));
#endif
const SkPaint child_paint = SkPaint(SkColors::kGreen);
const SkRect expected_layer_bounds =
layer_transform.mapRect(child_path.getBounds());
Expand All @@ -165,6 +185,10 @@ TEST_F(OpacityLayerTest, HalfTransparent) {
auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer_transform}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr,
2}},
Expand All @@ -187,6 +211,13 @@ TEST_F(OpacityLayerTest, Nested) {
SkMatrix::MakeTrans(layer1_offset.fX, layer1_offset.fY);
const SkMatrix layer2_transform =
SkMatrix::MakeTrans(layer2_offset.fX, layer2_offset.fY);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
const SkMatrix integral_layer1_transform = RasterCache::GetIntegralTransCTM(
SkMatrix::Concat(initial_transform, layer1_transform));
const SkMatrix integral_layer2_transform = RasterCache::GetIntegralTransCTM(
SkMatrix::Concat(SkMatrix::Concat(initial_transform, layer1_transform),
layer2_transform));
#endif
const SkPaint child1_paint = SkPaint(SkColors::kRed);
const SkPaint child2_paint = SkPaint(SkColors::kBlue);
const SkPaint child3_paint = SkPaint(SkColors::kGreen);
Expand Down Expand Up @@ -247,13 +278,21 @@ TEST_F(OpacityLayerTest, Nested) {
auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer1_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer1_transform}},
#endif
MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{opacity1_bounds, opacity1_paint,
nullptr, 2}},
MockCanvas::DrawCall{
2, MockCanvas::DrawPathData{child1_path, child1_paint}},
MockCanvas::DrawCall{2, MockCanvas::SaveData{3}},
MockCanvas::DrawCall{3, MockCanvas::ConcatMatrixData{layer2_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
3, MockCanvas::SetMatrixData{integral_layer2_transform}},
#endif
MockCanvas::DrawCall{
3, MockCanvas::SaveLayerData{opacity2_bounds, opacity2_paint,
nullptr, 4}},
Expand Down
7 changes: 7 additions & 0 deletions flow/layers/picture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {

SkMatrix ctm = matrix;
ctm.postTranslate(offset_.x(), offset_.y());
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
ctm = RasterCache::GetIntegralTransCTM(ctm);
#endif
cache->Prepare(context->gr_context, sk_picture, ctm,
context->dst_color_space, is_complex_, will_change_);
}
Expand All @@ -41,6 +44,10 @@ void PictureLayer::Paint(PaintContext& context) const {

SkAutoCanvasRestore save(context.leaf_nodes_canvas, true);
context.leaf_nodes_canvas->translate(offset_.x(), offset_.y());
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
context.leaf_nodes_canvas->setMatrix(RasterCache::GetIntegralTransCTM(
context.leaf_nodes_canvas->getTotalMatrix()));
#endif

if (context.raster_cache) {
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
Expand Down
19 changes: 14 additions & 5 deletions flow/layers/picture_layer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include "flutter/testing/mock_canvas.h"
#include "third_party/skia/include/core/SkPicture.h"

#ifndef SUPPORT_FRACTIONAL_TRANSLATION
#include "flutter/flow/raster_cache.h"
#endif

namespace flutter {
namespace testing {

Expand Down Expand Up @@ -81,11 +85,16 @@ TEST_F(PictureLayerTest, SimplePicture) {
EXPECT_FALSE(layer->needs_system_composite());

layer->Paint(paint_context());
auto expected_draw_calls =
std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{
1, MockCanvas::ConcatMatrixData{layer_offset_matrix}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1,
MockCanvas::ConcatMatrixData{layer_offset_matrix}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{RasterCache::GetIntegralTransCTM(
layer_offset_matrix)}},
#endif
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}});
EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
}

Expand Down
7 changes: 7 additions & 0 deletions flow/raster_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ class RasterCache {
return bounds;
}

static SkMatrix GetIntegralTransCTM(const SkMatrix& ctm) {
SkMatrix result = ctm;
result[SkMatrix::kMTransX] = SkScalarRoundToScalar(ctm.getTranslateX());
result[SkMatrix::kMTransY] = SkScalarRoundToScalar(ctm.getTranslateY());
return result;
}

// Return true if the cache is generated.
//
// We may return false and not generate the cache if
Expand Down
7 changes: 5 additions & 2 deletions flow/raster_cache_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ template <typename ID>
class RasterCacheKey {
public:
RasterCacheKey(ID id, const SkMatrix& ctm) : id_(id), matrix_(ctm) {
matrix_[SkMatrix::kMTransX] = 0;
matrix_[SkMatrix::kMTransY] = 0;
matrix_[SkMatrix::kMTransX] = SkScalarFraction(ctm.getTranslateX());
matrix_[SkMatrix::kMTransY] = SkScalarFraction(ctm.getTranslateY());
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
FML_DCHECK(matrix_.getTranslateX() == 0 && matrix_.getTranslateY() == 0);
#endif
}

ID id() const { return id_; }
Expand Down

0 comments on commit b5aedb3

Please sign in to comment.