[Libreoffice-commits] core.git: Branch 'feature/gtkbmptiledviewer' - 3 commits - desktop/inc desktop/qa desktop/source include/vcl vcl/headless vcl/inc vcl/source

Andrzej Hunt andrzej.hunt at collabora.com
Sun May 25 08:43:29 PDT 2014


 desktop/inc/liblibreoffice.h                 |    3 +
 desktop/inc/liblibreoffice.hxx               |    6 ++-
 desktop/qa/gtktiledviewer/gtktiledviewer.cxx |   43 ++++++++++++++++++---------
 desktop/source/lib/init.cxx                  |   36 +++++++++++-----------
 include/vcl/virdev.hxx                       |   14 ++++++--
 vcl/headless/svpvd.cxx                       |   12 ++++---
 vcl/inc/headless/svpvd.hxx                   |    5 ++-
 vcl/inc/salvd.hxx                            |    8 +++--
 vcl/source/gdi/virdev.cxx                    |   24 ++++++++++-----
 9 files changed, 98 insertions(+), 53 deletions(-)

New commits:
commit e1259e8644d163bcc9a59ea421b93129be883349
Author: Andrzej Hunt <andrzej.hunt at collabora.com>
Date:   Sun May 25 16:42:17 2014 +0100

    Upgrade gtktiledviewer to use its own buffer.
    
    Change-Id: I3f567ff19ee0d5b0d54aeef9b163b78567d72946

diff --git a/desktop/qa/gtktiledviewer/gtktiledviewer.cxx b/desktop/qa/gtktiledviewer/gtktiledviewer.cxx
index 1a9ae31..6a321e1 100644
--- a/desktop/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/desktop/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -30,6 +30,7 @@ static int help()
 }
 
 static GtkWidget* ourCanvas;
