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

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Mon Sep 7 13:20:17 UTC 2020


 vcl/skia/gdiimpl.cxx |   92 +++++++++++++--------------------------------------
 1 file changed, 24 insertions(+), 68 deletions(-)

New commits:
commit 717ce6838b7ef0add1f9a9655e2b8c0bf60203f0
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Sat Sep 5 07:05:16 2020 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Sep 7 15:19:32 2020 +0200

    avoid temporary SkImage when merging bitmaps in Skia (tdf#136244)
    
    The original idea was to create a temporary SkImage in order to first
    merge the bitmap and its alpha bitmap, otherwise scaling already
    while merging them could introduce artefacts because of smoothscaling
    the alpha. But SkShader use blends the bitmap and alpha values
    before the scaling, so this is actually not necessary.
    
    Change-Id: I4e351611e3c33530dd5326c542b0a191955b5109
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102068
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 61f843dee609..652fea88f38e 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -1391,31 +1391,6 @@ void SkiaSalGraphicsImpl::invert(sal_uInt32 nPoints, const SalPoint* pPointArray
 
 bool SkiaSalGraphicsImpl::drawEPS(long, long, long, long, void*, sal_uInt32) { return false; }
 
-static void drawBitmapToCanvas(const SkiaSalBitmap& bitmap, SkCanvas* canvas, const SkPaint& paint)
-{
-    if (bitmap.PreferSkShader())
-    {
-        SkPaint paint2(paint);
-        paint2.setShader(bitmap.GetSkShader());
-        canvas->drawPaint(paint2);
-    }
-    else
-        canvas->drawImage(bitmap.GetSkImage(), 0, 0, &paint);
-}
-
-static void drawAlphaBitmapToCanvas(const SkiaSalBitmap& bitmap, SkCanvas* canvas,
-                                    const SkPaint& paint)
-{
-    if (bitmap.PreferSkShader())
-    {
-        SkPaint paint2(paint);
-        paint2.setShader(bitmap.GetAlphaSkShader());
-        canvas->drawPaint(paint2);
-    }
-    else
-        canvas->drawImage(bitmap.GetAlphaSkImage(), 0, 0, &paint);
-}
-
 // Create SkImage from a bitmap and possibly an alpha mask (the usual VCL one-minus-alpha),
 // with the given target size. Result will be possibly cached, unless disabled.
 sk_sp<SkImage> SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitmap,
@@ -1477,54 +1452,35 @@ sk_sp<SkImage> SkiaSalGraphicsImpl::mergeCacheBitmaps(const SkiaSalBitmap& bitma
         assert(image->width() == targetSize.Width() && image->height() == targetSize.Height());
         return image;
     }
-    // Combine bitmap + alpha bitmap into one temporary bitmap with alpha.
-    // If scaling is needed, first apply the alpha, then scale, otherwise the scaling might affect the alpha values.
-    if (alphaBitmap && targetSize != bitmap.GetSize())
+    sk_sp<SkSurface> tmpSurface = SkiaHelper::createSkSurface(targetSize);
+    if (!tmpSurface)
+        return nullptr;
+    SkCanvas* canvas = tmpSurface->getCanvas();
+    SkAutoCanvasRestore autoRestore(canvas, true);
+    SkPaint paint;
+    if (targetSize != bitmap.GetSize())
     {
-        sk_sp<SkSurface> mergedSurface = SkiaHelper::createSkSurface(bitmap.GetSize());
-        if (!mergedSurface)
-            return nullptr;
-        SkPaint paint;
-        paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
-        drawBitmapToCanvas(bitmap, mergedSurface->getCanvas(), paint);
-        paint.setBlendMode(SkBlendMode::kDstOut); // VCL alpha is one-minus-alpha
-        drawAlphaBitmapToCanvas(*alphaBitmap, mergedSurface->getCanvas(), paint);
-        sk_sp<SkSurface> scaledSurface = SkiaHelper::createSkSurface(targetSize);
-        if (!scaledSurface)
-            return nullptr;
-        paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
+        SkMatrix matrix;
+        matrix.set(SkMatrix::kMScaleX, 1.0 * targetSize.Width() / bitmap.GetSize().Width());
+        matrix.set(SkMatrix::kMScaleY, 1.0 * targetSize.Height() / bitmap.GetSize().Height());
+        canvas->concat(matrix);
         paint.setFilterQuality(kHigh_SkFilterQuality);
-        scaledSurface->getCanvas()->drawImageRect(
-            mergedSurface->makeImageSnapshot(),
-            SkRect::MakeXYWH(0, 0, bitmap.GetSize().Width(), bitmap.GetSize().Height()),
-            SkRect::MakeXYWH(0, 0, targetSize.Width(), targetSize.Height()), &paint);
-        image = scaledSurface->makeImageSnapshot();
     }
-    else // No alpha or no scaling, scale directly.
+    if (alphaBitmap != nullptr)
     {
-        sk_sp<SkSurface> tmpSurface = SkiaHelper::createSkSurface(targetSize);
-        if (!tmpSurface)
-            return nullptr;
-        SkCanvas* canvas = tmpSurface->getCanvas();
-        SkAutoCanvasRestore autoRestore(canvas, true);
-        SkPaint paint;
-        if (targetSize != bitmap.GetSize())
-        {
-            SkMatrix matrix;
-            matrix.set(SkMatrix::kMScaleX, 1.0 * targetSize.Width() / bitmap.GetSize().Width());
-            matrix.set(SkMatrix::kMScaleY, 1.0 * targetSize.Height() / bitmap.GetSize().Height());
-            canvas->concat(matrix);
-            paint.setFilterQuality(kHigh_SkFilterQuality);
-        }
-        paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
-        drawBitmapToCanvas(bitmap, canvas, paint);
-        if (alphaBitmap != nullptr)
-        {
-            paint.setBlendMode(SkBlendMode::kDstOut); // VCL alpha is one-minus-alpha
-            drawAlphaBitmapToCanvas(*alphaBitmap, canvas, paint);
-        }
-        image = tmpSurface->makeImageSnapshot();
+        canvas->clear(SK_ColorTRANSPARENT);
+        paint.setShader(SkShaders::Blend(SkBlendMode::kDstOut, bitmap.GetSkShader(),
+                                         alphaBitmap->GetAlphaSkShader()));
+        canvas->drawPaint(paint);
     }
+    else if (bitmap.PreferSkShader())
+    {
+        paint.setShader(bitmap.GetSkShader());
+        canvas->drawPaint(paint);
+    }
+    else
+        canvas->drawImage(bitmap.GetSkImage(), 0, 0, &paint);
+    image = tmpSurface->makeImageSnapshot();
     SkiaHelper::addCachedImage(key, image);
     return image;
 }


More information about the Libreoffice-commits mailing list