From c2e581b781fc07d9374aa5ab561fcd694aa398b8 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Wed, 25 Mar 2020 13:37:27 -0700 Subject: [PATCH] Allow drawing raster cache results whose device rect is one pixel larger than the cached image (flutter/engine#17278) RasterCacheResult::draw constructs the device target rectangle by calling SkRect::roundOut, which rounds down the left/top coordinates and rounds up the right/bottom coordinates. The rounding can produce a device rect whose width and/or height differs from the cache result image's width/height by one pixel. --- engine/src/flutter/flow/raster_cache.cc | 4 ++- .../flutter/flow/raster_cache_unittests.cc | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/flow/raster_cache.cc b/engine/src/flutter/flow/raster_cache.cc index f179905ed8e..e7709b14c7b 100644 --- a/engine/src/flutter/flow/raster_cache.cc +++ b/engine/src/flutter/flow/raster_cache.cc @@ -26,7 +26,9 @@ void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const { SkAutoCanvasRestore auto_restore(&canvas, true); SkIRect bounds = RasterCache::GetDeviceBounds(logical_rect_, canvas.getTotalMatrix()); - FML_DCHECK(bounds.size() == image_->dimensions()); + FML_DCHECK( + std::abs(bounds.size().width() - image_->dimensions().width()) <= 1 && + std::abs(bounds.size().height() - image_->dimensions().height()) <= 1); canvas.resetMatrix(); canvas.drawImage(image_, bounds.fLeft, bounds.fTop, paint); } diff --git a/engine/src/flutter/flow/raster_cache_unittests.cc b/engine/src/flutter/flow/raster_cache_unittests.cc index 03e3b3879c4..0c00a47087f 100644 --- a/engine/src/flutter/flow/raster_cache_unittests.cc +++ b/engine/src/flutter/flow/raster_cache_unittests.cc @@ -122,5 +122,37 @@ TEST(RasterCache, SweepsRemoveUnusedFrames) { ASSERT_FALSE(cache.Get(*picture, matrix).is_valid()); } +// Construct a cache result whose device target rectangle rounds out to be one +// pixel wider than the cached image. Verify that it can be drawn without +// triggering any assertions. +TEST(RasterCache, DeviceRectRoundOut) { + size_t threshold = 1; + flutter::RasterCache cache(threshold); + + SkPictureRecorder recorder; + SkRect logical_rect = SkRect::MakeLTRB(28, 0, 354.56731, 310.288); + recorder.beginRecording(logical_rect); + SkPaint paint; + paint.setColor(SK_ColorRED); + recorder.getRecordingCanvas()->drawRect(logical_rect, paint); + sk_sp picture = recorder.finishRecordingAsPicture(); + + SkMatrix ctm = SkMatrix::MakeAll(1.3312, 0, 233, 0, 1.3312, 206, 0, 0, 1); + + sk_sp srgb = SkColorSpace::MakeSRGB(); + ASSERT_FALSE( + cache.Prepare(NULL, picture.get(), ctm, srgb.get(), true, false)); + ASSERT_FALSE(cache.Get(*picture, ctm).is_valid()); + cache.SweepAfterFrame(); + ASSERT_TRUE(cache.Prepare(NULL, picture.get(), ctm, srgb.get(), true, false)); + ASSERT_TRUE(cache.Get(*picture, ctm).is_valid()); + + SkCanvas canvas(100, 100, nullptr); + canvas.setMatrix(ctm); + canvas.translate(248, 0); + + cache.Get(*picture, ctm).draw(canvas); +} + } // namespace testing } // namespace flutter