+static GdkPixbuf* ourPixBuf = 0;
 
 bool drawCallback(GtkWidget* /* The eventbox */, void* /* cairo_t* cr */, gpointer pData)
 {
@@ -44,25 +45,40 @@ bool drawCallback(GtkWidget* /* The eventbox */, void* /* cairo_t* cr */, gpoint
     int nRenderWidth = nWidth / 10;
     int nRenderHeight = nHeight / 10;
     int nRowStride;
-    unsigned char* pBuffer = pDocument->paintTile( nRenderWidth, nRenderHeight,
-                                                   &nRowStride,
-                                                   0, 0, // origin
-                                                   nWidth, nHeight );
+
+    if ( ourPixBuf &&
+            (gdk_pixbuf_get_width( ourPixBuf ) != nRenderWidth ||
+             gdk_pixbuf_get_height( ourPixBuf ) != nRenderHeight ) )
+    {
+        g_object_unref( G_OBJECT( ourPixBuf ) );
+        ourPixBuf = 0;
+
+    }
+    if (!ourPixBuf)
+    {
+        ourPixBuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB,
+                                    true, 8,
+                                    nRenderWidth, nRenderHeight);
+    }
+
+    unsigned char* pBuffer = gdk_pixbuf_get_pixels( ourPixBuf );
+
+    pDocument->paintTile( pBuffer,
+                          nRenderWidth, nRenderHeight,
+                          &nRowStride,
+                          0, 0, // origin
+                          nWidth, nHeight );
+    // TODO: double check that the rowstride really matches what we expected,
+    // although presumably we'd already be crashing by now if things were
+    // wrong.
+    (void) nRowStride;
 
     for (int i = 3; i < nRowStride*nRenderHeight; i += 4)
     {
         pBuffer[i] = 0xFF;
     }
 
-    GdkPixbuf* pBixBuf = gdk_pixbuf_new_from_data( pBuffer, GDK_COLORSPACE_RGB,
-                                                   true, 8,
-                                                   nRenderWidth, nRenderHeight,
-                                                   nRowStride,
-                                                   0, 0 );
-    pBixBuf = gdk_pixbuf_flip( pBixBuf, false );
-    gtk_image_set_from_pixbuf( GTK_IMAGE(ourCanvas), pBixBuf );
-
-    // TODO: we need to keep track of and cleanup these buffers etc.
+    gtk_image_set_from_pixbuf( GTK_IMAGE( ourCanvas ), ourPixBuf );
 
     return true;
 
@@ -114,7 +130,6 @@ int main( int argc, char* argv[] )
     ourCanvas = pCanvas;
     gtk_container_add( GTK_CONTAINER( pEventBox ), pCanvas );
 
-
     g_signal_connect( G_OBJECT(pEventBox), "button-press-event", G_CALLBACK(drawCallback), pDocument);
 
     gtk_widget_show( pCanvas );
commit 9ceb425f55bdae8a434b94ee175100a6b372ba90
Author: Andrzej Hunt <andrzej.hunt at collabora.com>
Date:   Sun May 25 16:41:41 2014 +0100

    Use external buffer for LibLO tiled rendering.
    
    Means we can get rid of hackily storing a reference to the last
    buffer we created.
    
    Change-Id: I8092a7d87bc391301f75651a59b37fbd73ac64fd

diff --git a/desktop/inc/liblibreoffice.h b/desktop/inc/liblibreoffice.h
index dc001b6..fad7f72 100644
--- a/desktop/inc/liblibreoffice.h
+++ b/desktop/inc/liblibreoffice.h
@@ -67,7 +67,8 @@ struct _LibreOfficeDocument
   // for its internal buffer, i.e. the rowstride for the buffer may be larger
   // than the desired width, hence we need to be able to return the
   // rowstride too.
-  unsigned char* (*paintTile)  (LibreOfficeDocument* pThis,
+  void (*paintTile)  (LibreOfficeDocument* pThis,
+                     unsigned char* pBuffer,
                      const int nCanvasWidth,
                      const int nCanvasHeight,
                      int* pRowStride,
diff --git a/desktop/inc/liblibreoffice.hxx b/desktop/inc/liblibreoffice.hxx
index 5ad73f9..475b065 100644
--- a/desktop/inc/liblibreoffice.hxx
+++ b/desktop/inc/liblibreoffice.hxx
@@ -65,7 +65,9 @@ public:
         mpDoc->setPart(mpDoc, nPart);
     }
 
-    inline unsigned char* paintTile(const int nCanvasWidth,
+    inline void paintTile(
+                          unsigned char* pBuffer,
+                          const int nCanvasWidth,
                           const int nCanvasHeight,
                           int* pRowStride,
                           const int nTilePosX,
@@ -73,7 +75,7 @@ public:
                           const int nTileWidth,
                           const int nTileHeight)
     {
-        return mpDoc->paintTile(mpDoc, nCanvasWidth, nCanvasHeight, pRowStride,
+        return mpDoc->paintTile(mpDoc, pBuffer, nCanvasWidth, nCanvasHeight, pRowStride,
                                 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
     }
 
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 459ab8d..fcdc358 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -71,6 +71,17 @@ typedef struct
     const char *filterName;
 } ExtensionMap;
 
+// We need a shared_array for passing into the BitmapDevice (via
+// VirtualDevice.SetOutputSizePixelScaleOffsetAndBuffer which goes via the
+// SvpVirtualDevice, ending up in the basebmp BitmapDevice. However as we're
+// given the array externally we can't delete it, and hence need to override
+// shared_array's default of deleting its pointer.
+template<typename T>
+struct NoDelete
+{
+   void operator()(T* /* p */) {}
+};
+
 static const ExtensionMap aWriterExtensionMap[] =
 {
     { "doc",   "MS Word 97" },
@@ -168,7 +179,8 @@ static int  doc_saveAsWithOptions(LibreOfficeDocument* pThis, const char* pUrl,
 static LibreOfficeDocumentType doc_getDocumentType(LibreOfficeDocument* pThis);
 static int doc_getNumberOfParts(LibreOfficeDocument* pThis);
 static void doc_setPart(LibreOfficeDocument* pThis, int nPart);
-static unsigned char* doc_paintTile(LibreOfficeDocument* pThis,
+static void doc_paintTile(LibreOfficeDocument* pThis,
+                          unsigned char* pBuffer,
                           const int nCanvasWidth, const int nCanvasHeight,
                           int* pRowStride,
                           const int nTilePosX, const int nTilePosY,
@@ -369,14 +381,6 @@ static void doc_setPart(LibreOfficeDocument* pThis, int nPart)
     (void) nPart;
 }
 
-// TODO: Temporary hack -- we need to keep the buffer alive while we paint it
-// in the gtk tiled viewer -- we can't pass out the shared_array through
-// the C interface, so maybe we want some sort of wrapper where we can return
-// a handle which we then associate with a given shared_array within LibLO
-// (where the client then has to tell us when they are finished with using
-// the buffer).
-boost::shared_array< sal_uInt8 > ourBuffer;
-
 // TODO: Not 100% sure about the bitmap buffer format yet -- it appears
 // to just be RGB, 8 bits per sample, and vertically mirrored compared
 // to what gtk expects.
@@ -394,7 +398,8 @@ boost::shared_array< sal_uInt8 > ourBuffer;
 // We probably also want to use getScanlineStride() -- I'm guessing that
 // this is where we are actually just returning a sub-portion of a larger buffer
 // which /shouldn't/ apply in our case, but better to be safe here.
-static unsigned char* doc_paintTile (LibreOfficeDocument* pThis,
+static void doc_paintTile (LibreOfficeDocument* pThis,
+                           unsigned char* pBuffer,
                            const int nCanvasWidth, const int nCanvasHeight,
                            int* pRowStride,
                            const int nTilePosX, const int nTilePosY,
@@ -402,8 +407,6 @@ static unsigned char* doc_paintTile (LibreOfficeDocument* pThis,
 {
     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
 
-    unsigned char* pRet = 0;
-
     Application::AcquireSolarMutex(1);
     {
         SwXTextDocument* pTxtDoc = dynamic_cast< SwXTextDocument* >( pDocument->mxComponent.get() );
@@ -416,6 +419,10 @@ static unsigned char* doc_paintTile (LibreOfficeDocument* pThis,
         pSalInstance->setBitCountFormatMapping( 32, ::basebmp::FORMAT_THIRTYTWO_BIT_TC_MASK_RGBA );
 
         VirtualDevice aDevice(0, (sal_uInt16)32);
+        boost::shared_array< sal_uInt8 > aBuffer( pBuffer, NoDelete< sal_uInt8 >() );
+        aDevice.SetOutputSizePixelScaleOffsetAndBuffer(
+                    Size(nCanvasWidth, nCanvasHeight), Fraction(1.0), Point(),
+                    aBuffer, true );
 
         pViewShell->PaintTile(aDevice, nCanvasWidth, nCanvasHeight,
                                 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
@@ -424,13 +431,8 @@ static unsigned char* doc_paintTile (LibreOfficeDocument* pThis,
         basebmp::BitmapDeviceSharedPtr pBmpDev = pSalDev->getBitmapDevice();
 
         *pRowStride = pBmpDev->getScanlineStride();
-        ourBuffer = pBmpDev->getBuffer();
-
-        pRet = ourBuffer.get();
     }
     Application::ReleaseSolarMutex();
-
-    return pRet;
 }
 
 static void doc_getDocumentSize(LibreOfficeDocument* pThis,
commit 975b8a38f0f05d73477b22291db61fe2b4f9e764
Author: Andrzej Hunt <andrzej.hunt at collabora.com>
Date:   Sun May 25 16:40:47 2014 +0100

    Allow passing in external buffers to svp's VirtualDevice.
    
    We also want to be able to set whether or not the buffers
    should be painted to top down, so add that parameter
    as necessary (default seems to be false, however e.g. gtk
    requires this to be true, i.e. needed for tiled rendering).
    
    Change-Id: Id98882e4c7f62508ae5a976c0d8df743460a4ab2

diff --git a/include/vcl/virdev.hxx b/include/vcl/virdev.hxx
index 74a6174..8c36f52 100644
--- a/include/vcl/virdev.hxx
+++ b/include/vcl/virdev.hxx
@@ -43,8 +43,12 @@ private:
     sal_uInt8           meRefDevMode;
 
     SAL_DLLPRIVATE void ImplInitVirDev( const OutputDevice* pOutDev, long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData = NULL );
-    SAL_DLLPRIVATE bool InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase, const basebmp::RawMemorySharedArray &pBuffer );
-    SAL_DLLPRIVATE bool ImplSetOutputSizePixel( const Size& rNewSize, bool bErase, const basebmp::RawMemorySharedArray &pBuffer );
+    SAL_DLLPRIVATE bool InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase,
+                                                     const basebmp::RawMemorySharedArray &pBuffer,
+                                                     const bool bTopDown );
+    SAL_DLLPRIVATE bool ImplSetOutputSizePixel( const Size& rNewSize, bool bErase,
+                                                const basebmp::RawMemorySharedArray &pBuffer,
+                                                const bool bTopDown );
 
     // Copy assignment is forbidden and not implemented.
     VirtualDevice (const VirtualDevice &);
@@ -119,7 +123,11 @@ public:
     virtual void        EnableRTL( bool bEnable = true ) SAL_OVERRIDE;
 
     bool                SetOutputSizePixel( const Size& rNewSize, bool bErase = true );
-    bool                SetOutputSizePixelScaleOffsetAndBuffer( const Size& rNewSize, const Fraction& rScale, const Point& rNewOffset, const basebmp::RawMemorySharedArray &pBuffer );
+    bool                SetOutputSizePixelScaleOffsetAndBuffer( const Size& rNewSize,
+                                                                const Fraction& rScale,
+                                                                const Point& rNewOffset,
+                                                                const basebmp::RawMemorySharedArray &pBuffer,
+                                                                const bool bTopDown = false );
     bool                SetOutputSize( const Size& rNewSize, bool bErase = true )
                             { return SetOutputSizePixel( LogicToPixel( rNewSize ), bErase ); }
 
diff --git a/vcl/headless/svpvd.cxx b/vcl/headless/svpvd.cxx
index d85cd8c..dc280db 100644
--- a/vcl/headless/svpvd.cxx
+++ b/vcl/headless/svpvd.cxx
@@ -52,10 +52,12 @@ void SvpSalVirtualDevice::ReleaseGraphics( SalGraphics* pGraphics )
 
 bool SvpSalVirtualDevice::SetSize( long nNewDX, long nNewDY )
 {
-    return SetSizeUsingBuffer( nNewDX, nNewDY, basebmp::RawMemorySharedArray() );
+    return SetSizeUsingBuffer( nNewDX, nNewDY, basebmp::RawMemorySharedArray(), false );
 }
 
-bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, const basebmp::RawMemorySharedArray &pBuffer )
+bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY,
+                                              const basebmp::RawMemorySharedArray &pBuffer,
+                                              const bool bTopDown )
 {
     B2IVector aDevSize( nNewDX, nNewDY );
     if( aDevSize.getX() == 0 )
@@ -73,13 +75,13 @@ bool SvpSalVirtualDevice::SetSizeUsingBuffer( long nNewDX, long nNewDY, const ba
             std::vector< basebmp::Color > aDevPal(2);
             aDevPal.push_back( basebmp::Color( 0, 0, 0 ) );
             aDevPal.push_back( basebmp::Color( 0xff, 0xff, 0xff ) );
-            m_aDevice = createBitmapDevice( aDevSize, false, nFormat, PaletteMemorySharedVector( new std::vector< basebmp::Color >(aDevPal) ) );
+            m_aDevice = createBitmapDevice( aDevSize, bTopDown, nFormat, PaletteMemorySharedVector( new std::vector< basebmp::Color >(aDevPal) ) );
         }
         else
         {
             m_aDevice = pBuffer ?
-                          createBitmapDevice( aDevSize, false, nFormat, pBuffer, PaletteMemorySharedVector() )
-                        : createBitmapDevice( aDevSize, false, nFormat );
+                          createBitmapDevice( aDevSize, bTopDown, nFormat, pBuffer, PaletteMemorySharedVector() )
+                        : createBitmapDevice( aDevSize, bTopDown, nFormat );
         }
 
         // update device in existing graphics
diff --git a/vcl/inc/headless/svpvd.hxx b/vcl/inc/headless/svpvd.hxx
index e4d37fc..f6a9cc5 100644
--- a/vcl/inc/headless/svpvd.hxx
+++ b/vcl/inc/headless/svpvd.hxx
@@ -45,7 +45,10 @@ public:
     virtual void            ReleaseGraphics( SalGraphics* pGraphics ) SAL_OVERRIDE;
 
     virtual bool        SetSize( long nNewDX, long nNewDY ) SAL_OVERRIDE;
-    virtual bool        SetSizeUsingBuffer( long nNewDX, long nNewDY, const basebmp::RawMemorySharedArray &pBuffer ) SAL_OVERRIDE;
+    virtual bool        SetSizeUsingBuffer( long nNewDX, long nNewDY,
+                                            const basebmp::RawMemorySharedArray &pBuffer,
+                                            const bool bTopDown
+                                          ) SAL_OVERRIDE;
     virtual void            GetSize( long& rWidth, long& rHeight ) SAL_OVERRIDE;
 
     basebmp::BitmapDeviceSharedPtr getBitmapDevice() { return m_aDevice; }
diff --git a/vcl/inc/salvd.hxx b/vcl/inc/salvd.hxx
index 842429f..0cac639 100644
--- a/vcl/inc/salvd.hxx
+++ b/vcl/inc/salvd.hxx
@@ -40,9 +40,13 @@ public:
     virtual bool        SetSize( long nNewDX, long nNewDY ) = 0;
 
     // Set new size using a buffer at the given address
-    virtual bool        SetSizeUsingBuffer( long nNewDX, long nNewDY, const basebmp::RawMemorySharedArray & /* pBuffer */ )
+    virtual bool        SetSizeUsingBuffer( long nNewDX, long nNewDY,
+                                            const basebmp::RawMemorySharedArray & /* pBuffer */,
+                                            const bool /* bTopDown */
+                                          )
         {
-            // Only the headless virtual device has an implementation that uses pBuffer.
+            // Only the headless virtual device has an implementation that uses
+            // pBuffer (and bTopDown).
             return SetSize( nNewDX, nNewDY );
         }
 
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
index 6378785..54cd376 100644
--- a/vcl/source/gdi/virdev.cxx
+++ b/vcl/source/gdi/virdev.cxx
@@ -267,7 +267,9 @@ VirtualDevice::~VirtualDevice()
         pSVData->maGDIData.mpLastVirDev = mpPrev;
 }
 
-bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase, const basebmp::RawMemorySharedArray &pBuffer )
+bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase,
+                                                 const basebmp::RawMemorySharedArray &pBuffer,
+                                                 const bool bTopDown )
 {
     SAL_INFO( "vcl.gdi",
               "VirtualDevice::InnerImplSetOutputSizePixel( " << rNewSize.Width() << ", "
@@ -296,7 +298,7 @@ bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bEra
     if ( bErase )
     {
         if ( pBuffer )
-            bRet = mpVirDev->SetSizeUsingBuffer( nNewWidth, nNewHeight, pBuffer );
+            bRet = mpVirDev->SetSizeUsingBuffer( nNewWidth, nNewHeight, pBuffer, bTopDown );
         else
             bRet = mpVirDev->SetSize( nNewWidth, nNewHeight );
 
@@ -381,9 +383,11 @@ void VirtualDevice::ImplFillOpaqueRectangle( const Rectangle& rRect )
     Pop();
 }
 
-bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, bool bErase, const basebmp::RawMemorySharedArray &pBuffer )
+bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, bool bErase,
+                                            const basebmp::RawMemorySharedArray &pBuffer,
+                                            const bool bTopDown )
 {
-    if( InnerImplSetOutputSizePixel(rNewSize, bErase, pBuffer) )
+    if( InnerImplSetOutputSizePixel(rNewSize, bErase, pBuffer, bTopDown) )
     {
         if( mnAlphaDepth != -1 )
         {
@@ -397,7 +401,9 @@ bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, bool bErase, c
             if( !mpAlphaVDev )
             {
                 mpAlphaVDev = new VirtualDevice( *this, mnAlphaDepth );
-                mpAlphaVDev->InnerImplSetOutputSizePixel(rNewSize, bErase, basebmp::RawMemorySharedArray() );
+                mpAlphaVDev->InnerImplSetOutputSizePixel(rNewSize, bErase,
+                                                         basebmp::RawMemorySharedArray(),
+                                                         bTopDown );
             }
 
             // TODO: copy full outdev state to new one, here. Also needed in outdev2.cxx:DrawOutDev
@@ -430,10 +436,12 @@ void VirtualDevice::EnableRTL( bool bEnable )
 
 bool VirtualDevice::SetOutputSizePixel( const Size& rNewSize, bool bErase )
 {
-    return ImplSetOutputSizePixel( rNewSize, bErase, basebmp::RawMemorySharedArray() );
+    return ImplSetOutputSizePixel( rNewSize, bErase, basebmp::RawMemorySharedArray(), false );
 }
 
-bool VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer( const Size& rNewSize, const Fraction& rScale, const Point& rNewOffset, const basebmp::RawMemorySharedArray &pBuffer )
+bool VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer(
+    const Size& rNewSize, const Fraction& rScale, const Point& rNewOffset,
+    const basebmp::RawMemorySharedArray &pBuffer, const bool bTopDown )
 {
     if (pBuffer) {
         MapMode mm = GetMapMode();
@@ -442,7 +450,7 @@ bool VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer( const Size& rNewSize
         mm.SetScaleY( rScale );
         SetMapMode( mm );
     }
-    return ImplSetOutputSizePixel( rNewSize, true, pBuffer);
+    return ImplSetOutputSizePixel( rNewSize, true, pBuffer, bTopDown );
 }
 
 void VirtualDevice::SetReferenceDevice( RefDevMode i_eRefDevMode )


More information about the Libreoffice-commits mailing list