未验证 提交 040747ed 编写于 作者: M Mehmet Fidanboylu 提交者: GitHub

Revert again "Remove layer integral offset snapping" (#18132) (#18138)

上级 2037e0f1
...@@ -65,15 +65,6 @@ void ContainerLayer::PaintChildren(PaintContext& context) const { ...@@ -65,15 +65,6 @@ void ContainerLayer::PaintChildren(PaintContext& context) const {
} }
} }
void ContainerLayer::TryToPrepareRasterCache(PrerollContext* context,
Layer* layer,
const SkMatrix& matrix) {
if (!context->has_platform_view && context->raster_cache &&
SkRect::Intersects(context->cull_rect, layer->paint_bounds())) {
context->raster_cache->Prepare(context, layer, matrix);
}
}
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
void ContainerLayer::UpdateScene(SceneUpdateContext& context) { void ContainerLayer::UpdateScene(SceneUpdateContext& context) {
......
...@@ -37,20 +37,6 @@ class ContainerLayer : public Layer { ...@@ -37,20 +37,6 @@ class ContainerLayer : public Layer {
// For OpacityLayer to restructure to have a single child. // For OpacityLayer to restructure to have a single child.
void ClearChildren() { layers_.clear(); } void ClearChildren() { layers_.clear(); }
// Try to prepare the raster cache for a given layer.
//
// The raster cache would fail if either of the followings is true:
// 1. The context has a platform view.
// 2. The context does not have a valid raster cache.
// 3. The layer's paint bounds does not intersect with the cull rect.
//
// We make this a static function instead of a member function that directy
// uses the "this" pointer as the layer because we sometimes need to raster
// cache a child layer and one can't access its child's protected method.
static void TryToPrepareRasterCache(PrerollContext* context,
Layer* layer,
const SkMatrix& matrix);
private: private:
std::vector<std::shared_ptr<Layer>> layers_; std::vector<std::shared_ptr<Layer>> layers_;
......
...@@ -28,13 +28,26 @@ void ImageFilterLayer::Preroll(PrerollContext* context, ...@@ -28,13 +28,26 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
set_paint_bounds(child_paint_bounds_); set_paint_bounds(child_paint_bounds_);
} }
TryToPrepareRasterCache(context, this, matrix); 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);
}
} }
void ImageFilterLayer::Paint(PaintContext& context) const { void ImageFilterLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "ImageFilterLayer::Paint"); TRACE_EVENT0("flutter", "ImageFilterLayer::Paint");
FML_DCHECK(needs_painting()); 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 && if (context.raster_cache &&
context.raster_cache->Draw(this, *context.leaf_nodes_canvas)) { context.raster_cache->Draw(this, *context.leaf_nodes_canvas)) {
return; return;
......
...@@ -60,11 +60,14 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) { ...@@ -60,11 +60,14 @@ TEST_F(ImageFilterLayerTest, EmptyFilter) {
layer->Paint(paint_context()); layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(), EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({ std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint, 1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}}, nullptr, 2}},
MockCanvas::DrawCall{ 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}}, MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
})); }));
} }
...@@ -93,11 +96,14 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) { ...@@ -93,11 +96,14 @@ TEST_F(ImageFilterLayerTest, SimpleFilter) {
layer->Paint(paint_context()); layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(), EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({ std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint, 1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}}, nullptr, 2}},
MockCanvas::DrawCall{ 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}}, MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
})); }));
} }
...@@ -126,11 +132,14 @@ TEST_F(ImageFilterLayerTest, SimpleFilterBounds) { ...@@ -126,11 +132,14 @@ TEST_F(ImageFilterLayerTest, SimpleFilterBounds) {
layer->Paint(paint_context()); layer->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(), EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({ std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{child_bounds, filter_paint, 1, MockCanvas::SaveLayerData{child_bounds, filter_paint,
nullptr, 1}}, nullptr, 2}},
MockCanvas::DrawCall{ 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}}, MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
})); }));
} }
...@@ -168,16 +177,19 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) { ...@@ -168,16 +177,19 @@ TEST_F(ImageFilterLayerTest, MultipleChildren) {
SkPaint filter_paint; SkPaint filter_paint;
filter_paint.setImageFilter(layer_filter); filter_paint.setImageFilter(layer_filter);
layer->Paint(paint_context()); layer->Paint(paint_context());
EXPECT_EQ( EXPECT_EQ(mock_canvas().draw_calls(),
mock_canvas().draw_calls(), std::vector(
std::vector({MockCanvas::DrawCall{ {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
0, MockCanvas::SaveLayerData{children_bounds, MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
filter_paint, nullptr, 1}}, MockCanvas::DrawCall{
MockCanvas::DrawCall{ 1, MockCanvas::SaveLayerData{children_bounds, filter_paint,
1, MockCanvas::DrawPathData{child_path1, child_paint1}}, nullptr, 2}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{
1, MockCanvas::DrawPathData{child_path2, child_paint2}}, 2, MockCanvas::DrawPathData{child_path1, child_paint1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}})); 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) { TEST_F(ImageFilterLayerTest, Nested) {
...@@ -225,16 +237,22 @@ TEST_F(ImageFilterLayerTest, Nested) { ...@@ -225,16 +237,22 @@ TEST_F(ImageFilterLayerTest, Nested) {
layer1->Paint(paint_context()); layer1->Paint(paint_context());
EXPECT_EQ(mock_canvas().draw_calls(), EXPECT_EQ(mock_canvas().draw_calls(),
std::vector({ std::vector({
MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::SetMatrixData{SkMatrix()}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{
0, MockCanvas::SaveLayerData{children_bounds, filter_paint1, 1, MockCanvas::SaveLayerData{children_bounds, filter_paint1,
nullptr, 1}}, nullptr, 2}},
MockCanvas::DrawCall{ 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{ MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{child_path2.getBounds(), 3, MockCanvas::SaveLayerData{child_path2.getBounds(),
filter_paint2, nullptr, 2}}, filter_paint2, nullptr, 4}},
MockCanvas::DrawCall{ 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{2, MockCanvas::RestoreData{1}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}, MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}},
})); }));
......
...@@ -48,7 +48,14 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { ...@@ -48,7 +48,14 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
{ {
set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY)); set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY));
TryToPrepareRasterCache(context, container, child_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);
}
} }
} }
...@@ -62,6 +69,11 @@ void OpacityLayer::Paint(PaintContext& context) const { ...@@ -62,6 +69,11 @@ void OpacityLayer::Paint(PaintContext& context) const {
SkAutoCanvasRestore save(context.internal_nodes_canvas, true); SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
context.internal_nodes_canvas->translate(offset_.fX, offset_.fY); 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 && if (context.raster_cache &&
context.raster_cache->Draw(GetChildContainer(), context.raster_cache->Draw(GetChildContainer(),
*context.leaf_nodes_canvas, &paint)) { *context.leaf_nodes_canvas, &paint)) {
...@@ -71,7 +83,8 @@ void OpacityLayer::Paint(PaintContext& context) const { ...@@ -71,7 +83,8 @@ void OpacityLayer::Paint(PaintContext& context) const {
// Skia may clip the content with saveLayerBounds (although it's not a // 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 // 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 // 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 // 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 // not available (e.g., when we're using the software backend in golden
......
...@@ -58,6 +58,10 @@ TEST_F(OpacityLayerTest, FullyOpaque) { ...@@ -58,6 +58,10 @@ TEST_F(OpacityLayerTest, FullyOpaque) {
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f);
const SkMatrix layer_transform = const SkMatrix layer_transform =
SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); 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 SkPaint child_paint = SkPaint(SkColors::kGreen);
const SkRect expected_layer_bounds = const SkRect expected_layer_bounds =
layer_transform.mapRect(child_path.getBounds()); layer_transform.mapRect(child_path.getBounds());
...@@ -82,6 +86,10 @@ TEST_F(OpacityLayerTest, FullyOpaque) { ...@@ -82,6 +86,10 @@ TEST_F(OpacityLayerTest, FullyOpaque) {
auto expected_draw_calls = std::vector( auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}}, MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer_transform}},
#endif
MockCanvas::DrawCall{ MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr, 1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr,
2}}, 2}},
...@@ -99,6 +107,10 @@ TEST_F(OpacityLayerTest, FullyTransparent) { ...@@ -99,6 +107,10 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f);
const SkMatrix layer_transform = const SkMatrix layer_transform =
SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); 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 SkPaint child_paint = SkPaint(SkColors::kGreen);
const SkRect expected_layer_bounds = const SkRect expected_layer_bounds =
layer_transform.mapRect(child_path.getBounds()); layer_transform.mapRect(child_path.getBounds());
...@@ -121,6 +133,10 @@ TEST_F(OpacityLayerTest, FullyTransparent) { ...@@ -121,6 +133,10 @@ TEST_F(OpacityLayerTest, FullyTransparent) {
auto expected_draw_calls = std::vector( auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}}, 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{1, MockCanvas::SaveData{2}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{
2, MockCanvas::ClipRectData{kEmptyRect, SkClipOp::kIntersect, 2, MockCanvas::ClipRectData{kEmptyRect, SkClipOp::kIntersect,
...@@ -139,6 +155,10 @@ TEST_F(OpacityLayerTest, HalfTransparent) { ...@@ -139,6 +155,10 @@ TEST_F(OpacityLayerTest, HalfTransparent) {
const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f); const SkMatrix initial_transform = SkMatrix::MakeTrans(0.5f, 0.5f);
const SkMatrix layer_transform = const SkMatrix layer_transform =
SkMatrix::MakeTrans(layer_offset.fX, layer_offset.fY); 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 SkPaint child_paint = SkPaint(SkColors::kGreen);
const SkRect expected_layer_bounds = const SkRect expected_layer_bounds =
layer_transform.mapRect(child_path.getBounds()); layer_transform.mapRect(child_path.getBounds());
...@@ -165,6 +185,10 @@ TEST_F(OpacityLayerTest, HalfTransparent) { ...@@ -165,6 +185,10 @@ TEST_F(OpacityLayerTest, HalfTransparent) {
auto expected_draw_calls = std::vector( auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}}, MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer_transform}},
#endif
MockCanvas::DrawCall{ MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr, 1, MockCanvas::SaveLayerData{opacity_bounds, opacity_paint, nullptr,
2}}, 2}},
...@@ -187,6 +211,13 @@ TEST_F(OpacityLayerTest, Nested) { ...@@ -187,6 +211,13 @@ TEST_F(OpacityLayerTest, Nested) {
SkMatrix::MakeTrans(layer1_offset.fX, layer1_offset.fY); SkMatrix::MakeTrans(layer1_offset.fX, layer1_offset.fY);
const SkMatrix layer2_transform = const SkMatrix layer2_transform =
SkMatrix::MakeTrans(layer2_offset.fX, layer2_offset.fY); 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 child1_paint = SkPaint(SkColors::kRed);
const SkPaint child2_paint = SkPaint(SkColors::kBlue); const SkPaint child2_paint = SkPaint(SkColors::kBlue);
const SkPaint child3_paint = SkPaint(SkColors::kGreen); const SkPaint child3_paint = SkPaint(SkColors::kGreen);
...@@ -247,6 +278,10 @@ TEST_F(OpacityLayerTest, Nested) { ...@@ -247,6 +278,10 @@ TEST_F(OpacityLayerTest, Nested) {
auto expected_draw_calls = std::vector( auto expected_draw_calls = std::vector(
{MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer1_transform}}, MockCanvas::DrawCall{1, MockCanvas::ConcatMatrixData{layer1_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
1, MockCanvas::SetMatrixData{integral_layer1_transform}},
#endif
MockCanvas::DrawCall{ MockCanvas::DrawCall{
1, MockCanvas::SaveLayerData{opacity1_bounds, opacity1_paint, 1, MockCanvas::SaveLayerData{opacity1_bounds, opacity1_paint,
nullptr, 2}}, nullptr, 2}},
...@@ -254,6 +289,10 @@ TEST_F(OpacityLayerTest, Nested) { ...@@ -254,6 +289,10 @@ TEST_F(OpacityLayerTest, Nested) {
2, MockCanvas::DrawPathData{child1_path, child1_paint}}, 2, MockCanvas::DrawPathData{child1_path, child1_paint}},
MockCanvas::DrawCall{2, MockCanvas::SaveData{3}}, MockCanvas::DrawCall{2, MockCanvas::SaveData{3}},
MockCanvas::DrawCall{3, MockCanvas::ConcatMatrixData{layer2_transform}}, MockCanvas::DrawCall{3, MockCanvas::ConcatMatrixData{layer2_transform}},
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
MockCanvas::DrawCall{
3, MockCanvas::SetMatrixData{integral_layer2_transform}},
#endif
MockCanvas::DrawCall{ MockCanvas::DrawCall{
3, MockCanvas::SaveLayerData{opacity2_bounds, opacity2_paint, 3, MockCanvas::SaveLayerData{opacity2_bounds, opacity2_paint,
nullptr, 4}}, nullptr, 4}},
......
...@@ -24,7 +24,12 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { ...@@ -24,7 +24,12 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
if (auto* cache = context->raster_cache) { if (auto* cache = context->raster_cache) {
TRACE_EVENT0("flutter", "PictureLayer::RasterCache (Preroll)"); TRACE_EVENT0("flutter", "PictureLayer::RasterCache (Preroll)");
cache->Prepare(context->gr_context, sk_picture, 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_); context->dst_color_space, is_complex_, will_change_);
} }
...@@ -39,6 +44,10 @@ void PictureLayer::Paint(PaintContext& context) const { ...@@ -39,6 +44,10 @@ void PictureLayer::Paint(PaintContext& context) const {
SkAutoCanvasRestore save(context.leaf_nodes_canvas, true); SkAutoCanvasRestore save(context.leaf_nodes_canvas, true);
context.leaf_nodes_canvas->translate(offset_.x(), offset_.y()); 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 && if (context.raster_cache &&
context.raster_cache->Draw(*picture(), *context.leaf_nodes_canvas)) { context.raster_cache->Draw(*picture(), *context.leaf_nodes_canvas)) {
......
...@@ -11,6 +11,10 @@ ...@@ -11,6 +11,10 @@
#include "flutter/testing/mock_canvas.h" #include "flutter/testing/mock_canvas.h"
#include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkPicture.h"
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
#include "flutter/flow/raster_cache.h"
#endif
namespace flutter { namespace flutter {
namespace testing { namespace testing {
...@@ -81,11 +85,16 @@ TEST_F(PictureLayerTest, SimplePicture) { ...@@ -81,11 +85,16 @@ TEST_F(PictureLayerTest, SimplePicture) {
EXPECT_FALSE(layer->needs_system_composite()); EXPECT_FALSE(layer->needs_system_composite());
layer->Paint(paint_context()); layer->Paint(paint_context());
auto expected_draw_calls = auto expected_draw_calls = std::vector(
std::vector({MockCanvas::DrawCall{0, MockCanvas::SaveData{1}}, {MockCanvas::DrawCall{0, MockCanvas::SaveData{1}},
MockCanvas::DrawCall{ MockCanvas::DrawCall{1,
1, MockCanvas::ConcatMatrixData{layer_offset_matrix}}, MockCanvas::ConcatMatrixData{layer_offset_matrix}},
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); #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); EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls);
} }
......
...@@ -62,6 +62,13 @@ class RasterCache { ...@@ -62,6 +62,13 @@ class RasterCache {
return bounds; 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. // Return true if the cache is generated.
// //
// We may return false and not generate the cache if // We may return false and not generate the cache if
......
...@@ -15,8 +15,11 @@ template <typename ID> ...@@ -15,8 +15,11 @@ template <typename ID>
class RasterCacheKey { class RasterCacheKey {
public: public:
RasterCacheKey(ID id, const SkMatrix& ctm) : id_(id), matrix_(ctm) { RasterCacheKey(ID id, const SkMatrix& ctm) : id_(id), matrix_(ctm) {
matrix_[SkMatrix::kMTransX] = 0; matrix_[SkMatrix::kMTransX] = SkScalarFraction(ctm.getTranslateX());
matrix_[SkMatrix::kMTransY] = 0; matrix_[SkMatrix::kMTransY] = SkScalarFraction(ctm.getTranslateY());
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
FML_DCHECK(matrix_.getTranslateX() == 0 && matrix_.getTranslateY() == 0);
#endif
} }
ID id() const { return id_; } ID id() const { return id_; }
......
...@@ -159,6 +159,9 @@ TEST(RasterCache, DeviceRectRoundOut) { ...@@ -159,6 +159,9 @@ TEST(RasterCache, DeviceRectRoundOut) {
ASSERT_TRUE(cache.Draw(*picture, canvas)); ASSERT_TRUE(cache.Draw(*picture, canvas));
canvas.translate(248, 0); canvas.translate(248, 0);
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
canvas.setMatrix(RasterCache::GetIntegralTransCTM(canvas.getTotalMatrix()));
#endif
ASSERT_TRUE(cache.Draw(*picture, canvas)); ASSERT_TRUE(cache.Draw(*picture, canvas));
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册