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

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Thu May 14 09:58:24 UTC 2020


 vcl/skia/SkiaHelper.cxx |    3 +
 vcl/skia/gdiimpl.cxx    |   86 +++++++++++++++++++++++-------------------------
 2 files changed, 44 insertions(+), 45 deletions(-)

New commits:
commit 1b5bd34d8430690b19fae0d0febfd810b9525ca2
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed May 13 19:25:15 2020 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Thu May 14 11:57:49 2020 +0200

    cache Skia' drawAlphaBitmap() in raster mode (tdf#104878)
    
    Moving the mouse with the bug document triggers repeated calls
    to drawAlphaBitmap(), which is somewhat costly if not GPU-accelerated.
    Now the main cost in that bugreport is generating the frames
    all over again.
    
    Change-Id: Ic44811c713a745459f0af811c3d55038c944d89e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94152
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index d7004a7afcb7..aab6560b2554 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -489,12 +489,13 @@ sk_sp<SkImage> findCachedImage(const OString& key)
             if (it->key == key)
             {
                 sk_sp<SkImage> ret = it->image;
-                SAL_INFO("vcl.skia.trace", "findcachedimage " << it->image);
+                SAL_INFO("vcl.skia.trace", "findcachedimage " << it->image << " found");
                 imageCache->splice(imageCache->begin(), *imageCache, it);
                 return ret;
             }
         }
     }
+    SAL_INFO("vcl.skia.trace", "findcachedimage " << key << " not found");
     return nullptr;
 }
 
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 436a9d35d43d..28183ecf10f4 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -1256,57 +1256,23 @@ bool SkiaSalGraphicsImpl::drawEPS(long, long, long, long, void*, sal_uInt32)
     return false;
 }
 
-bool SkiaSalGraphicsImpl::drawAlphaBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSourceBitmap,
-                                          const SalBitmap& rAlphaBitmap)
-{
-    assert(dynamic_cast<const SkiaSalBitmap*>(&rSourceBitmap));
-    assert(dynamic_cast<const SkiaSalBitmap*>(&rAlphaBitmap));
-    sk_sp<SkSurface> tmpSurface = SkiaHelper::createSkSurface(rSourceBitmap.GetSize());
-    if (!tmpSurface)
-        return false;
-    SkCanvas* canvas = tmpSurface->getCanvas();
-    SkPaint paint;
-    paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
-    canvas->drawImage(static_cast<const SkiaSalBitmap&>(rSourceBitmap).GetSkImage(), 0, 0, &paint);
-    paint.setBlendMode(SkBlendMode::kDstOut); // VCL alpha is one-minus-alpha
-    canvas->drawImage(static_cast<const SkiaSalBitmap&>(rAlphaBitmap).GetAlphaSkImage(), 0, 0,
-                      &paint);
-    drawImage(rPosAry, tmpSurface->makeImageSnapshot());
-    return true;
-}
-
-void SkiaSalGraphicsImpl::drawImage(const SalTwoRect& rPosAry, const sk_sp<SkImage>& aImage,
-                                    SkBlendMode eBlendMode)
-{
-    SkRect aSourceRect
-        = SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
-    SkRect aDestinationRect = SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY,
-                                               rPosAry.mnDestWidth, rPosAry.mnDestHeight);
-
-    SkPaint aPaint;
-    aPaint.setBlendMode(eBlendMode);
-
-    preDraw();
-    SAL_INFO("vcl.skia.trace", "drawimage(" << this << "): " << rPosAry << ":" << int(eBlendMode));
-    getDrawCanvas()->drawImageRect(aImage, aSourceRect, aDestinationRect, &aPaint);
-    addXorRegion(aDestinationRect);
-    postDraw();
-}
-
 // 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.
 static sk_sp<SkImage> mergeBitmaps(const SkiaSalBitmap& bitmap, const SkiaSalBitmap* alphaBitmap,
-                                   const Size targetSize, bool blockCaching)
+                                   const Size targetSize, bool blockCaching = false)
 {
     sk_sp<SkImage> image;
     OString key;
-    if (targetSize == bitmap.GetSize())
-        blockCaching = true; // probably not much point in caching if no scaling is involved
+    if (alphaBitmap == nullptr && targetSize == bitmap.GetSize())
+        blockCaching = true; // probably not much point in caching of just doing a copy
     if (targetSize.Width() > bitmap.GetSize().Width()
         || targetSize.Height() > bitmap.GetSize().Height())
         blockCaching = true; // caching enlarging is probably wasteful and not worth it
     if (bitmap.GetSize().Width() < 100 && bitmap.GetSize().Height() < 100)
         blockCaching = true; // image too small to be worth caching
+    if (SkiaHelper::renderMethodToUse() != SkiaHelper::RenderRaster
+        && targetSize == bitmap.GetSize())
+        blockCaching = true; // GPU-accelerated shouldn't need caching of applying alpha
     if (!blockCaching)
     {
         OStringBuffer keyBuf;
@@ -1377,6 +1343,36 @@ static sk_sp<SkImage> mergeBitmaps(const SkiaSalBitmap& bitmap, const SkiaSalBit
     return image;
 }
 
+bool SkiaSalGraphicsImpl::drawAlphaBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSourceBitmap,
+                                          const SalBitmap& rAlphaBitmap)
+{
+    assert(dynamic_cast<const SkiaSalBitmap*>(&rSourceBitmap));
+    assert(dynamic_cast<const SkiaSalBitmap*>(&rAlphaBitmap));
+    sk_sp<SkImage> image
+        = mergeBitmaps(static_cast<const SkiaSalBitmap&>(rSourceBitmap),
+                       static_cast<const SkiaSalBitmap*>(&rAlphaBitmap), rSourceBitmap.GetSize());
+    drawImage(rPosAry, image);
+    return true;
+}
+
+void SkiaSalGraphicsImpl::drawImage(const SalTwoRect& rPosAry, const sk_sp<SkImage>& aImage,
+                                    SkBlendMode eBlendMode)
+{
+    SkRect aSourceRect
+        = SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight);
+    SkRect aDestinationRect = SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY,
+                                               rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+
+    SkPaint aPaint;
+    aPaint.setBlendMode(eBlendMode);
+
+    preDraw();
+    SAL_INFO("vcl.skia.trace", "drawimage(" << this << "): " << rPosAry << ":" << int(eBlendMode));
+    getDrawCanvas()->drawImageRect(aImage, aSourceRect, aDestinationRect, &aPaint);
+    addXorRegion(aDestinationRect);
+    postDraw();
+}
+
 bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
                                                 const basegfx::B2DPoint& rX,
                                                 const basegfx::B2DPoint& rY,
@@ -1389,10 +1385,12 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
     const SkiaSalBitmap& rSkiaBitmap = static_cast<const SkiaSalBitmap&>(rSourceBitmap);
     const SkiaSalBitmap* pSkiaAlphaBitmap = static_cast<const SkiaSalBitmap*>(pAlphaBitmap);
 
-    // setup the image transformation
-    // using the rNull, rX, rY points as destinations for the (0,0), (Width,0), (0,Height) source points
-    const basegfx::B2DVector aXRel = rX - rNull;
-    const basegfx::B2DVector aYRel = rY - rNull;
+    // Setup the image transformation,
+    // using the rNull, rX, rY points as destinations for the (0,0), (Width,0), (0,Height) source points.
+    // Round to pixels, otherwise kMScaleX/Y below could be slightly != 1, causing unnecessary uncached
+    // scaling.
+    const basegfx::B2IVector aXRel = basegfx::fround(rX - rNull);
+    const basegfx::B2IVector aYRel = basegfx::fround(rY - rNull);
 
     const Size aSize = rSourceBitmap.GetSize();
 


More information about the Libreoffice-commits mailing list