summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-05-13 19:25:15 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-05-14 11:57:49 +0200
commit1b5bd34d8430690b19fae0d0febfd810b9525ca2 (patch)
tree41197c5562c9d7cb27172616c0a29f0e73ec1084 /vcl
parentfc0bff85f3338cb4fe8f4d42421cb69801cb3abb (diff)
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@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/skia/SkiaHelper.cxx3
-rw-r--r--vcl/skia/gdiimpl.cxx86
2 files changed, 44 insertions, 45 deletions
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();