Skip to content

Commit

Permalink
Fix preroll matrix snapping (flutter#36213)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams committed Sep 16, 2022
1 parent efd64fd commit 1692276
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 12 deletions.
4 changes: 2 additions & 2 deletions flow/layers/color_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ void ColorFilterLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context);
AutoCache cache = AutoCache(layer_raster_cache_item_.get(), context, matrix);

SkMatrix child_matrix = matrix;
if (context->raster_cache) {
child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix);
}
AutoCache cache =
AutoCache(layer_raster_cache_item_.get(), context, child_matrix);

ContainerLayer::Preroll(context, child_matrix);
// We always use a saveLayer (or a cached rendering), so we
Expand Down
10 changes: 6 additions & 4 deletions flow/layers/image_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,16 @@ void ImageFilterLayer::Preroll(PrerollContext* context,

Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context);

AutoCache cache = AutoCache(layer_raster_cache_item_.get(), context, matrix);

SkRect child_bounds = SkRect::MakeEmpty();
SkMatrix child_matrix = matrix;
if (context->raster_cache) {
child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix);
}

AutoCache cache =
AutoCache(layer_raster_cache_item_.get(), context, child_matrix);

SkRect child_bounds = SkRect::MakeEmpty();

PrerollChildren(context, child_matrix, &child_bounds);
context->subtree_can_inherit_opacity = true;

Expand Down
9 changes: 7 additions & 2 deletions flow/layers/shader_mask_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,15 @@ void ShaderMaskLayer::Diff(DiffContext* context, const Layer* old_layer) {
void ShaderMaskLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context);
SkMatrix child_matrix = matrix;
if (context->raster_cache) {
child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix);
}

AutoCache cache = AutoCache(layer_raster_cache_item_.get(), context, matrix);
AutoCache cache =
AutoCache(layer_raster_cache_item_.get(), context, child_matrix);

ContainerLayer::Preroll(context, matrix);
ContainerLayer::Preroll(context, child_matrix);
// We always paint with a saveLayer (or a cached rendering),
// so we can always apply opacity in any of those cases.
context->subtree_can_inherit_opacity = true;
Expand Down
42 changes: 42 additions & 0 deletions flow/layers/shader_mask_layer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "flutter/flow/layers/layer_tree.h"
#include "flutter/flow/layers/opacity_layer.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/flow/raster_cache_util.h"
#include "flutter/flow/testing/layer_test.h"
#include "flutter/flow/testing/mock_layer.h"
#include "flutter/fml/macros.h"
Expand Down Expand Up @@ -389,5 +390,46 @@ TEST_F(ShaderMaskLayerTest, OpacityInheritance) {
EXPECT_TRUE(DisplayListsEQ_Verbose(expected_builder.Build(), display_list()));
}

TEST_F(ShaderMaskLayerTest, SimpleFilterWithRasterCache) {
use_mock_raster_cache(); // Ensure non-fractional alignment.

const SkMatrix initial_transform = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
const SkRect layer_bounds = SkRect::MakeLTRB(2.0f, 4.0f, 6.5f, 6.5f);
const SkPath child_path = SkPath().addRect(child_bounds);
const SkPaint child_paint = SkPaint(SkColors::kYellow);
auto layer_filter =
SkPerlinNoiseShader::MakeFractalNoise(1.0f, 1.0f, 1, 1.0f);
auto dl_filter = DlColorSource::From(layer_filter);
auto mock_layer = std::make_shared<MockLayer>(child_path, child_paint);
auto layer = std::make_shared<ShaderMaskLayer>(dl_filter, layer_bounds,
DlBlendMode::kSrc);
layer->Add(mock_layer);
layer->Preroll(preroll_context(), initial_transform);

SkPaint filter_paint;
filter_paint.setBlendMode(SkBlendMode::kSrc);
filter_paint.setShader(layer_filter);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
std::vector({MockCanvas::DrawCall{0, MockCanvas::SetMatrixData{SkM44(
SkMatrix::Translate(0.0, 0.0))}},
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}}}));
}

} // namespace testing
} // namespace flutter
17 changes: 13 additions & 4 deletions flow/testing/mock_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,27 @@ void MockCacheableContainerLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context);
auto cache = AutoCache(layer_raster_cache_item_.get(), context, matrix);
SkMatrix child_matrix = matrix;
if (context->raster_cache) {
child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix);
}

auto cache = AutoCache(layer_raster_cache_item_.get(), context, child_matrix);

ContainerLayer::Preroll(context, matrix);
ContainerLayer::Preroll(context, child_matrix);
}

void MockCacheableLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context);
auto cache = AutoCache(raster_cache_item_.get(), context, matrix);
SkMatrix child_matrix = matrix;
if (context->raster_cache) {
child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix);
}
auto cache = AutoCache(raster_cache_item_.get(), context, child_matrix);

MockLayer::Preroll(context, matrix);
MockLayer::Preroll(context, child_matrix);
}

} // namespace testing
Expand Down

0 comments on commit 1692276

Please sign in to comment.