vcl/inc/salbmp.hxx                |    5 +++++
 vcl/inc/skia/salbmp.hxx           |    1 +
 vcl/skia/salbmp.cxx               |   25 +++++++++++++++++++++++++
 vcl/source/bitmap/bitmappaint.cxx |    2 +-
 4 files changed, 32 insertions(+), 1 deletion(-)

New commits:
commit 72f2de04a23680fcb75cf5bc89b3422f9e89cdef
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Fri Jun 30 15:02:16 2023 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sun Jul 2 16:57:46 2023 +0200

    optimised Skia Invert() operation
    
    which is not that important right now, but my upcoming
    transparency->alpha patch will make more heavy use of Invert(),
    and this change will reduce the cost of that
    
    Change-Id: I53d8dfbf153f16f4d94022527c71d70d08392dfc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153857
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx
index 2ffffb93fb4d..3f9dafab15dc 100644
--- a/vcl/inc/salbmp.hxx
+++ b/vcl/inc/salbmp.hxx
@@ -104,6 +104,11 @@ public:
         return false;
     }
 
+    virtual bool            Invert()
+    {
+        return false;
+    }
+
 #if defined MACOSX || defined IOS
     // Related: tdf#146842 Eliminate temporary copies of SkiaSalBitmap when
     // printing
diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx
index 8a974f08566c..3c8b1a964806 100644
--- a/vcl/inc/skia/salbmp.hxx
+++ b/vcl/inc/skia/salbmp.hxx
@@ -64,6 +64,7 @@ public:
     virtual bool ConvertToGreyscale() override;
     virtual bool Erase(const Color& color) override;
     virtual bool AlphaBlendWith(const SalBitmap& rSalBmp) override;
+    virtual bool Invert() override;
 #if defined MACOSX || defined IOS
     virtual CGImageRef CreateWithMask(const SalBitmap& rMask, int nX, int nY, 
int nWidth,
                                       int nHeight) const override;
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 57cea14316c5..1ce85dd0e837 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -623,6 +623,31 @@ bool SkiaSalBitmap::AlphaBlendWith(const SalBitmap& 
rSalBmp)
     return true;
 }
 
+bool SkiaSalBitmap::Invert()
+{
+#ifdef DBG_UTIL
+    assert(mWriteAccessCount == 0);
+#endif
+    // Normally this would need to convert contents of mBuffer for all 
possible formats,
+    // so just let the VCL algorithm do it.
+    // Avoid the costly SkImage->buffer->SkImage conversion.
+    if (!mBuffer && mImage && !mEraseColorSet)
+    {
+        // This is 8-bit bitmap serving as alpha/transparency/mask, so the 
image itself needs no alpha.
+        sk_sp<SkSurface> surface = createSkSurface(mSize, kOpaque_SkAlphaType);
+        surface->getCanvas()->clear(SK_ColorWHITE);
+        SkPaint paint;
+        paint.setBlendMode(SkBlendMode::kDifference);
+        surface->getCanvas()->drawImage(
+            mImage, 0, 0, SkSamplingOptions(SkFilterMode::kLinear, 
SkMipmapMode::kLinear), &paint);
+        ResetToSkImage(makeCheckedImageSnapshot(surface));
+        DataChanged();
+        SAL_INFO("vcl.skia.trace", "invert(" << this << ")");
+        return true;
+    }
+    return false;
+}
+
 SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
 {
 #ifdef DBG_UTIL
diff --git a/vcl/source/bitmap/bitmappaint.cxx 
b/vcl/source/bitmap/bitmappaint.cxx
index f454aa97affa..7701af429ef6 100644
--- a/vcl/source/bitmap/bitmappaint.cxx
+++ b/vcl/source/bitmap/bitmappaint.cxx
@@ -77,7 +77,7 @@ bool Bitmap::Invert()
 
             pAcc->SetPalette(aBmpPal);
         }
-        else
+        else if (!mxSalBmp->Invert()) // try optimised call first
         {
             const tools::Long nWidth = pAcc->Width();
             const tools::Long nHeight = pAcc->Height();

Reply via email to