[Libreoffice-commits] core.git: vcl/skia
LuboÅ¡ LuÅák (via logerrit)
logerrit at kemper.freedesktop.org
Tue Apr 7 09:54:54 UTC 2020
vcl/skia/gdiimpl.cxx | 52 ++++++++++++++++++++++++++++++++++-----------------
1 file changed, 35 insertions(+), 17 deletions(-)
New commits:
commit 81edf0ceef264dbbb338d2ed91378baa59b7a3bf
Author: Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Apr 6 17:10:20 2020 +0200
Commit: Luboš Luňák <l.lunak at collabora.com>
CommitDate: Tue Apr 7 11:54:13 2020 +0200
optimize SkiaSalGraphicsImpl area copying
SkSurface::draw() can avoid copies if it detects the source and
destination are the same surface. This can especially make
a difference on Windows with raster, because RasterWindowContext_win
shares the surface's pixel data with BITMAPINFO, which resets
SkSurface's fWeOwnThePixels, making even makeImageSnapshot()
do copies.
Can be seen in the profile e.g. for tdf#131408.
Change-Id: I08d08974c4725824e05c5644549b920f69b9ce64
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91773
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 e4f064589b21..8b484ea124c7 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -852,6 +852,20 @@ bool SkiaSalGraphicsImpl::drawPolyPolygonBezier(sal_uInt32, const sal_uInt32*,
return false;
}
+static void copyArea(SkCanvas* canvas, sk_sp<SkSurface> surface, long nDestX, long nDestY,
+ long nSrcX, long nSrcY, long nSrcWidth, long nSrcHeight)
+{
+ // Using SkSurface::draw() should be more efficient than SkSurface::makeImageSnapshot(),
+ // because it may detect copying to itself and avoid some needless copies.
+ // It cannot do a subrectangle though, so clip.
+ canvas->save();
+ canvas->clipRect(SkRect::MakeXYWH(nDestX, nDestY, nSrcWidth, nSrcHeight));
+ SkPaint paint;
+ paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
+ surface->draw(canvas, nDestX - nSrcX, nDestY - nSrcY, &paint);
+ canvas->restore();
+}
+
void SkiaSalGraphicsImpl::copyArea(long nDestX, long nDestY, long nSrcX, long nSrcY, long nSrcWidth,
long nSrcHeight, bool /*bWindowInvalidate*/)
{
@@ -861,12 +875,7 @@ void SkiaSalGraphicsImpl::copyArea(long nDestX, long nDestY, long nSrcX, long nS
SAL_INFO("vcl.skia.trace", "copyarea(" << this << "): " << Point(nSrcX, nSrcY) << "->"
<< Point(nDestX, nDestY) << "/"
<< Size(nSrcWidth, nSrcHeight));
- // Do not use makeImageSnapshot(rect), as that one may make a needless data copy.
- sk_sp<SkImage> image = mSurface->makeImageSnapshot();
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
- getDrawCanvas()->drawImageRect(image, SkIRect::MakeXYWH(nSrcX, nSrcY, nSrcWidth, nSrcHeight),
- SkRect::MakeXYWH(nDestX, nDestY, nSrcWidth, nSrcHeight), &paint);
+ ::copyArea(getDrawCanvas(), mSurface, nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight);
if (mXorMode) // limit xor area update
mXorExtents = SkRect::MakeXYWH(nDestX, nDestY, nSrcWidth, nSrcHeight);
postDraw();
@@ -884,17 +893,26 @@ void SkiaSalGraphicsImpl::copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcG
}
else
src = this;
- SAL_INFO("vcl.skia.trace", "copybits(" << this << "): (" << src << "):" << rPosAry);
- // Do not use makeImageSnapshot(rect), as that one may make a needless data copy.
- sk_sp<SkImage> image = src->mSurface->makeImageSnapshot();
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
- getDrawCanvas()->drawImageRect(
- image,
- SkIRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
- SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth,
- rPosAry.mnDestHeight),
- &paint);
+ if (rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight)
+ {
+ SAL_INFO("vcl.skia.trace", "copybits(" << this << "): copy area:" << rPosAry);
+ ::copyArea(getDrawCanvas(), src->mSurface, rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX,
+ rPosAry.mnSrcY, rPosAry.mnDestWidth, rPosAry.mnDestHeight);
+ }
+ else
+ {
+ SAL_INFO("vcl.skia.trace", "copybits(" << this << "): (" << src << "):" << rPosAry);
+ // Do not use makeImageSnapshot(rect), as that one may make a needless data copy.
+ sk_sp<SkImage> image = src->mSurface->makeImageSnapshot();
+ SkPaint paint;
+ paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha
+ getDrawCanvas()->drawImageRect(image,
+ SkIRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY,
+ rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
+ SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY,
+ rPosAry.mnDestWidth, rPosAry.mnDestHeight),
+ &paint);
+ }
if (mXorMode) // limit xor area update
mXorExtents = SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth,
rPosAry.mnDestHeight);
More information about the Libreoffice-commits
mailing list