[Libreoffice-commits] core.git: vcl/inc vcl/source

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Mon Oct 12 13:10:07 UTC 2020


 vcl/inc/bmpfast.hxx        |    5 ++
 vcl/source/gdi/bmpacc.cxx  |   20 +++++----
 vcl/source/gdi/bmpfast.cxx |   97 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+), 8 deletions(-)

New commits:
commit 6036b2486cdc5ba8eac8636b2e087658e3550586
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Oct 9 15:20:43 2020 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Mon Oct 12 15:09:27 2020 +0200

    implement fast bitmap variant for CopyScanline()
    
    JPEG reads RGB, but e.g. with Skia the default bitmap format is BGRA.
    
    Change-Id: Iad1a9e99f286b03db0fa683c14d70b8ad48d3d9d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104120
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/inc/bmpfast.hxx b/vcl/inc/bmpfast.hxx
index f9a1f891bb47..ebdb431fc941 100644
--- a/vcl/inc/bmpfast.hxx
+++ b/vcl/inc/bmpfast.hxx
@@ -21,6 +21,7 @@
 #define INCLUDED_VCL_INC_BMPFAST_HXX
 
 #include <vcl/dllapi.h>
+#include <vcl/Scanline.hxx>
 
 class BitmapWriteAccess;
 class BitmapReadAccess;
@@ -34,6 +35,10 @@ struct SalTwoRect;
 VCL_DLLPUBLIC bool ImplFastBitmapConversion( BitmapBuffer& rDst, const BitmapBuffer& rSrc,
         const SalTwoRect& rTwoRect );
 
+bool ImplFastCopyScanline( long nY, BitmapBuffer& rDst, const BitmapBuffer& rSrc);
+bool ImplFastCopyScanline( long nY, BitmapBuffer& rDst, ConstScanline aSrcScanline,
+    ScanlineFormat nSrcScanlineFormat, sal_uInt32 nSrcScanlineSize);
+
 bool ImplFastBitmapBlending( BitmapWriteAccess const & rDst,
     const BitmapReadAccess& rSrc, const BitmapReadAccess& rMask,
     const SalTwoRect& rTwoRect );
diff --git a/vcl/source/gdi/bmpacc.cxx b/vcl/source/gdi/bmpacc.cxx
index a406951cd7f7..3994f9c1889a 100644
--- a/vcl/source/gdi/bmpacc.cxx
+++ b/vcl/source/gdi/bmpacc.cxx
@@ -24,6 +24,7 @@
 #include <salbmp.hxx>
 #include <svdata.hxx>
 #include <salinst.hxx>
+#include <bmpfast.hxx>
 
 #include <string.h>
 #include <sal/log.hxx>
@@ -344,11 +345,14 @@ void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc
     }
     else
     {
-        // TODO: use fastbmp infrastructure
-        Scanline pScanline = GetScanline( nY );
-        Scanline pScanlineRead = rReadAcc.GetScanline(nY);
-        for( long nX = 0, nWidth = std::min( mpBuffer->mnWidth, rReadAcc.Width() ); nX < nWidth; nX++ )
-            SetPixelOnData( pScanline, nX, rReadAcc.GetPixelFromData( pScanlineRead, nX ) );
+        long nWidth = std::min( mpBuffer->mnWidth, rReadAcc.Width() );
+        if(!ImplFastCopyScanline( nY, *ImplGetBitmapBuffer(), *rReadAcc.ImplGetBitmapBuffer()))
+        {
+            Scanline pScanline = GetScanline( nY );
+            Scanline pScanlineRead = rReadAcc.GetScanline(nY);
+            for( long nX = 0; nX < nWidth; nX++ )
+                SetPixelOnData( pScanline, nX, rReadAcc.GetPixelFromData( pScanlineRead, nX ) );
+        }
     }
 }
 
