diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2021-11-16 08:03:06 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2021-11-16 10:41:36 +0100 |
commit | 621430208d29e40ab95509a4e94da6e8313ed389 (patch) | |
tree | 2ad585cae06e6ccf2136e39b76d6a311e30549a8 /vcl | |
parent | adba50494e11ca799ce6a794195ff844dfac7cd3 (diff) |
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.lunak@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/skia/gdiimpl.cxx | 27 |
1 files changed, 21 insertions, 6 deletions
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) |