[Libreoffice-commits] core.git: basebmp/source

tsahi glik tsahi.glik at cloudon.com
Fri Sep 27 07:47:30 PDT 2013


 basebmp/source/bitmapdevice.cxx |   87 ++++++++++++++++++++++++++++++----------
 1 file changed, 66 insertions(+), 21 deletions(-)

New commits:
commit 3ea2ce9dacc88c664418e9aa13dc87afcaed9e5a
Author: tsahi glik <tsahi.glik at cloudon.com>
Date:   Fri Aug 30 19:29:50 2013 -0700

    Improve performance of copyArea(), especially relevant for mobile devices.
    
    vigra::copyImage89 does not handle copy areas in the same image so the
    code checks whether the src and dst are same buffer and directs it to
    scaleImage() which is very slow. The whole concept of pixel accessors
    is a huge overhead in the case of direct pixel copy (vigra::copyImage
    is also using pixel accessors). The idea here is to identify when
    direct memory copy is applicable (when the format is an integral
    number of bytes per pixel, src.size==dst.size, and
    src.format==dst.format) and use direct memory block copy and not
    pixel-wise copy. The result is 100x faster than the vigra
    implementation. This direct copy is also handling the case when the
    src and dst are same buffer by copy it from bottom to top when needed
    and using memmove() instead of memcpy().
    
    Change-Id: I8ec589463d6386db82777a916371a5ebbf9e2d50
    Reviewed-on: https://gerrit.libreoffice.org/5707
    Reviewed-by: Tor Lillqvist <tml at collabora.com>
    Tested-by: Tor Lillqvist <tml at collabora.com>

