vcl/skia/gdiimpl.cxx | 52 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-)
New commits: commit 81edf0ceef264dbbb338d2ed91378baa59b7a3bf Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Mon Apr 6 17:10:20 2020 +0200 Commit: Luboš Luňák <l.lu...@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.lu...@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); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits