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

Reply via email to