diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-11-16 13:34:37 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-11-16 18:37:21 +0100 |
commit | a0a4709eb4226ae15931999fc17afe5b5b9f8081 (patch) | |
tree | 3fcbd0cd908ff498ff68c918a880c271e48dcb58 /vcl/qa | |
parent | f33b76b4e675818deae244427cef84c576a1a1f8 (diff) |
try to avoid scaling bitmaps twice in Skia when drawing
The scenario is that something scales a bitmap and then asks for it
to be drawn (possibly drawn scaled again). One example is
OutputDevice::DrawBitmap() subsampling the bitmap that according
to c0ce7ca4884f7f6d1 is supposed to improve quality with headless(?)
backend, but with Skia it's pointless and it breaks things like
caching during repeated drawing, because then GetSkImage() will need
to generate a new SkImage each time.
Since Skia backend uses delayed scaling, these cases can be sorted
out by checking the stored SkImage and using it if suitable, as
the original image is as good as the rescaled one, but often
it's better - it may be cached, sometimes the scaling operations
cancel each other out (often the case in HiDPI mode).
Change-Id: I0af32f7abdf057a3bdda75247d2dc374eaf1bc4b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125311
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl/qa')
-rw-r--r-- | vcl/qa/cppunit/skia/skia.cxx | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx index 128829aecc18..f6920ccf1d8a 100644 --- a/vcl/qa/cppunit/skia/skia.cxx +++ b/vcl/qa/cppunit/skia/skia.cxx @@ -43,6 +43,7 @@ public: void testMatrixQuality(); void testDelayedScale(); void testDelayedScaleAlphaImage(); + void testDrawDelayedScaleImage(); void testTdf137329(); void testTdf140848(); void testTdf132367(); @@ -56,6 +57,7 @@ public: CPPUNIT_TEST(testMatrixQuality); CPPUNIT_TEST(testDelayedScale); CPPUNIT_TEST(testDelayedScaleAlphaImage); + CPPUNIT_TEST(testDrawDelayedScaleImage); CPPUNIT_TEST(testTdf137329); CPPUNIT_TEST(testTdf140848); CPPUNIT_TEST(testTdf132367); @@ -429,6 +431,41 @@ void SkiaTest::testDelayedScaleAlphaImage() CPPUNIT_ASSERT_EQUAL(Size(240, 240), bitmapCopy.GetSize()); } +void SkiaTest::testDrawDelayedScaleImage() +{ + if (!SkiaHelper::isVCLSkiaEnabled()) + return; + ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT); + device->SetOutputSizePixel(Size(10, 10)); + device->SetBackground(Wallpaper(COL_WHITE)); + device->Erase(); + Bitmap bitmap(Size(10, 10), vcl::PixelFormat::N24_BPP); + bitmap.Erase(COL_RED); + // Set a pixel to create pixel data. + BitmapWriteAccess(bitmap).SetPixel(0, 0, COL_BLUE); + SkiaSalBitmap* skiaBitmap1 = dynamic_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get()); + // Force creating of image. + sk_sp<SkImage> image1 = skiaBitmap1->GetSkImage(); + CPPUNIT_ASSERT(skiaBitmap1->unittestHasImage()); + CPPUNIT_ASSERT(bitmap.Scale(Size(5, 5))); + // Make sure delayed scaling has not changed the image. + SkiaSalBitmap* skiaBitmap2 = dynamic_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get()); + CPPUNIT_ASSERT(skiaBitmap2->unittestHasImage()); + sk_sp<SkImage> image2 = skiaBitmap2->GetSkImage(SkiaHelper::DirectImage::Yes); + CPPUNIT_ASSERT_EQUAL(image1, image2); + CPPUNIT_ASSERT_EQUAL(Size(5, 5), bitmap.GetSizePixel()); + CPPUNIT_ASSERT_EQUAL(Size(10, 10), SkiaHelper::imageSize(image2)); + // Draw the bitmap scaled to size 10x10 and check that the 10x10 image was used (and kept), + // even though technically the bitmap is 5x5. + device->DrawBitmap(Point(0, 0), Size(10, 10), bitmap); + SkiaSalBitmap* skiaBitmap3 = dynamic_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get()); + CPPUNIT_ASSERT(skiaBitmap3->unittestHasImage()); + sk_sp<SkImage> image3 = skiaBitmap3->GetSkImage(SkiaHelper::DirectImage::Yes); + CPPUNIT_ASSERT_EQUAL(image1, image3); + CPPUNIT_ASSERT_EQUAL(Size(5, 5), bitmap.GetSizePixel()); + CPPUNIT_ASSERT_EQUAL(Size(10, 10), SkiaHelper::imageSize(image3)); +} + void SkiaTest::testTdf137329() { if (!SkiaHelper::isVCLSkiaEnabled()) |