diff --git a/basebmp/source/bitmapdevice.cxx b/basebmp/source/bitmapdevice.cxx
index 24d9ef1..415c0d6 100644
--- a/basebmp/source/bitmapdevice.cxx
+++ b/basebmp/source/bitmapdevice.cxx
@@ -91,6 +91,28 @@ operator^( RGBValue<Value, RedIndex, GreenIndex, BlueIndex> const& lhs,
 namespace basebmp
 {
 
+static const sal_uInt8 bitsPerPixel[] =
+{
+    0,  // NONE
+    1,  // ONE_BIT_MSB_GREY
+    1,  // ONE_BIT_LSB_GREY
+    1,  // ONE_BIT_MSB_PAL
+    1,  // ONE_BIT_LSB_PAL
+    4,  // FOUR_BIT_MSB_GREY
+    4,  // FOUR_BIT_LSB_GREY
+    4,  // FOUR_BIT_MSB_PAL
+    4,  // FOUR_BIT_LSB_PAL
+    8,  // EIGHT_BIT_PAL
+    8,  // EIGHT_BIT_GREY
+    16, // SIXTEEN_BIT_LSB_TC_MASK
+    16, // SIXTEEN_BIT_MSB_TC_MASK
+    24, // TWENTYFOUR_BIT_TC_MASK
+    32, // THIRTYTWO_BIT_TC_MASK_BGRA
+    32, // THIRTYTWO_BIT_TC_MASK_ARGB
+    32, // THIRTYTWO_BIT_TC_MASK_ABGR
+    32, // THIRTYTWO_BIT_TC_MASK_RGBA
+};
+
 namespace
 {
     /** Create the type for an accessor that takes the (mask,bitmap)
@@ -712,6 +734,45 @@ namespace
             damaged( rDstRect );
         }
 
+        void implDrawBitmapDirect(const BitmapDeviceSharedPtr& rSrcBitmap,
+                                  const basegfx::B2IBox&       rSrcRect,
+                                  const basegfx::B2IBox&       rDstRect)
+        {
+            sal_Int32 nSrcX = rSrcRect.getMinX();
+            sal_Int32 nSrcY = rSrcRect.getMinY();
+            sal_Int32 nSrcWidth = rSrcRect.getMaxX() - nSrcX + 1;
+            sal_Int32 nSrcHeight = rSrcRect.getMaxY() - nSrcY + 1;
+            sal_Int32 nDestX = rDstRect.getMinX();
+            sal_Int32 nDestY = rDstRect.getMinY();
+
+            char* dstBuf =  (char*)getBuffer().get();
+            char* srcBuf =  (char*)rSrcBitmap->getBuffer().get();
+            sal_Int32 dstStride =  getScanlineStride();
+            sal_Int32 srcStride =  rSrcBitmap->getScanlineStride();
+            int bytesPerPixel = (bitsPerPixel[getScanlineFormat()] + 7) >> 3; // round up to bytes
+
+            if (dstBuf == srcBuf && nSrcY < nDestY) // reverse copy order to avoid overlapping
+            {
+                dstBuf += dstStride * (getBufferSize().getY() - 1);
+                srcBuf += srcStride * (getBufferSize().getY() - 1);
+                nSrcY = getBufferSize().getY() - nSrcY - nSrcHeight;
+                nDestY = getBufferSize().getY() - nDestY - nSrcHeight;
+                dstStride = -dstStride;
+                srcStride = -srcStride;
+            }
+
+            char* dstline = dstBuf + dstStride * nDestY + nDestX * bytesPerPixel;
+            char* srcline = srcBuf + srcStride * nSrcY + nSrcX * bytesPerPixel;
+            int lineBytes = nSrcWidth * bytesPerPixel;
+
+            for(; 0 < nSrcHeight; nSrcHeight--)
+            {
+                memmove(dstline, srcline, lineBytes);
+                dstline += dstStride;
+                srcline += srcStride;
+            }
+        }
+
         virtual void drawBitmap_i(const BitmapDeviceSharedPtr& rSrcBitmap,
                                   const basegfx::B2IBox&       rSrcRect,
                                   const basegfx::B2IBox&       rDstRect,
@@ -723,6 +784,10 @@ namespace
                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
                                    maBegin,
                                    maRawXorAccessor);
+                else if (bitsPerPixel[getScanlineFormat()] >= 8
+                         && rSrcRect.getWidth() == rDstRect.getWidth() && rSrcRect.getHeight() == rDstRect.getHeight()
+                         && rSrcBitmap->getScanlineFormat() == getScanlineFormat())
+                    implDrawBitmapDirect(rSrcBitmap, rSrcRect, rDstRect);
                 else
                     implDrawBitmap(rSrcBitmap, rSrcRect, rDstRect,
                                    maBegin,
@@ -1867,27 +1932,7 @@ BitmapDeviceSharedPtr createBitmapDeviceImplInner( const basegfx::B2IVector&
         nScanlineFormat >  FORMAT_MAX )
         return BitmapDeviceSharedPtr();
 
-    static const sal_uInt8 bitsPerPixel[] =
-    {
-        0,  // NONE
-        1,  // ONE_BIT_MSB_GREY
-        1,  // ONE_BIT_LSB_GREY
-        1,  // ONE_BIT_MSB_PAL
-        1,  // ONE_BIT_LSB_PAL
-        4,  // FOUR_BIT_MSB_GREY
-        4,  // FOUR_BIT_LSB_GREY
-        4,  // FOUR_BIT_MSB_PAL
-        4,  // FOUR_BIT_LSB_PAL
-        8,  // EIGHT_BIT_PAL
-        8,  // EIGHT_BIT_GREY
-        16, // SIXTEEN_BIT_LSB_TC_MASK
-        16, // SIXTEEN_BIT_MSB_TC_MASK
-        24, // TWENTYFOUR_BIT_TC_MASK
-        32, // THIRTYTWO_BIT_TC_MASK_BGRA
-        32, // THIRTYTWO_BIT_TC_MASK_ARGB
-        32, // THIRTYTWO_BIT_TC_MASK_ABGR
-        32, // THIRTYTWO_BIT_TC_MASK_RGBA
-   };
+
 
     sal_Int32  nScanlineStride(0);
 


More information about the Libreoffice-commits mailing list