vcl/skia/gdiimpl.cxx | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)
New commits: commit 621430208d29e40ab95509a4e94da6e8313ed389 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Tue Nov 16 08:03:06 2021 +0100 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Nov 16 10:41:36 2021 +0100 optimize Skia's copyArea() to copy less data Change-Id: Ia1cd0522643b58ea1be3ad974c1fc5f7fed657d4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125268 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 b97d2f28c428..4019c436d51d 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -1347,17 +1347,32 @@ void SkiaSalGraphicsImpl::privateCopyBits(const SalTwoRect& rPosAry, SkiaSalGrap rPosAry.mnDestHeight)); SkPaint paint; paint.setBlendMode(SkBlendMode::kSrc); // copy as is, including alpha - SkRect srcRect - = SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight); + SkIRect srcRect = SkIRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, + rPosAry.mnSrcHeight); SkRect destRect = SkRect::MakeXYWH(rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight); // Scaling for source coordinates must be done manually. if (src->mScaling != 1) srcRect = scaleRect(srcRect, src->mScaling); - // Do not use makeImageSnapshot(rect), as that one may make a needless data copy. - getDrawCanvas()->drawImageRect(makeCheckedImageSnapshot(src->mSurface), srcRect, destRect, - makeSamplingOptions(rPosAry, mScaling, src->mScaling), &paint, - SkCanvas::kFast_SrcRectConstraint); + if (src == this) + { + // Copy-to-self means that we'd take a snapshot, which would refcount the data, + // and then drawing would result in copy in write, copying the entire surface. + // Try to copy less by making a snapshot of only what is needed. + sk_sp<SkImage> image = makeCheckedImageSnapshot(src->mSurface, srcRect); + srcRect.offset(-srcRect.x(), -srcRect.y()); + getDrawCanvas()->drawImageRect(image, SkRect::Make(srcRect), destRect, + makeSamplingOptions(rPosAry, mScaling, src->mScaling), + &paint, SkCanvas::kFast_SrcRectConstraint); + } + else + { + // Do not use makeImageSnapshot(rect), as that one may make a needless data copy. + getDrawCanvas()->drawImageRect(makeCheckedImageSnapshot(src->mSurface), + SkRect::Make(srcRect), destRect, + makeSamplingOptions(rPosAry, mScaling, src->mScaling), + &paint, SkCanvas::kFast_SrcRectConstraint); + } } bool SkiaSalGraphicsImpl::blendBitmap(const SalTwoRect& rPosAry, const SalBitmap& rBitmap)