[Libreoffice-commits] core.git: 2 commits - external/skia vcl/inc vcl/skia

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 7 09:53:10 UTC 2020


 external/skia/UnpackedTarball_skia.mk    |    1 
 external/skia/extend-rgb-to-rgba.patch.0 |   23 +++
 vcl/inc/skia/salbmp.hxx                  |    7 +
 vcl/skia/salbmp.cxx                      |  198 ++++++++++++++++++++++++-------
 4 files changed, 187 insertions(+), 42 deletions(-)

New commits:
commit c27d2e9145be8972e5d2174fb3f317dc08930074
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Apr 2 12:33:57 2020 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Apr 7 11:52:43 2020 +0200

    optimize bit depth conversions to/from Skia where possible
    
    Skia has an optimized function for RGB->RGBA conversion that
    we are going to do often because 24bpp is the most common LO
    image format. The function is private, so patch that.
    Also optimize 32bpp->8bpp conversion with gray palette.
    
    Change-Id: I48b06f80d5ca9e1c8e3ee51da61e87541bd83d5a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91768
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk
index 99344871cb9d..da0a2a7a0547 100644
--- a/external/skia/UnpackedTarball_skia.mk
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -32,6 +32,7 @@ skia_patches := \
     windows-force-unicode-api.patch.0 \
     operator-eq-bool.patch.0 \
     fix-without-gl.patch.0 \
+    extend-rgb-to-rgba.patch.0 \
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
 
diff --git a/external/skia/extend-rgb-to-rgba.patch.0 b/external/skia/extend-rgb-to-rgba.patch.0
new file mode 100644
index 000000000000..f68dbab96336
--- /dev/null
+++ b/external/skia/extend-rgb-to-rgba.patch.0
@@ -0,0 +1,23 @@
+diff --git a/include/core/SkSwizzle.h b/include/core/SkSwizzle.h
+index 61e93b2da7..c19063bb91 100644
+--- ./include/core/SkSwizzle.h
++++ ./include/core/SkSwizzle.h
+@@ -16,4 +16,6 @@
+ */
+ SK_API void SkSwapRB(uint32_t* dest, const uint32_t* src, int count);
+ 
++SK_API void SkExtendRGBToRGBA(uint32_t* dest, const uint8_t* src, int count);
++
+ #endif
+diff --git a/src/core/SkSwizzle.cpp b/src/core/SkSwizzle.cpp
+index 301b0184f1..6e6dd27558 100644
+--- ./src/core/SkSwizzle.cpp
++++ ./src/core/SkSwizzle.cpp
+@@ -12,3 +12,7 @@
+ void SkSwapRB(uint32_t* dest, const uint32_t* src, int count) {
+     SkOpts::RGBA_to_BGRA(dest, src, count);
+ }
++
++void SkExtendRGBToRGBA(uint32_t* dest, const uint8_t* src, int count) {
++    SkOpts::RGB_to_RGB1(dest, src, count);
++}
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index f0bffb500194..c000b391eaa2 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -32,6 +32,7 @@
 #include <SkImage.h>
 #include <SkPixelRef.h>
 #include <SkSurface.h>
+#include <SkSwizzle.h>
 
 #include <skia/utils.hxx>
 #include <skia/zone.hxx>
@@ -387,19 +388,16 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
         else if (mBitCount == 24)
         {
             // Convert 24bpp RGB/BGR to 32bpp RGBA/BGRA.
-            std::unique_ptr<sal_uInt8[]> data(
-                new sal_uInt8[mPixelsSize.Height() * mPixelsSize.Width() * 4]);
-            sal_uInt8* dest = data.get();
+            std::unique_ptr<uint32_t[]> data(
+                new uint32_t[mPixelsSize.Height() * mPixelsSize.Width()]);
+            uint32_t* dest = data.get();
             for (long y = 0; y < mPixelsSize.Height(); ++y)
             {
                 const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
-                for (long x = 0; x < mPixelsSize.Width(); ++x)
-                {
-                    *dest++ = *src++;
-                    *dest++ = *src++;
-                    *dest++ = *src++;
-                    *dest++ = 0xff;
-                }
+                // This also works as BGR to BGRA (the function extends 3 bytes to 4
+                // by adding 0xFF alpha, so position of B and R doesn't matter).
+                SkExtendRGBToRGBA(dest, src, mPixelsSize.Width());
+                dest += mPixelsSize.Width();
             }
             if (!bitmap.installPixels(
                     SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(),
@@ -647,6 +645,17 @@ void SkiaSalBitmap::EnsureBitmapData()
             }
         }
     }
+    else if (mBitCount == 8 && mPalette.IsGreyPalette())
+    {
+        for (long y = 0; y < mSize.Height(); ++y)
+        {
+            const uint8_t* src = static_cast<uint8_t*>(mBitmap.getAddr(0, y));
+            sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
+            // no actual data conversion, use one color channel as the gray value
+            for (long x = 0; x < mSize.Width(); ++x)
+                dest[x] = src[x * 4];
+        }
+    }
     else
     {
         std::unique_ptr<vcl::ScanlineWriter> pWriter
commit 912773d521fd6b8ff90d27f7bd3f5a46fd0df582
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Mar 24 16:21:44 2020 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Apr 7 11:52:32 2020 +0200

    use delayed scaling in SalSkiaBitmap
    
    This allows doing the scaling at least in some cases on the GPU.
    Pending scaling is detected by mSize (logical size) != mPixelSize
    (actual size of pixel data).
    
    Change-Id: I8adef13750c195fdbe48c9167737a0c31cda66d5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91767
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx
index 762e45c420b8..a5f264ae2ba1 100644
--- a/vcl/inc/skia/salbmp.hxx
+++ b/vcl/inc/skia/salbmp.hxx
@@ -73,6 +73,8 @@ private:
     // Reset the cached images allocated in GetSkImage()/GetAlphaSkImage(),
     // and also the SkBitmap allocated in GetAsSkBitmap().
     void ResetCachedData();
+    // Sets the data only as SkImage (will be converted as needed).
+    void ResetToSkImage(sk_sp<SkImage> image);
     // Call to ensure mBuffer has data (will convert from mImage if necessary).
     void EnsureBitmapData();
     void EnsureBitmapData() const { return const_cast<SkiaSalBitmap*>(this)->EnsureBitmapData(); }
@@ -117,6 +119,11 @@ private:
     SkBitmap mBitmap; // cached mBuffer, if needed
     sk_sp<SkImage> mImage; // possibly GPU-backed
     sk_sp<SkImage> mAlphaImage; // cached contents as alpha image, possibly GPU-backed
+    // Actual scaling triggered by scale() is done on-demand. This is the size of the pixel
+    // data in mBuffer, if it differs from mSize, then there is a scaling operation pending.
+    Size mPixelsSize;
+    SkFilterQuality mScaleQuality = kHigh_SkFilterQuality; // quality for on-demand scaling
+    bool mDisableScale = false; // used to block our scale()
 #ifdef DBG_UTIL
     int mWriteAccessCount = 0; // number of write AcquireAccess() that have not been released
 #endif
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 27de5fc82508..f0bffb500194 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -58,7 +58,7 @@ SkiaSalBitmap::SkiaSalBitmap(const sk_sp<SkImage>& image)
     mImage = image;
     mPalette = BitmapPalette();
     mBitCount = 32;
-    mSize = Size(image->width(), image->height());
+    mSize = mPixelsSize = Size(image->width(), image->height());
 #ifdef DBG_UTIL
     mWriteAccessCount = 0;
 #endif
@@ -73,14 +73,14 @@ bool SkiaSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const Bitmap
         return false;
     mPalette = rPal;
     mBitCount = nBitCount;
-    mSize = rSize;
+    mSize = mPixelsSize = rSize;
 #ifdef DBG_UTIL
     mWriteAccessCount = 0;
 #endif
     if (!CreateBitmapData())
     {
         mBitCount = 0;
-        mSize = Size();
+        mSize = mPixelsSize = Size();
         mPalette = BitmapPalette();
         return false;
     }
@@ -146,6 +146,7 @@ bool SkiaSalBitmap::Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount)
     mPalette = src.mPalette;
     mBitCount = src.mBitCount;
     mSize = src.mSize;
+    mPixelsSize = src.mPixelsSize;
     mScanlineSize = src.mScanlineSize;
 #ifdef DBG_UTIL
     mWriteAccessCount = 0;
@@ -156,9 +157,7 @@ bool SkiaSalBitmap::Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount)
         // about it and rely on EnsureBitmapData() doing the conversion from mImage
         // if needed, even if that may need unnecessary to- and from- SkImage
         // conversion.
-        GetSkImage(); // create mImage
-        mBitmap.reset();
-        mBuffer.reset();
+        ResetToSkImage(GetSkImage());
     }
     SAL_INFO("vcl.skia.trace", "create(" << this << "): (" << &src << ")");
     return true;
@@ -282,7 +281,7 @@ bool SkiaSalBitmap::GetSystemData(BitmapSystemData&)
     return false;
 }
 
