vcl/inc/skia/salbmp.hxx      |    4 ++++
 vcl/qa/cppunit/skia/skia.cxx |   41 +++++++++++++++++++++++++++++++++++++++++
 vcl/skia/salbmp.cxx          |   16 +++++++++++++++-
 3 files changed, 60 insertions(+), 1 deletion(-)

New commits:
commit 63b8d83fd0d135af4ac04f78d26bfd3322ab65f6
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Thu Dec 9 13:09:57 2021 +0100
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Fri Dec 10 11:02:15 2021 +0100

    make sure Skia bitmap checksum is invalidated properly
    
    Change-Id: I85e81b730dcb0fdc7728d5a956974ef09a73de87
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126585
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx
index 2959952a3442..05e489643f88 100644
--- a/vcl/inc/skia/salbmp.hxx
+++ b/vcl/inc/skia/salbmp.hxx
@@ -107,8 +107,12 @@ public:
     const sal_uInt8* unittestGetBuffer() const { return mBuffer.get(); }
     const SkImage* unittestGetImage() const { return mImage.get(); }
     const SkImage* unittestGetAlphaImage() const { return mAlphaImage.get(); }
+    void unittestResetToImage() { ResetToSkImage(GetSkImage()); }
 
 private:
+    // This should be called whenever the contents have (possibly) changed.
+    // It may reset some cached data such as the checksum.
+    void DataChanged();
     // Reset the state to pixel data (resets cached images allocated in 
GetSkImage()/GetAlphaSkImage()).
     void ResetToBuffer();
     // Sets the data only as SkImage (will be converted as needed).
diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx
index b94e2ede7eba..21e3d0baf696 100644
--- a/vcl/qa/cppunit/skia/skia.cxx
+++ b/vcl/qa/cppunit/skia/skia.cxx
@@ -44,6 +44,7 @@ public:
     void testDelayedScale();
     void testDelayedScaleAlphaImage();
     void testDrawDelayedScaleImage();
+    void testChecksum();
     void testTdf137329();
     void testTdf140848();
     void testTdf132367();
@@ -58,6 +59,7 @@ public:
     CPPUNIT_TEST(testDelayedScale);
     CPPUNIT_TEST(testDelayedScaleAlphaImage);
     CPPUNIT_TEST(testDrawDelayedScaleImage);
+    CPPUNIT_TEST(testChecksum);
     CPPUNIT_TEST(testTdf137329);
     CPPUNIT_TEST(testTdf140848);
     CPPUNIT_TEST(testTdf132367);
@@ -468,6 +470,45 @@ void SkiaTest::testDrawDelayedScaleImage()
     CPPUNIT_ASSERT_EQUAL(Size(10, 10), SkiaHelper::imageSize(image3));
 }
 
