summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-11-16 08:03:06 +0100
committerLuboš Luňák <l.lunak@collabora.com>2021-11-16 10:41:36 +0100
commit621430208d29e40ab95509a4e94da6e8313ed389 (patch)
tree2ad585cae06e6ccf2136e39b76d6a311e30549a8
parentadba50494e11ca799ce6a794195ff844dfac7cd3 (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>
-rw-r--r--vcl/skia/gdiimpl.cxx27
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)