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.
This commit is contained in:
Jason Simmons 2020-03-25 13:37:27 -07:00 committed by GitHub
parent abfe606076
commit c2e581b781
2 changed files with 35 additions and 1 deletions

View File

@ -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);
}

View File

@ -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<SkPicture> picture = recorder.finishRecordingAsPicture();
SkMatrix ctm = SkMatrix::MakeAll(1.3312, 0, 233, 0, 1.3312, 206, 0, 0, 1);
sk_sp<SkColorSpace> 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