+void SkiaTest::testChecksum()
+{
+    if (!SkiaHelper::isVCLSkiaEnabled())
+        return;
+    Bitmap bitmap(Size(10, 10), vcl::PixelFormat::N24_BPP);
+    bitmap.Erase(COL_RED);
+    BitmapChecksum checksum1 = bitmap.GetChecksum();
+    // Set a pixel to create pixel data, that should change checksum.
+    BitmapWriteAccess(bitmap).SetPixel(0, 0, COL_BLUE);
+    BitmapChecksum checksum2 = bitmap.GetChecksum();
+    CPPUNIT_ASSERT(checksum2 != checksum1);
+    SkiaSalBitmap* skiaBitmap1 = 
dynamic_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get());
+    // Creating an image should not change the checksum.
+    sk_sp<SkImage> image1 = skiaBitmap1->GetSkImage();
+    BitmapChecksum checksum3 = bitmap.GetChecksum();
+    CPPUNIT_ASSERT_EQUAL(checksum2, checksum3);
+    // Delayed scaling should change checksum even if the scaling has not 
taken place.
+    bitmap.Scale(Size(20, 20));
+    BitmapChecksum checksum4 = bitmap.GetChecksum();
+    CPPUNIT_ASSERT(checksum4 != checksum3);
+    // Setting back to the original red content should have the original 
checksum.
+    // (This also makes sure this next step is not affected by the delayed 
scaling
+    // above possibly taking place now.)
+    bitmap = Bitmap(Size(10, 10), vcl::PixelFormat::N24_BPP);
+    bitmap.Erase(COL_RED);
+    BitmapChecksum checksum5 = bitmap.GetChecksum();
+    CPPUNIT_ASSERT_EQUAL(checksum1, checksum5);
+    // The optimized changing of images to greyscale should change the 
checksum.
+    SkiaSalBitmap* skiaBitmap2 = 
dynamic_cast<SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get());
+    skiaBitmap2->unittestResetToImage();
+    BitmapChecksum checksum6;
+    skiaBitmap2->GetChecksum(checksum6);
+    CPPUNIT_ASSERT_EQUAL(checksum5, checksum6);
+    CPPUNIT_ASSERT(skiaBitmap2->ConvertToGreyscale());
+    BitmapChecksum checksum7;
+    skiaBitmap2->GetChecksum(checksum7);
+    CPPUNIT_ASSERT(checksum7 != checksum6);
+}
+
 void SkiaTest::testTdf137329()
 {
     if (!SkiaHelper::isVCLSkiaEnabled())
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 7b5d05007129..c18ad18f8428 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -158,6 +158,8 @@ bool SkiaSalBitmap::Create(const SalBitmap& rSalBmp, 
SalGraphics* pGraphics)
 bool SkiaSalBitmap::Create(const SalBitmap& rSalBmp, vcl::PixelFormat 
eNewPixelFormat)
 {
     assert(mAnyAccessCount == 0);
+    assert(&rSalBmp != this);
+    ResetAllData();
     const SkiaSalBitmap& src = static_cast<const SkiaSalBitmap&>(rSalBmp);
     mImage = src.mImage;
     mAlphaImage = src.mAlphaImage;
@@ -296,7 +298,7 @@ void SkiaSalBitmap::ReleaseBuffer(BitmapBuffer* pBuffer, 
BitmapAccessMode nMode,
 #endif
         mPalette = pBuffer->maPalette;
         ResetToBuffer();
-        InvalidateChecksum();
+        DataChanged();
     }
     assert(mAnyAccessCount > 0);
     --mAnyAccessCount;
@@ -451,6 +453,7 @@ bool SkiaSalBitmap::Scale(const double& rScaleX, const 
double& rScaleY, BmpScale
         ResetToSkImage(mImage);
     else
         ResetToBuffer();
+    DataChanged();
     // The rest will be handled when the scaled bitmap is actually needed,
     // such as in EnsureBitmapData() or GetSkImage().
     return true;
@@ -494,6 +497,7 @@ bool SkiaSalBitmap::ConvertToGreyscale()
         ComputeScanlineSize();
         mPalette = Bitmap::GetGreyPalette(256);
         ResetToSkImage(makeCheckedImageSnapshot(surface));
+        DataChanged();
         SAL_INFO("vcl.skia.trace", "converttogreyscale(" << this << ")");
         return true;
     }
@@ -531,6 +535,7 @@ bool SkiaSalBitmap::InterpretAs8Bit()
         ComputeScanlineSize();
         mPalette = Bitmap::GetGreyPalette(256);
         ResetToSkImage(mImage); // keep mImage, it will be interpreted as 8bit 
if needed
+        DataChanged();
         SAL_INFO("vcl.skia.trace", "interpretas8bit(" << this << ") with 
image");
         return true;
     }
@@ -584,6 +589,7 @@ bool SkiaSalBitmap::AlphaBlendWith(const SalBitmap& rSalBmp)
         const sal_uInt16 nGrey2 = otherBitmap->mEraseColor.GetRed();
         const sal_uInt8 nGrey = static_cast<sal_uInt8>(nGrey1 + nGrey2 - 
nGrey1 * nGrey2 / 255);
         mEraseColor = Color(nGrey, nGrey, nGrey);
+        DataChanged();
         SAL_INFO("vcl.skia.trace",
                  "alphablendwith(" << this << ") : with erase color " << 
otherBitmap);
         return true;
@@ -603,6 +609,7 @@ bool SkiaSalBitmap::AlphaBlendWith(const SalBitmap& rSalBmp)
     paint.setBlendMode(SkBlendMode::kScreen); // src+dest - src*dest/255 (in 
0..1)
     surface->getCanvas()->drawImage(otherBitmap->GetSkImage(), 0, 0, 
SkSamplingOptions(), &paint);
     ResetToSkImage(makeCheckedImageSnapshot(surface));
+    DataChanged();
     SAL_INFO("vcl.skia.trace", "alphablendwith(" << this << ") : with image " 
<< otherBitmap);
     return true;
 }
@@ -1318,8 +1325,11 @@ void SkiaSalBitmap::ResetAllData()
     mEraseColorSet = false;
     mPixelsSize = mSize;
     ComputeScanlineSize();
+    DataChanged();
 }
 
+void SkiaSalBitmap::DataChanged() { InvalidateChecksum(); }
+
 void SkiaSalBitmap::ResetPendingScaling()
 {
     if (mPixelsSize == mSize)
commit a78040cabc6878e06e7519d6d53a0ef6e5c4d658
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Thu Dec 9 13:04:36 2021 +0100
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Fri Dec 10 11:02:00 2021 +0100

    don't use 32bit Skia bitmaps if not configured so
    
    Change-Id: Ic7781f799d0d4baef01955f03ace8428b6d9f229
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126584
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 32545963db1b..7b5d05007129 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -61,7 +61,11 @@ SkiaSalBitmap::SkiaSalBitmap(const sk_sp<SkImage>& image)
     ResetAllData();
     mImage = image;
     mPalette = BitmapPalette();
+#if SKIA_USE_BITMAP32
     mBitCount = 32;
+#else
+    mBitCount = 24;
+#endif
     mSize = mPixelsSize = Size(image->width(), image->height());
     ComputeScanlineSize();
     mAnyAccessCount = 0;

Reply via email to