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

New commits:
commit b99aada53eb259a3045ced558ebc9c44d3eb722f
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Tue Dec 8 12:48:08 2020 +0100
Commit:     Luboš Luňák <l.lu...@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.lu...@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);
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to