summaryrefslogtreecommitdiff
path: root/vcl/qa
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-11-16 13:34:37 +0100
committerLuboš Luňák <l.lunak@collabora.com>2021-11-16 18:37:21 +0100
commita0a4709eb4226ae15931999fc17afe5b5b9f8081 (patch)
tree3fcbd0cd908ff498ff68c918a880c271e48dcb58 /vcl/qa
parentf33b76b4e675818deae244427cef84c576a1a1f8 (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.cxx37
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())