-bool SkiaSalBitmap::ScalingSupported() const { return true; }
+bool SkiaSalBitmap::ScalingSupported() const { return !mDisableScale; }
 
 bool SkiaSalBitmap::Scale(const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag)
 {
@@ -297,32 +296,39 @@ bool SkiaSalBitmap::Scale(const double& rScaleX, const double& rScaleY, BmpScale
     SAL_INFO("vcl.skia.trace", "scale(" << this << "): " << mSize << "->" << newSize << ":"
                                         << static_cast<int>(nScaleFlag));
 
-    SkPaint paint;
+    // The idea here is that the actual scaling will be delayed until the result
+    // is actually needed. Usually the scaled bitmap will be drawn somewhere,
+    // so delaying will mean the scaling can be done as a part of GetSkImage().
+    // That means it can be GPU-accelerated, while done here directly it would need
+    // to be either done by CPU, or with the CPU->GPU->CPU roundtrip required
+    // by GPU-accelereated scaling.
+    // Pending scaling is detected by 'mSize != mPixelsSize'.
+    SkFilterQuality currentQuality;
     switch (nScaleFlag)
     {
         case BmpScaleFlag::Fast:
-            paint.setFilterQuality(kNone_SkFilterQuality);
+            currentQuality = kNone_SkFilterQuality;
             break;
         case BmpScaleFlag::Default:
-            paint.setFilterQuality(kMedium_SkFilterQuality);
+            currentQuality = kMedium_SkFilterQuality;
             break;
         case BmpScaleFlag::BestQuality:
-            paint.setFilterQuality(kHigh_SkFilterQuality);
+            currentQuality = kHigh_SkFilterQuality;
             break;
         default:
             return false;
     }
-    sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(newSize);
-    assert(surface);
-    paint.setBlendMode(SkBlendMode::kSrc); // draw as is, including alpha
-    surface->getCanvas()->drawImageRect(
-        GetSkImage(), SkRect::MakeXYWH(0, 0, mSize.Width(), mSize.Height()),
-        SkRect::MakeXYWH(0, 0, newSize.Width(), newSize.Height()), &paint);
-    // This will get generated from mImage if needed.
-    mBuffer.reset();
-    ResetCachedData();
-    mImage = surface->makeImageSnapshot();
+    // if there is already one scale() pending, use the lowest quality of all requested
+    static_assert(kMedium_SkFilterQuality < kHigh_SkFilterQuality);
+    mScaleQuality = std::min(mScaleQuality, currentQuality);
+    // scaling will be actually done on-demand when needed, the need will be recognized
+    // by mSize != mPixelsSize
     mSize = newSize;
+    // Do not reset cached data if mImage is possibly the only data we have.
+    if (mBuffer)
+        ResetCachedData();
+    // The rest will be handled when the scaled bitmap is actually needed,
+    // such as in EnsureBitmapData() or GetSkImage().
     return true;
 }
 
@@ -354,6 +360,7 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
     if (!mBitmap.isNull())
         return mBitmap;
     EnsureBitmapData();
+    assert(mSize == mPixelsSize); // data has already been scaled if needed
     SkiaZone zone;
     SkBitmap bitmap;
     if (mBuffer)
@@ -362,7 +369,7 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
         {
             // Make a copy, the bitmap should be immutable (otherwise converting it
             // to SkImage will make a copy anyway).
-            const size_t bytes = mSize.Height() * mScanlineSize;
+            const size_t bytes = mPixelsSize.Height() * mScanlineSize;
             std::unique_ptr<sal_uInt8[]> data(new sal_uInt8[bytes]);
             memcpy(data.get(), mBuffer.get(), bytes);
 #if SKIA_USE_BITMAP32
@@ -371,8 +378,8 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
             SkAlphaType alphaType = kUnpremul_SkAlphaType;
 #endif
             if (!bitmap.installPixels(
-                    SkImageInfo::MakeS32(mSize.Width(), mSize.Height(), alphaType), data.release(),
-                    mSize.Width() * 4,
+                    SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(), alphaType),
+                    data.release(), mPixelsSize.Width() * 4,
                     [](void* addr, void*) { delete[] static_cast<sal_uInt8*>(addr); }, nullptr))
                 abort();
             bitmap.setImmutable();
@@ -380,12 +387,13 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
         else if (mBitCount == 24)
         {
             // Convert 24bpp RGB/BGR to 32bpp RGBA/BGRA.
-            std::unique_ptr<sal_uInt8[]> data(new sal_uInt8[mSize.Height() * mSize.Width() * 4]);
+            std::unique_ptr<sal_uInt8[]> data(
+                new sal_uInt8[mPixelsSize.Height() * mPixelsSize.Width() * 4]);
             sal_uInt8* dest = data.get();
-            for (long y = 0; y < mSize.Height(); ++y)
+            for (long y = 0; y < mPixelsSize.Height(); ++y)
             {
                 const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
-                for (long x = 0; x < mSize.Width(); ++x)
+                for (long x = 0; x < mPixelsSize.Width(); ++x)
                 {
                     *dest++ = *src++;
                     *dest++ = *src++;
@@ -394,8 +402,9 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
                 }
             }
             if (!bitmap.installPixels(
-                    SkImageInfo::MakeS32(mSize.Width(), mSize.Height(), kOpaque_SkAlphaType),
-                    data.release(), mSize.Width() * 4,
+                    SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(),
+                                         kOpaque_SkAlphaType),
+                    data.release(), mPixelsSize.Width() * 4,
                     [](void* addr, void*) { delete[] static_cast<sal_uInt8*>(addr); }, nullptr))
                 abort();
             bitmap.setImmutable();
@@ -408,12 +417,13 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
 #define GET_FORMAT                                                                                 \
     (kN32_SkColorType == kBGRA_8888_SkColorType ? BitConvert::BGRA : BitConvert::RGBA)
             std::unique_ptr<sal_uInt8[]> data
-                = convertDataBitCount(mBuffer.get(), mSize.Width(), mSize.Height(), mBitCount,
-                                      mScanlineSize, mPalette, GET_FORMAT);
+                = convertDataBitCount(mBuffer.get(), mPixelsSize.Width(), mPixelsSize.Height(),
+                                      mBitCount, mScanlineSize, mPalette, GET_FORMAT);
 #undef GET_FORMAT
             if (!bitmap.installPixels(
-                    SkImageInfo::MakeS32(mSize.Width(), mSize.Height(), kOpaque_SkAlphaType),
-                    data.release(), mSize.Width() * 4,
+                    SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(),
+                                         kOpaque_SkAlphaType),
+                    data.release(), mPixelsSize.Width() * 4,
                     [](void* addr, void*) { delete[] static_cast<sal_uInt8*>(addr); }, nullptr))
                 abort();
             bitmap.setImmutable();