@@ -371,13 +375,13 @@ void BitmapWriteAccess::CopyScanline( long nY, ConstScanline aSrcScanline,
         memcpy(GetScanline(nY), aSrcScanline, nCount);
     else
     {
+        if(ImplFastCopyScanline( nY, *ImplGetBitmapBuffer(), aSrcScanline, nSrcScanlineFormat, nSrcScanlineSize ))
+            return;
+
         DBG_ASSERT( nFormat != ScanlineFormat::N8BitTcMask &&
                     nFormat != ScanlineFormat::N32BitTcMask,
                     "No support for pixel formats with color masks yet!" );
-
-        // TODO: use fastbmp infrastructure
         FncGetPixel pFncGetPixel;
-
         switch( nFormat )
         {
             case ScanlineFormat::N1BitMsbPal:    pFncGetPixel = GetPixelForN1BitMsbPal; break;
diff --git a/vcl/source/gdi/bmpfast.cxx b/vcl/source/gdi/bmpfast.cxx
index 9ee00b7bdd40..1fe9a9ae543a 100644
--- a/vcl/source/gdi/bmpfast.cxx
+++ b/vcl/source/gdi/bmpfast.cxx
@@ -457,6 +457,103 @@ bool ImplFastBitmapConversion( BitmapBuffer& rDst, const BitmapBuffer& rSrc,
     return false;
 }
 
+static inline ConstScanline ImplGetScanline( const BitmapBuffer& rBuf, long nY )
+{
+    if( rBuf.mnFormat & ScanlineFormat::TopDown )
+        return rBuf.mpBits + nY * rBuf.mnScanlineSize;
+    else
+        return rBuf.mpBits + (rBuf.mnHeight - 1 - nY) * rBuf.mnScanlineSize;
+}
+
+static inline Scanline ImplGetScanline( BitmapBuffer& rBuf, long nY )
+{
+    return const_cast<Scanline>(ImplGetScanline( const_cast<const BitmapBuffer&>(rBuf), nY ));
+}
+
+template <ScanlineFormat DSTFMT, ScanlineFormat SRCFMT>
+static bool ImplCopyToScanline( long nY, BitmapBuffer& rDst, TrueColorPixelPtr<SRCFMT>& rSrcLine, long nSrcWidth )
+{
+    TrueColorPixelPtr<DSTFMT> aDstType;
+    aDstType.SetRawPtr( ImplGetScanline( rDst, nY ));
+    ImplConvertLine( aDstType, rSrcLine, std::min( nSrcWidth, rDst.mnWidth ));
+    return true;
+}
+
+template <ScanlineFormat SRCFMT>
+static bool ImplCopyFromScanline( long nY, BitmapBuffer& rDst, ConstScanline aSrcScanline, long nSrcWidth )
+{
+    TrueColorPixelPtr<SRCFMT> aSrcType;
+    aSrcType.SetRawPtr( const_cast<Scanline>( aSrcScanline ));
+    // select the matching instantiation for the destination's bitmap format
+    switch( RemoveScanline( rDst.mnFormat ))
+    {
+        case ScanlineFormat::N24BitTcBgr:
+            return ImplCopyToScanline<ScanlineFormat::N24BitTcBgr>( nY, rDst, aSrcType, nSrcWidth );
+        case ScanlineFormat::N24BitTcRgb:
+            return ImplCopyToScanline<ScanlineFormat::N24BitTcRgb>( nY, rDst, aSrcType, nSrcWidth );
+
+        case ScanlineFormat::N32BitTcAbgr:
+            return ImplCopyToScanline<ScanlineFormat::N32BitTcAbgr>( nY, rDst, aSrcType, nSrcWidth );
+        case ScanlineFormat::N32BitTcArgb:
+            return ImplCopyToScanline<ScanlineFormat::N32BitTcArgb>( nY, rDst, aSrcType, nSrcWidth );
+        case ScanlineFormat::N32BitTcBgra:
+            return ImplCopyToScanline<ScanlineFormat::N32BitTcBgra>( nY, rDst, aSrcType, nSrcWidth );
+        case ScanlineFormat::N32BitTcRgba:
+            return ImplCopyToScanline<ScanlineFormat::N32BitTcRgba>( nY, rDst, aSrcType, nSrcWidth );
+        default:
+            break;
+    }
+    return false;
+
+}
+
+bool ImplFastCopyScanline( long nY, BitmapBuffer& rDst, ConstScanline aSrcScanline,
+    ScanlineFormat nSrcScanlineFormat, sal_uInt32 nSrcScanlineSize)
+{
+    if( rDst.mnHeight <= nY )
+        return false;
+
+    const ScanlineFormat nSrcFormat = RemoveScanline(nSrcScanlineFormat);
+    const ScanlineFormat nDstFormat = RemoveScanline(rDst.mnFormat);
+
+    // special handling of trivial cases
+    if( nSrcFormat == nDstFormat )
+    {
+        memcpy( ImplGetScanline( rDst, nY ), aSrcScanline, std::min<long>(nSrcScanlineSize, rDst.mnScanlineSize));
+        return true;
+    }
+
+    // select the matching instantiation for the source's bitmap format
+    switch( nSrcFormat )
+    {
+        case ScanlineFormat::N24BitTcBgr:
+            return ImplCopyFromScanline<ScanlineFormat::N24BitTcBgr>( nY, rDst, aSrcScanline, nSrcScanlineSize / 3 );
+        case ScanlineFormat::N24BitTcRgb:
+            return ImplCopyFromScanline<ScanlineFormat::N24BitTcRgb>( nY, rDst, aSrcScanline, nSrcScanlineSize / 3 );
+
+        case ScanlineFormat::N32BitTcAbgr:
+            return ImplCopyFromScanline<ScanlineFormat::N32BitTcAbgr>( nY, rDst, aSrcScanline, nSrcScanlineSize / 4 );
+        case ScanlineFormat::N32BitTcArgb:
+            return ImplCopyFromScanline<ScanlineFormat::N32BitTcArgb>( nY, rDst, aSrcScanline, nSrcScanlineSize / 4 );
+        case ScanlineFormat::N32BitTcBgra:
+            return ImplCopyFromScanline<ScanlineFormat::N32BitTcBgra>( nY, rDst, aSrcScanline, nSrcScanlineSize / 4 );
+        case ScanlineFormat::N32BitTcRgba:
+            return ImplCopyFromScanline<ScanlineFormat::N32BitTcRgba>( nY, rDst, aSrcScanline, nSrcScanlineSize / 4 );
+        default:
+            break;
+    }
+    return false;
+}
+
+bool ImplFastCopyScanline( long nY, BitmapBuffer& rDst, const BitmapBuffer& rSrc)
+{
+    if( nY >= rDst.mnHeight )
+        return false;
+    if( rSrc.maPalette != rDst.maPalette )
+        return false;
+    return ImplFastCopyScanline( nY, rDst, ImplGetScanline( rSrc, nY ), rSrc.mnFormat, rSrc.mnScanlineSize);
+}
+
 template <ScanlineFormat DSTFMT, ScanlineFormat SRCFMT> //,sal_uLong MSKFMT>
 static bool ImplBlendToBitmap( TrueColorPixelPtr<SRCFMT>& rSrcLine,
     BitmapBuffer& rDstBuffer, const BitmapBuffer& rSrcBuffer,


More information about the Libreoffice-commits mailing list