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

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Wed Dec 9 10:51:32 UTC 2020


 vcl/skia/salbmp.cxx |   49 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 5 deletions(-)

New commits:
commit b99aada53eb259a3045ced558ebc9c44d3eb722f
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Dec 8 12:48:08 2020 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Dec 9 11:50:56 2020 +0100

    faster Skia conversion to alpha for the alpha-vdev hack
    
    SkColorFilter::Matrix() uses a matrix and some range checks, so
    it's faster to just directly convert RGBA -> R in order to get
    the one channel we want.
    
    Change-Id: If7e42c13ec2a4aba5f98ada4facccac1eaf4f7a7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107409
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 0ce99d5778e4..096a667e9382 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -754,10 +754,46 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const
     if (mImage)
     {
         SkiaZone zone;
-        sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize, kAlpha_8_SkColorType);
-        assert(surface);
-        SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
+        bool scaling = mImage->width() != mSize.Width() || mImage->height() != mSize.Height();
+        SkPixmap pixmap;
+        // Note: We cannot do this when 'scaling' because SkCanvas::drawImageRect()
+        // with kAlpha_8_SkColorType as source and destination would act as SkBlendMode::kSrcOver
+        // despite SkBlendMode::kSrc set (https://bugs.chromium.org/p/skia/issues/detail?id=9692).
+        if (mImage->peekPixels(&pixmap) && !scaling)
+        {
+            assert(pixmap.colorType() == kN32_SkColorType);
+            // In non-GPU mode, convert 32bit data to 8bit alpha, this is faster than
+            // the SkColorFilter below. Since this is the VCL alpha-vdev alpha, where
+            // all R,G,B are the same and in fact mean alpha, this means we simply take one
+            // 8bit channel from the input, and that's the output.
+            SkBitmap bitmap;
+            if (!bitmap.installPixels(pixmap))
+                abort();
+            SkBitmap alphaBitmap;
+            if (!alphaBitmap.tryAllocPixels(SkImageInfo::MakeA8(bitmap.width(), bitmap.height())))
+                abort();
+            if (int(bitmap.rowBytes()) == bitmap.width() * 4)
+            {
+                SkConvertRGBAToR(alphaBitmap.getAddr8(0, 0), bitmap.getAddr32(0, 0),
+                                 bitmap.width() * bitmap.height());
+            }
+            else
+            {
+                for (tools::Long y = 0; y < bitmap.height(); ++y)
+                    SkConvertRGBAToR(alphaBitmap.getAddr8(0, y), bitmap.getAddr32(0, y),
+                                     bitmap.width());
+            }
+            alphaBitmap.setImmutable();
+            sk_sp<SkImage> alphaImage = SkiaHelper::createSkImage(alphaBitmap);
+            assert(alphaImage);
+            SAL_INFO("vcl.skia.trace", "getalphaskimage(" << this << ") from raster image");
+            // Don't bother here with ConserveMemory(), mImage -> mAlphaImage conversions should
+            // generally only happen with the separate-alpha-outdev hack, and those bitmaps should
+            // be temporary.
+            SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this);
+            thisPtr->mAlphaImage = alphaImage;
+            return mAlphaImage;
+        }
         // Move the R channel value to the alpha channel. This seems to be the only
         // way to reinterpret data in SkImage as an alpha SkImage without accessing the pixels.
         // NOTE: The matrix is 4x5 organized as columns (i.e. each line is a column, not a row).
@@ -765,13 +801,16 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const
                                            0, 0, 0, 0, 0, // G column
                                            0, 0, 0, 0, 0, // B column
                                            1, 0, 0, 0, 0); // A column
+        SkPaint paint;
         paint.setColorFilter(SkColorFilters::Matrix(redToAlpha));
-        bool scaling = mImage->width() != mSize.Width() || mImage->height() != mSize.Height();
         if (scaling)
         {
             assert(!mBuffer); // This code should be only called if only mImage holds data.
             paint.setFilterQuality(mScaleQuality);
         }
+        sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize, kAlpha_8_SkColorType);
+        assert(surface);
+        paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
         surface->getCanvas()->drawImageRect(mImage,
                                             SkRect::MakeWH(mImage->width(), mImage->height()),
                                             SkRect::MakeWH(mSize.Width(), mSize.Height()), &paint);


More information about the Libreoffice-commits mailing list