@@ -429,7 +439,28 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetSkImage() const
     assert(mWriteAccessCount == 0);
 #endif
     if (mImage)
+    {
+        if (mImage->width() != mSize.Width() || mImage->height() != mSize.Height())
+        {
+            assert(!mBuffer); // This code should be only called if only mImage holds data.
+            SkiaZone zone;
+            sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize);
+            assert(surface);
+            SkPaint paint;
+            paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
+            paint.setFilterQuality(mScaleQuality);
+            surface->getCanvas()->drawImageRect(
+                mImage, SkRect::MakeWH(mImage->width(), mImage->height()),
+                SkRect::MakeWH(mSize.Width(), mSize.Height()), &paint);
+            SAL_INFO("vcl.skia.trace", "getskimage(" << this << "): image scaled "
+                                                     << Size(mImage->width(), mImage->height())
+                                                     << "->" << mSize << ":"
+                                                     << static_cast<int>(mScaleQuality));
+            SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this);
+            thisPtr->mImage = surface->makeImageSnapshot();
+        }
         return mImage;
+    }
     SkiaZone zone;
     sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize);
     assert(surface);
@@ -447,10 +478,14 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const
     assert(mWriteAccessCount == 0);
 #endif
     if (mAlphaImage)
+    {
+        assert(mSize == mPixelsSize); // data has already been scaled if needed
         return mAlphaImage;
+    }
     SkiaZone zone;
     // TODO can we convert directly mImage -> mAlphaImage?
     EnsureBitmapData();
