From fccfbd2f6211feaab1d313649f34d2ff42dc6eeb Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 8 Sep 2022 18:10:01 -0700 Subject: [PATCH 1/2] add pixel snapping conditional on presence of raster cache (#35981) --- flow/compositor_context.cc | 10 +++++-- flow/compositor_context.h | 3 +- flow/diff_context.cc | 6 ++-- flow/diff_context.h | 9 +++++- flow/layers/clip_shape_layer.h | 14 ++++++++- flow/layers/color_filter_layer.cc | 15 +++++++++- flow/layers/display_list_layer.cc | 14 ++++++++- flow/layers/display_list_layer_unittests.cc | 17 ++++++++++- flow/layers/image_filter_layer.cc | 21 ++++++++++++- flow/layers/opacity_layer.cc | 10 +++++++ flow/layers/opacity_layer_unittests.cc | 16 +++++++++- flow/layers/shader_mask_layer.cc | 10 +++++++ flow/raster_cache.cc | 28 +++++++++-------- flow/raster_cache_util.h | 33 +++++++++++++++++++++ flow/testing/diff_context_test.cc | 5 ++-- flow/testing/diff_context_test.h | 3 +- 16 files changed, 185 insertions(+), 29 deletions(-) diff --git a/flow/compositor_context.cc b/flow/compositor_context.cc index 779a42c84eb92..1d19db76cddbf 100644 --- a/flow/compositor_context.cc +++ b/flow/compositor_context.cc @@ -11,14 +11,16 @@ namespace flutter { std::optional FrameDamage::ComputeClipRect( - flutter::LayerTree& layer_tree) { + flutter::LayerTree& layer_tree, + bool has_raster_cache) { if (layer_tree.root_layer()) { PaintRegionMap empty_paint_region_map; DiffContext context(layer_tree.frame_size(), layer_tree.device_pixel_ratio(), layer_tree.paint_region_map(), prev_layer_tree_ ? prev_layer_tree_->paint_region_map() - : empty_paint_region_map); + : empty_paint_region_map, + has_raster_cache); context.PushCullRect(SkRect::MakeIWH(layer_tree.frame_size().width(), layer_tree.frame_size().height())); { @@ -116,7 +118,9 @@ RasterStatus CompositorContext::ScopedFrame::Raster( TRACE_EVENT0("flutter", "CompositorContext::ScopedFrame::Raster"); std::optional clip_rect = - frame_damage ? frame_damage->ComputeClipRect(layer_tree) : std::nullopt; + frame_damage + ? frame_damage->ComputeClipRect(layer_tree, !ignore_raster_cache) + : std::nullopt; bool root_needs_readback = layer_tree.Preroll( *this, ignore_raster_cache, clip_rect ? *clip_rect : kGiantRect); diff --git a/flow/compositor_context.h b/flow/compositor_context.h index 0981cdd2538b1..0cea3fecb0967 100644 --- a/flow/compositor_context.h +++ b/flow/compositor_context.h @@ -81,7 +81,8 @@ class FrameDamage { // If previous layer tree is not specified, clip rect will be nullopt, // but the paint region of layer_tree will be calculated so that it can be // used for diffing of subsequent frames. - std::optional ComputeClipRect(flutter::LayerTree& layer_tree); + std::optional ComputeClipRect(flutter::LayerTree& layer_tree, + bool has_raster_cache); // See Damage::frame_damage. std::optional GetFrameDamage() const { diff --git a/flow/diff_context.cc b/flow/diff_context.cc index 0c9ea6a934493..d34914282822f 100644 --- a/flow/diff_context.cc +++ b/flow/diff_context.cc @@ -10,12 +10,14 @@ namespace flutter { DiffContext::DiffContext(SkISize frame_size, double frame_device_pixel_ratio, PaintRegionMap& this_frame_paint_region_map, - const PaintRegionMap& last_frame_paint_region_map) + const PaintRegionMap& last_frame_paint_region_map, + bool has_raster_cache) : rects_(std::make_shared>()), frame_size_(frame_size), frame_device_pixel_ratio_(frame_device_pixel_ratio), this_frame_paint_region_map_(this_frame_paint_region_map), - last_frame_paint_region_map_(last_frame_paint_region_map) {} + last_frame_paint_region_map_(last_frame_paint_region_map), + has_raster_cache_(has_raster_cache) {} void DiffContext::BeginSubtree() { state_stack_.push_back(state_); diff --git a/flow/diff_context.h b/flow/diff_context.h index 91d3852078dd4..d3cfb76db3c11 100644 --- a/flow/diff_context.h +++ b/flow/diff_context.h @@ -45,7 +45,8 @@ class DiffContext { explicit DiffContext(SkISize frame_size, double device_pixel_aspect_ratio, PaintRegionMap& this_frame_paint_region_map, - const PaintRegionMap& last_frame_paint_region_map); + const PaintRegionMap& last_frame_paint_region_map, + bool has_raster_cache); // Starts a new subtree. void BeginSubtree(); @@ -156,6 +157,11 @@ class DiffContext { // frame layer tree. PaintRegion GetOldLayerPaintRegion(const Layer* layer) const; + // Whether or not a raster cache is being used. If so, we must snap + // all transformations to physical pixels if the layer may be raster + // cached. + bool has_raster_cache() const { return has_raster_cache_; } + class Statistics { public: // Picture replaced by different picture @@ -232,6 +238,7 @@ class DiffContext { PaintRegionMap& this_frame_paint_region_map_; const PaintRegionMap& last_frame_paint_region_map_; + bool has_raster_cache_; void AddDamage(const SkRect& rect); diff --git a/flow/layers/clip_shape_layer.h b/flow/layers/clip_shape_layer.h index faf4c26d31b6c..e4594f8e2eafc 100644 --- a/flow/layers/clip_shape_layer.h +++ b/flow/layers/clip_shape_layer.h @@ -8,6 +8,7 @@ #include "flutter/flow/layers/cacheable_layer.h" #include "flutter/flow/layers/container_layer.h" #include "flutter/flow/paint_utils.h" +#include "flutter/flow/raster_cache_util.h" namespace flutter { @@ -32,6 +33,10 @@ class ClipShapeLayer : public CacheableContainerLayer { context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer)); } } + if (UsesSaveLayer() && context->has_raster_cache()) { + context->SetTransform( + RasterCacheUtil::GetIntegralTransCTM(context->GetTransform())); + } if (context->PushCullRect(clip_shape_bounds())) { DiffChildren(context, prev); } @@ -45,12 +50,16 @@ class ClipShapeLayer : public CacheableContainerLayer { if (!context->cull_rect.intersect(clip_shape_bounds())) { context->cull_rect.setEmpty(); } + SkMatrix child_matrix = matrix; + if (context->raster_cache && uses_save_layer) { + child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix); + } // We can use the raster_cache for children only when the use_save_layer is // true so if use_save_layer is false we pass the layer_raster_item is // nullptr which mean we don't do raster cache logic. AutoCache cache = AutoCache(uses_save_layer ? layer_raster_cache_item_.get() : nullptr, - context, matrix); + context, child_matrix); Layer::AutoPrerollSaveLayerState save = Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer()); @@ -89,6 +98,9 @@ class ClipShapeLayer : public CacheableContainerLayer { AutoCachePaint cache_paint(context); if (context.raster_cache) { + context.internal_nodes_canvas->setMatrix( + RasterCacheUtil::GetIntegralTransCTM( + context.leaf_nodes_canvas->getTotalMatrix())); if (layer_raster_cache_item_->Draw(context, cache_paint.sk_paint())) { return; } diff --git a/flow/layers/color_filter_layer.cc b/flow/layers/color_filter_layer.cc index c82ae04c0cd60..8806b88094c40 100644 --- a/flow/layers/color_filter_layer.cc +++ b/flow/layers/color_filter_layer.cc @@ -24,6 +24,11 @@ void ColorFilterLayer::Diff(DiffContext* context, const Layer* old_layer) { } } + if (context->has_raster_cache()) { + context->SetTransform( + RasterCacheUtil::GetIntegralTransCTM(context->GetTransform())); + } + DiffChildren(context, prev); context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion()); @@ -35,7 +40,12 @@ void ColorFilterLayer::Preroll(PrerollContext* context, Layer::AutoPrerollSaveLayerState::Create(context); AutoCache cache = AutoCache(layer_raster_cache_item_.get(), context, matrix); - ContainerLayer::Preroll(context, matrix); + SkMatrix child_matrix = matrix; + if (context->raster_cache) { + child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix); + } + + ContainerLayer::Preroll(context, child_matrix); // We always use a saveLayer (or a cached rendering), so we // can always apply opacity in those cases. context->subtree_can_inherit_opacity = true; @@ -48,6 +58,9 @@ void ColorFilterLayer::Paint(PaintContext& context) const { AutoCachePaint cache_paint(context); if (context.raster_cache) { + context.internal_nodes_canvas->setMatrix( + RasterCacheUtil::GetIntegralTransCTM( + context.leaf_nodes_canvas->getTotalMatrix())); if (layer_raster_cache_item_->IsCacheChildren()) { cache_paint.setColorFilter(filter_); } diff --git a/flow/layers/display_list_layer.cc b/flow/layers/display_list_layer.cc index 5039feae31c3b..b5fbe9ce1b521 100644 --- a/flow/layers/display_list_layer.cc +++ b/flow/layers/display_list_layer.cc @@ -52,6 +52,10 @@ void DisplayListLayer::Diff(DiffContext* context, const Layer* old_layer) { #endif } context->PushTransform(SkMatrix::Translate(offset_.x(), offset_.y())); + if (context->has_raster_cache()) { + context->SetTransform( + RasterCacheUtil::GetIntegralTransCTM(context->GetTransform())); + } context->AddLayerBounds(display_list()->bounds()); context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion()); } @@ -95,9 +99,13 @@ void DisplayListLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { TRACE_EVENT0("flutter", "DisplayListLayer::Preroll"); DisplayList* disp_list = display_list(); + SkMatrix child_matrix = matrix; + if (context->raster_cache) { + child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix); + } AutoCache cache = - AutoCache(display_list_raster_cache_item_.get(), context, matrix); + AutoCache(display_list_raster_cache_item_.get(), context, child_matrix); if (disp_list->can_apply_group_opacity()) { context->subtree_can_inherit_opacity = true; } @@ -111,6 +119,10 @@ void DisplayListLayer::Paint(PaintContext& context) const { SkAutoCanvasRestore save(context.leaf_nodes_canvas, true); context.leaf_nodes_canvas->translate(offset_.x(), offset_.y()); + if (context.raster_cache) { + context.leaf_nodes_canvas->setMatrix(RasterCacheUtil::GetIntegralTransCTM( + context.leaf_nodes_canvas->getTotalMatrix())); + } if (context.raster_cache && display_list_raster_cache_item_) { AutoCachePaint cache_paint(context); diff --git a/flow/layers/display_list_layer_unittests.cc b/flow/layers/display_list_layer_unittests.cc index ca88583539144..4db87af8d0451 100644 --- a/flow/layers/display_list_layer_unittests.cc +++ b/flow/layers/display_list_layer_unittests.cc @@ -325,10 +325,25 @@ TEST_F(DisplayListLayerDiffTest, FractionalTranslation) { tree1.root()->Add( CreateDisplayListLayer(display_list, SkPoint::Make(0.5, 0.5))); - auto damage = DiffLayerTree(tree1, MockLayerTree()); + auto damage = + DiffLayerTree(tree1, MockLayerTree(), SkIRect::MakeEmpty(), 0, 0, + /*use_raster_cache=*/false); EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 61, 61)); } +TEST_F(DisplayListLayerDiffTest, FractionalTranslationWithRasterCache) { + auto display_list = CreateDisplayList(SkRect::MakeLTRB(10, 10, 60, 60), 1); + + MockLayerTree tree1; + tree1.root()->Add( + CreateDisplayListLayer(display_list, SkPoint::Make(0.5, 0.5))); + + auto damage = + DiffLayerTree(tree1, MockLayerTree(), SkIRect::MakeEmpty(), 0, 0, + /*use_raster_cache=*/true); + EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(11, 11, 61, 61)); +} + TEST_F(DisplayListLayerDiffTest, DisplayListCompare) { MockLayerTree tree1; auto display_list1 = CreateDisplayList(SkRect::MakeLTRB(10, 10, 60, 60), 1); diff --git a/flow/layers/image_filter_layer.cc b/flow/layers/image_filter_layer.cc index 4793bfd8f0d03..7a063116d99e2 100644 --- a/flow/layers/image_filter_layer.cc +++ b/flow/layers/image_filter_layer.cc @@ -24,6 +24,11 @@ void ImageFilterLayer::Diff(DiffContext* context, const Layer* old_layer) { } } + if (context->has_raster_cache()) { + context->SetTransform( + RasterCacheUtil::GetIntegralTransCTM(context->GetTransform())); + } + if (filter_) { auto filter = filter_->makeWithLocalMatrix(context->GetTransform()); if (filter) { @@ -49,8 +54,16 @@ void ImageFilterLayer::Preroll(PrerollContext* context, AutoCache cache = AutoCache(layer_raster_cache_item_.get(), context, matrix); SkRect child_bounds = SkRect::MakeEmpty(); +<<<<<<< HEAD PrerollChildren(context, matrix, &child_bounds); context->subtree_can_inherit_opacity = true; +======= + SkMatrix child_matrix = matrix; + if (context->raster_cache) { + child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix); + } + PrerollChildren(context, child_matrix, &child_bounds); +>>>>>>> 07ebf3c997... add pixel snapping conditional on presence of raster cache (#35981) // We always paint with a saveLayer (or a cached rendering), // so we can always apply opacity in any of those cases. @@ -72,7 +85,7 @@ void ImageFilterLayer::Preroll(PrerollContext* context, // So in here we reset the LayerRasterCacheItem cache state. layer_raster_cache_item_->MarkNotCacheChildren(); - transformed_filter_ = filter_->makeWithLocalMatrix(matrix); + transformed_filter_ = filter_->makeWithLocalMatrix(child_matrix); if (transformed_filter_) { layer_raster_cache_item_->MarkCacheChildren(); } @@ -84,6 +97,12 @@ void ImageFilterLayer::Paint(PaintContext& context) const { AutoCachePaint cache_paint(context); + if (context.raster_cache) { + context.internal_nodes_canvas->setMatrix( + RasterCacheUtil::GetIntegralTransCTM( + context.leaf_nodes_canvas->getTotalMatrix())); + } + if (layer_raster_cache_item_->IsCacheChildren()) { cache_paint.setImageFilter(transformed_filter_); } diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index e9702629052ca..e1370300c75d7 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -5,6 +5,7 @@ #include "flutter/flow/layers/opacity_layer.h" #include "flutter/flow/layers/cacheable_layer.h" +#include "flutter/flow/raster_cache_util.h" #include "third_party/skia/include/core/SkPaint.h" namespace flutter { @@ -27,6 +28,10 @@ void OpacityLayer::Diff(DiffContext* context, const Layer* old_layer) { } } context->PushTransform(SkMatrix::Translate(offset_.fX, offset_.fY)); + if (context->has_raster_cache()) { + context->SetTransform( + RasterCacheUtil::GetIntegralTransCTM(context->GetTransform())); + } DiffChildren(context, prev); context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion()); } @@ -85,6 +90,11 @@ void OpacityLayer::Paint(PaintContext& context) const { SkAutoCanvasRestore save(context.internal_nodes_canvas, true); context.internal_nodes_canvas->translate(offset_.fX, offset_.fY); + if (context.raster_cache) { + context.internal_nodes_canvas->setMatrix( + RasterCacheUtil::GetIntegralTransCTM( + context.leaf_nodes_canvas->getTotalMatrix())); + } SkScalar inherited_opacity = context.inherited_opacity; SkScalar subtree_opacity = opacity() * inherited_opacity; diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc index c662e73284ec4..cc4c8b78761f5 100644 --- a/flow/layers/opacity_layer_unittests.cc +++ b/flow/layers/opacity_layer_unittests.cc @@ -644,9 +644,23 @@ TEST_F(OpacityLayerDiffTest, FractionalTranslation) { MockLayerTree tree1; tree1.root()->Add(layer); - auto damage = DiffLayerTree(tree1, MockLayerTree()); + auto damage = DiffLayerTree(tree1, MockLayerTree(), SkIRect::MakeEmpty(), 0, + 0, /*use_raster_cache=*/false); EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(10, 10, 61, 61)); } +TEST_F(OpacityLayerDiffTest, FractionalTranslationWithRasterCache) { + auto picture = CreateDisplayListLayer( + CreateDisplayList(SkRect::MakeLTRB(10, 10, 60, 60), 1)); + auto layer = CreateOpacityLater({picture}, 128, SkPoint::Make(0.5, 0.5)); + + MockLayerTree tree1; + tree1.root()->Add(layer); + + auto damage = DiffLayerTree(tree1, MockLayerTree(), SkIRect::MakeEmpty(), 0, + 0, /*use_raster_cache=*/true); + EXPECT_EQ(damage.frame_damage, SkIRect::MakeLTRB(11, 11, 61, 61)); +} + } // namespace testing } // namespace flutter diff --git a/flow/layers/shader_mask_layer.cc b/flow/layers/shader_mask_layer.cc index d39d508734c0b..a54ee1591d9ec 100644 --- a/flow/layers/shader_mask_layer.cc +++ b/flow/layers/shader_mask_layer.cc @@ -26,6 +26,10 @@ void ShaderMaskLayer::Diff(DiffContext* context, const Layer* old_layer) { context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer)); } } + if (context->has_raster_cache()) { + context->SetTransform( + RasterCacheUtil::GetIntegralTransCTM(context->GetTransform())); + } DiffChildren(context, prev); context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion()); @@ -49,6 +53,12 @@ void ShaderMaskLayer::Paint(PaintContext& context) const { AutoCachePaint cache_paint(context); + if (context.raster_cache) { + context.internal_nodes_canvas->setMatrix( + RasterCacheUtil::GetIntegralTransCTM( + context.leaf_nodes_canvas->getTotalMatrix())); + } + if (context.raster_cache) { if (layer_raster_cache_item_->Draw(context, cache_paint.sk_paint())) { return; diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index 2284cd238067d..45ec9b9aa402f 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -32,8 +32,8 @@ void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const { TRACE_EVENT0("flutter", "RasterCacheResult::draw"); SkAutoCanvasRestore auto_restore(&canvas, true); - SkRect bounds = - RasterCacheUtil::GetDeviceBounds(logical_rect_, canvas.getTotalMatrix()); + SkRect bounds = RasterCacheUtil::GetRoundedOutDeviceBounds( + logical_rect_, canvas.getTotalMatrix()); FML_DCHECK(std::abs(bounds.width() - image_->dimensions().width()) <= 1 && std::abs(bounds.height() - image_->dimensions().height()) <= 1); canvas.resetMatrix(); @@ -54,14 +54,12 @@ std::unique_ptr RasterCache::Rasterize( const std::function& draw_function) { TRACE_EVENT0("flutter", "RasterCachePopulate"); - SkRect dest_rect = - RasterCacheUtil::GetDeviceBounds(context.logical_rect, context.matrix); - // we always round out here so that the texture is integer sized. - int width = SkScalarCeilToInt(dest_rect.width()); - int height = SkScalarCeilToInt(dest_rect.height()); + SkRect dest_rect = RasterCacheUtil::GetRoundedOutDeviceBounds( + context.logical_rect, context.matrix); - const SkImageInfo image_info = SkImageInfo::MakeN32Premul( - width, height, sk_ref_sp(context.dst_color_space)); + const SkImageInfo image_info = + SkImageInfo::MakeN32Premul(dest_rect.width(), dest_rect.height(), + sk_ref_sp(context.dst_color_space)); sk_sp surface = context.gr_context ? SkSurface::MakeRenderTarget( @@ -112,7 +110,8 @@ bool RasterCache::UpdateCacheEntry( int RasterCache::MarkSeen(const RasterCacheKeyID& id, const SkMatrix& matrix, bool visible) const { - RasterCacheKey key = RasterCacheKey(id, matrix); + RasterCacheKey key = + RasterCacheKey(id, RasterCacheUtil::GetIntegralTransCTM(matrix)); Entry& entry = cache_[key]; entry.encountered_this_frame = true; entry.visible_this_frame = visible; @@ -124,7 +123,8 @@ int RasterCache::MarkSeen(const RasterCacheKeyID& id, int RasterCache::GetAccessCount(const RasterCacheKeyID& id, const SkMatrix& matrix) const { - RasterCacheKey key = RasterCacheKey(id, matrix); + RasterCacheKey key = + RasterCacheKey(id, RasterCacheUtil::GetIntegralTransCTM(matrix)); auto entry = cache_.find(key); if (entry != cache_.cend()) { return entry->second.accesses_since_visible; @@ -134,7 +134,8 @@ int RasterCache::GetAccessCount(const RasterCacheKeyID& id, bool RasterCache::HasEntry(const RasterCacheKeyID& id, const SkMatrix& matrix) const { - RasterCacheKey key = RasterCacheKey(id, matrix); + RasterCacheKey key = + RasterCacheKey(id, RasterCacheUtil::GetIntegralTransCTM(matrix)); if (cache_.find(key) != cache_.cend()) { return true; } @@ -144,7 +145,8 @@ bool RasterCache::HasEntry(const RasterCacheKeyID& id, bool RasterCache::Draw(const RasterCacheKeyID& id, SkCanvas& canvas, const SkPaint* paint) const { - auto it = cache_.find(RasterCacheKey(id, canvas.getTotalMatrix())); + auto it = cache_.find(RasterCacheKey( + id, RasterCacheUtil::GetIntegralTransCTM(canvas.getTotalMatrix()))); if (it == cache_.end()) { return false; } diff --git a/flow/raster_cache_util.h b/flow/raster_cache_util.h index 35abaf2d5f56c..71836fdaf502d 100644 --- a/flow/raster_cache_util.h +++ b/flow/raster_cache_util.h @@ -54,6 +54,39 @@ struct RasterCacheUtil { ctm.mapRect(&device_rect, rect); return device_rect; } + + static SkRect GetRoundedOutDeviceBounds(const SkRect& rect, + const SkMatrix& ctm) { + SkRect device_rect; + ctm.mapRect(&device_rect, rect); + device_rect.roundOut(&device_rect); + return device_rect; + } + + /** + * @brief Snap the translation components of the matrix to integers. + * + * The snapping will only happen if the matrix only has scale and translation + * transformations. This is used, along with GetRoundedOutDeviceBounds, to + * ensure that the textures drawn by the raster cache are exactly aligned to + * physical pixels. Any layers that participate in raster caching must align + * themselves to physical pixels even when not cached to prevent a change in + * apparent location if caching is later applied. + * + * @param ctm the current transformation matrix. + * @return SkMatrix the snapped transformation matrix. + */ + static SkMatrix GetIntegralTransCTM(const SkMatrix& ctm) { + // Avoid integral snapping if the matrix has complex transformation to avoid + // the artifact observed in https://github.com/flutter/flutter/issues/41654. + if (!ctm.isScaleTranslate()) { + return ctm; + } + SkMatrix result = ctm; + result[SkMatrix::kMTransX] = SkScalarRoundToScalar(ctm.getTranslateX()); + result[SkMatrix::kMTransY] = SkScalarRoundToScalar(ctm.getTranslateY()); + return result; + } }; } // namespace flutter diff --git a/flow/testing/diff_context_test.cc b/flow/testing/diff_context_test.cc index e9d5a4b05d9e6..47b35f5b80258 100644 --- a/flow/testing/diff_context_test.cc +++ b/flow/testing/diff_context_test.cc @@ -17,11 +17,12 @@ Damage DiffContextTest::DiffLayerTree(MockLayerTree& layer_tree, const MockLayerTree& old_layer_tree, const SkIRect& additional_damage, int horizontal_clip_alignment, - int vertical_clip_alignment) { + int vertical_clip_alignment, + bool use_raster_cache) { FML_CHECK(layer_tree.size() == old_layer_tree.size()); DiffContext dc(layer_tree.size(), 1, layer_tree.paint_region_map(), - old_layer_tree.paint_region_map()); + old_layer_tree.paint_region_map(), use_raster_cache); dc.PushCullRect( SkRect::MakeIWH(layer_tree.size().width(), layer_tree.size().height())); layer_tree.root()->Diff(&dc, old_layer_tree.root()); diff --git a/flow/testing/diff_context_test.h b/flow/testing/diff_context_test.h index 246e54817e251..0401b3232028d 100644 --- a/flow/testing/diff_context_test.h +++ b/flow/testing/diff_context_test.h @@ -39,7 +39,8 @@ class DiffContextTest : public ThreadTest { const MockLayerTree& old_layer_tree, const SkIRect& additional_damage = SkIRect::MakeEmpty(), int horizontal_clip_alignment = 0, - int vertical_alignment = 0); + int vertical_alignment = 0, + bool use_raster_cache = true); // Create display list consisting of filled rect with given color; Being able // to specify different color is useful to test deep comparison of pictures From 6bfc7bf66e491553f99357af6453d68930d19b20 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 8 Sep 2022 18:27:50 -0700 Subject: [PATCH 2/2] ++ --- flow/layers/image_filter_layer.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/flow/layers/image_filter_layer.cc b/flow/layers/image_filter_layer.cc index 7a063116d99e2..03be2a58a1883 100644 --- a/flow/layers/image_filter_layer.cc +++ b/flow/layers/image_filter_layer.cc @@ -54,16 +54,12 @@ void ImageFilterLayer::Preroll(PrerollContext* context, AutoCache cache = AutoCache(layer_raster_cache_item_.get(), context, matrix); SkRect child_bounds = SkRect::MakeEmpty(); -<<<<<<< HEAD - PrerollChildren(context, matrix, &child_bounds); - context->subtree_can_inherit_opacity = true; -======= SkMatrix child_matrix = matrix; if (context->raster_cache) { child_matrix = RasterCacheUtil::GetIntegralTransCTM(child_matrix); } PrerollChildren(context, child_matrix, &child_bounds); ->>>>>>> 07ebf3c997... add pixel snapping conditional on presence of raster cache (#35981) + context->subtree_can_inherit_opacity = true; // We always paint with a saveLayer (or a cached rendering), // so we can always apply opacity in any of those cases.