+    assert(mSize == mPixelsSize); // data has already been scaled if needed
     SkBitmap alphaBitmap;
     if (mBuffer && mBitCount <= 8)
     {
@@ -512,7 +547,49 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const
 void SkiaSalBitmap::EnsureBitmapData()
 {
     if (mBuffer)
+    {
+        if (mSize != mPixelsSize) // pending scaling?
+        {
+            // This will be pixel->pixel scaling, use VCL algorithm, it should be faster than Skia
+            // (no need to possibly convert bpp, it's multithreaded,...).
+            std::shared_ptr<SkiaSalBitmap> src = std::make_shared<SkiaSalBitmap>();
+            if (!src->Create(*this))
+                abort();
+            // force 'src' to use VCL's scaling
+            src->mDisableScale = true;
+            src->mSize = src->mPixelsSize;
+            Bitmap bitmap(src);
+            BmpScaleFlag scaleFlag;
+            switch (mScaleQuality)
+            {
+                case kNone_SkFilterQuality:
+                    scaleFlag = BmpScaleFlag::Fast;
+                    break;
+                case kMedium_SkFilterQuality:
+                    scaleFlag = BmpScaleFlag::Default;
+                    break;
+                case kHigh_SkFilterQuality:
+                    scaleFlag = BmpScaleFlag::BestQuality;
+                    break;
+                default:
+                    abort();
+            }
+            bitmap.Scale(mSize, scaleFlag);
+            assert(dynamic_cast<const SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get()));
+            const SkiaSalBitmap* dest
+                = static_cast<const SkiaSalBitmap*>(bitmap.ImplGetSalBitmap().get());
+            assert(dest->mSize == dest->mPixelsSize);
+            assert(dest->mSize == mSize);
+            SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << "): pixels scaled "
+                                                           << mPixelsSize << "->" << mSize << ":"
+                                                           << static_cast<int>(mScaleQuality));
+            Destroy();
+            Create(*dest);
+            mDisableScale = false;
+        }
         return;
+    }
+    // Try to fill mBuffer from mImage.
     if (!mImage)
         return;
     SkiaZone zone;
@@ -529,7 +606,20 @@ void SkiaSalBitmap::EnsureBitmapData()
     SkCanvas canvas(mBitmap);
     SkPaint paint;
     paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
-    canvas.drawImage(mImage, 0, 0, &paint);
+    if (mSize != mPixelsSize) // pending scaling?
+    {
+        paint.setFilterQuality(mScaleQuality);
+        canvas.drawImageRect(mImage,
+                             SkRect::MakeWH(mPixelsSize.getWidth(), mPixelsSize.getHeight()),
+                             SkRect::MakeWH(mSize.getWidth(), mSize.getHeight()), &paint);
+        SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << "): image scaled " << mPixelsSize
+                                                       << "->" << mSize << ":"
+                                                       << static_cast<int>(mScaleQuality));
+        mPixelsSize = mSize;
+        mScaleQuality = kNone_SkFilterQuality;
+    }
+    else
+        canvas.drawImage(mImage, 0, 0, &paint);
     canvas.flush();
     mBitmap.setImmutable();
     assert(mBuffer != nullptr);
@@ -600,11 +690,23 @@ void SkiaSalBitmap::EnsureBitmapUniqueData()
 void SkiaSalBitmap::ResetCachedData()
 {
     SkiaZone zone;
+    // There may be a case when only mImage is set and CreatBitmapData() will create
+    // mBuffer from it if needed, in that case ResetToSkImage() should be used.
+    assert(mBuffer.get() || !mImage);
     mBitmap.reset();
     mAlphaImage.reset();
     mImage.reset();
 }
 
+void SkiaSalBitmap::ResetToSkImage(sk_sp<SkImage> image)
+{
+    SkiaZone zone;
+    mBuffer.reset();
+    mBitmap.reset();
+    mAlphaImage.reset();
+    mImage = image;
+}
+
 #ifdef DBG_UTIL
 void SkiaSalBitmap::dump(const char* file) const
 {
@@ -613,6 +715,7 @@ void SkiaSalBitmap::dump(const char* file) const
     SkBitmap saveBitmap = mBitmap;
     bool resetBuffer = !mBuffer;
     int saveWriteAccessCount = mWriteAccessCount;
+    Size savePrescaleSize = mPixelsSize;
     SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this);
     // avoid possible assert
     thisPtr->mWriteAccessCount = 0;
@@ -624,13 +727,15 @@ void SkiaSalBitmap::dump(const char* file) const
     thisPtr->mImage = saveImage;
     thisPtr->mAlphaImage = saveAlphaImage;
     thisPtr->mWriteAccessCount = saveWriteAccessCount;
+    thisPtr->mPixelsSize = savePrescaleSize;
 }
 
 void SkiaSalBitmap::verify() const
 {
     if (!mBuffer)
         return;
-    size_t canary = mScanlineSize * mSize.Height();
+    // Use mPixelsSize, that describes the size of the actual data.
+    size_t canary = mScanlineSize * mPixelsSize.Height();
     assert(memcmp(mBuffer.get() + canary, CANARY, sizeof(CANARY)) == 0);
 }
 


More information about the Libreoffice-commits mailing list