diff options
author | Radek Doulik <rodo@novell.com> | 2013-03-14 09:36:43 +0100 |
---|---|---|
committer | Radek Doulik <rodo@novell.com> | 2013-03-14 09:39:52 +0100 |
commit | c6c0e73e0fda18b7bb37685ab8f8630e15bb427a (patch) | |
tree | c8b127497b6d83a2deec7d6688296fdb2f979abd | |
parent | 35e2749cb534fdbe355166ec656beb72248cb096 (diff) |
pass argb32 pixmaps from vcl to canvas, avoiding costly x11 roundtrips
- fixes also problem with emf+ rendering for slideshow
Change-Id: Icb894d3f37b29f23d3f267c944d827eefbf47fda
-rw-r--r-- | canvas/source/cairo/cairo_canvasbitmap.cxx | 30 | ||||
-rw-r--r-- | canvas/source/cairo/cairo_canvasbitmap.hxx | 4 | ||||
-rw-r--r-- | canvas/source/cairo/cairo_xlib_cairo.cxx | 7 | ||||
-rw-r--r-- | canvas/source/cairo/cairo_xlib_cairo.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/unx/salbmp.h | 4 | ||||
-rw-r--r-- | vcl/inc/vcl/bitmap.hxx | 3 | ||||
-rw-r--r-- | vcl/source/gdi/bitmap.cxx | 13 | ||||
-rw-r--r-- | vcl/source/helper/canvastools.cxx | 25 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salbmp.cxx | 16 | ||||
-rw-r--r-- | vcl/unx/generic/gdi/salgdi2.cxx | 8 |
10 files changed, 97 insertions, 14 deletions
diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx index 1d6255461b8c..949a9caa3e4a 100644 --- a/canvas/source/cairo/cairo_canvasbitmap.cxx +++ b/canvas/source/cairo/cairo_canvasbitmap.cxx @@ -143,6 +143,30 @@ namespace cairocanvas return maCanvasHelper.repaint( pSurface, viewState, renderState ); } + void SAL_CALL CanvasBitmap::setFastPropertyValue( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rAny ) throw (uno::RuntimeException) + { + sal_Int64 nPointer; + + if ( nHandle == 0 ) + { + rAny >>= nPointer; + + if ( nPointer ) + { + ::Bitmap *pBitmap = reinterpret_cast< ::Bitmap* >( nPointer ); + + mpBufferSurface = createSurface( *pBitmap ); + mpBufferCairo = mpBufferSurface->getCairo(); + + ::Size aSize( pBitmap->GetSizePixel() ); + maSize = ::basegfx::B2ISize( aSize.getWidth(), aSize.getHeight() ); + + maCanvasHelper.setSize( maSize ); + maCanvasHelper.setSurface( mpBufferSurface, mbHasAlpha ); + } + } + } + uno::Any SAL_CALL CanvasBitmap::getFastPropertyValue( sal_Int32 nHandle ) throw (uno::RuntimeException) { uno::Any aRV( sal_Int32(0) ); @@ -161,10 +185,11 @@ namespace cairocanvas #ifdef CAIRO_HAS_XLIB_SURFACE X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(mpBufferSurface.get()); OSL_ASSERT(pXlibSurface); - uno::Sequence< uno::Any > args( 3 ); + uno::Sequence< uno::Any > args( 4 ); args[0] = uno::Any( false ); // do not call XFreePixmap on it args[1] = uno::Any( pXlibSurface->getPixmap()->mhDrawable ); args[2] = uno::Any( sal_Int32( pXlibSurface->getDepth() ) ); + args[3] = uno::Any( sal_Int64( pXlibSurface->getVisual () ) ); aRV = uno::Any( args ); #elif defined CAIRO_HAS_QUARTZ_SURFACE @@ -189,7 +214,7 @@ namespace cairocanvas case 2: { #ifdef CAIRO_HAS_XLIB_SURFACE - uno::Sequence< uno::Any > args( 3 ); + uno::Sequence< uno::Any > args( 4 ); SurfaceSharedPtr pAlphaSurface = mpSurfaceProvider->createSurface( maSize, CAIRO_CONTENT_COLOR ); CairoSharedPtr pAlphaCairo = pAlphaSurface->getCairo(); X11Surface* pXlibSurface=dynamic_cast<X11Surface*>(pAlphaSurface.get()); @@ -208,6 +233,7 @@ namespace cairocanvas args[0] = uno::Any( true ); args[1] = ::com::sun::star::uno::Any( pPixmap->mhDrawable ); args[2] = ::com::sun::star::uno::Any( sal_Int32( pXlibSurface->getDepth () ) ); + args[3] = ::com::sun::star::uno::Any( sal_Int64( pXlibSurface->getVisual () ) ); pPixmap->clear(); // caller takes ownership of pixmap // return pixmap and alphachannel pixmap - it will be used in BitmapEx diff --git a/canvas/source/cairo/cairo_canvasbitmap.hxx b/canvas/source/cairo/cairo_canvasbitmap.hxx index 1626c9240ff6..523228cb9c59 100644 --- a/canvas/source/cairo/cairo_canvasbitmap.hxx +++ b/canvas/source/cairo/cairo_canvasbitmap.hxx @@ -124,14 +124,14 @@ namespace cairocanvas // 2nd the pixmap handle // 3rd the pixmap depth virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) throw (::com::sun::star::uno::RuntimeException); - virtual void SAL_CALL setFastPropertyValue(sal_Int32, const ::com::sun::star::uno::Any&) throw (::com::sun::star::uno::RuntimeException) {} + virtual void SAL_CALL setFastPropertyValue(sal_Int32, const ::com::sun::star::uno::Any&) throw (::com::sun::star::uno::RuntimeException); private: SurfaceProviderRef mpSurfaceProvider; ::cairo::SurfaceSharedPtr mpBufferSurface; ::cairo::CairoSharedPtr mpBufferCairo; - const ::basegfx::B2ISize maSize; + ::basegfx::B2ISize maSize; const bool mbHasAlpha; }; } diff --git a/canvas/source/cairo/cairo_xlib_cairo.cxx b/canvas/source/cairo/cairo_xlib_cairo.cxx index 0259154c043e..c75bc967d40b 100644 --- a/canvas/source/cairo/cairo_xlib_cairo.cxx +++ b/canvas/source/cairo/cairo_xlib_cairo.cxx @@ -196,7 +196,7 @@ namespace cairo mpSurface( cairo_xlib_surface_create( (Display*)rSysData.pDisplay, (Drawable)rData.aPixmap, - (Visual*) rSysData.pVisual, + (Visual*) (rData.aVisual ? rData.aVisual : rSysData.pVisual), rData.mnWidth, rData.mnHeight ), &cairo_surface_destroy) { @@ -321,6 +321,11 @@ namespace cairo return -1; } + void* X11Surface::getVisual() const + { + return cairo_xlib_surface_get_visual( mpSurface.get() ); + } + SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface ) { return SurfaceSharedPtr(new X11Surface(rSurface)); diff --git a/canvas/source/cairo/cairo_xlib_cairo.hxx b/canvas/source/cairo/cairo_xlib_cairo.hxx index 92ca044a72ff..2736ed45d9e2 100644 --- a/canvas/source/cairo/cairo_xlib_cairo.hxx +++ b/canvas/source/cairo/cairo_xlib_cairo.hxx @@ -101,6 +101,7 @@ namespace cairo { X11PixmapSharedPtr getPixmap() const { return mpPixmap; } void* getRenderFormat() const { return maSysData.pRenderFormat; } long getDrawable() const { return mpPixmap ? mpPixmap->mhDrawable : maSysData.hDrawable; } + void* getVisual() const; }; } diff --git a/vcl/inc/unx/salbmp.h b/vcl/inc/unx/salbmp.h index d9ce1920af86..e97b9b97dc90 100644 --- a/vcl/inc/unx/salbmp.h +++ b/vcl/inc/unx/salbmp.h @@ -89,6 +89,7 @@ public: SAL_DLLPRIVATE bool ImplCreateFromDrawable( Drawable aDrawable, + void* pVisual, SalX11Screen nXScreen, long nDrawableDepth, long nX, @@ -171,6 +172,7 @@ class ImplSalDDB private: Pixmap maPixmap; + void* mpVisual; SalTwoRect maTwoRect; long mnDepth; SalX11Screen mnXScreen; @@ -202,6 +204,7 @@ public: ImplSalDDB( Drawable aDrawable, + void *pVisual, SalX11Screen nXScreen, long nDrawableDepth, long nX, @@ -213,6 +216,7 @@ public: ~ImplSalDDB(); Pixmap ImplGetPixmap() const { return maPixmap; } + void* ImplGetVisual() const { return mpVisual; } long ImplGetWidth() const { return maTwoRect.mnDestWidth; } long ImplGetHeight() const { return maTwoRect.mnDestHeight; } long ImplGetDepth() const { return mnDepth; } diff --git a/vcl/inc/vcl/bitmap.hxx b/vcl/inc/vcl/bitmap.hxx index efc37a01c9f1..d162daab6a85 100644 --- a/vcl/inc/vcl/bitmap.hxx +++ b/vcl/inc/vcl/bitmap.hxx @@ -330,6 +330,7 @@ struct BitmapSystemData void* rImageContext; //Image context (CGContextRef) #else void* aPixmap; + void* aVisual; #endif int mnWidth; int mnHeight; @@ -847,6 +848,8 @@ public: const BmpFilterParam* pFilterParam = NULL, const Link* pProgress = NULL ); + bool HasAlpha(); + public: BitmapReadAccess* AcquireReadAccess(); BitmapWriteAccess* AcquireWriteAccess(); diff --git a/vcl/source/gdi/bitmap.cxx b/vcl/source/gdi/bitmap.cxx index 3d298b7a68d5..dc279cf26879 100644 --- a/vcl/source/gdi/bitmap.cxx +++ b/vcl/source/gdi/bitmap.cxx @@ -1910,4 +1910,17 @@ bool Bitmap::GetSystemData( BitmapSystemData& rData ) const return bRet; } +bool Bitmap::HasAlpha() +{ + bool bRet = false; + if( mpImpBmp ) + { + SalBitmap* pSalBitmap = mpImpBmp->ImplGetSalBitmap(); + if( pSalBitmap ) + bRet = pSalBitmap->HasAlpha(); + } + + return bRet; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx index b8dce8d6ecb4..a0a69375a1e3 100644 --- a/vcl/source/helper/canvastools.cxx +++ b/vcl/source/helper/canvastools.cxx @@ -30,6 +30,8 @@ #include <rtl/logfile.hxx> #include <cppuhelper/compbase1.hxx> +#include <com/sun/star/beans/XFastPropertySet.hpp> + #include <com/sun/star/geometry/RealSize2D.hpp> #include <com/sun/star/geometry/RealPoint2D.hpp> #include <com/sun/star/geometry/RealRectangle2D.hpp> @@ -79,11 +81,32 @@ namespace vcl { namespace unotools { - uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, + uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice, const ::BitmapEx& inputBitmap ) { RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xBitmapFromBitmapEx()" ); + if ( inputBitmap.GetBitmap().HasAlpha() ) + { + geometry::IntegerSize2D aSize; + + aSize.Width = aSize.Height = 1; + + uno::Reference< rendering::XBitmap > xBitmap = xGraphicDevice->createCompatibleAlphaBitmap( aSize ); + + uno::Reference< beans::XFastPropertySet > rPropSet( xBitmap, uno::UNO_QUERY ); + if ( rPropSet.is() ) + { + Bitmap aBitmap = inputBitmap.GetBitmap(); + rPropSet->setFastPropertyValue( 0, uno::Any( sal_Int64( &aBitmap ))); + + aSize = xBitmap->getSize(); + + if ( aSize.Width != 1 || aSize.Height != 1 ) + return xBitmap; + } + } + return new vcl::unotools::VclCanvasBitmap( inputBitmap ); } diff --git a/vcl/unx/generic/gdi/salbmp.cxx b/vcl/unx/generic/gdi/salbmp.cxx index 790245848752..9528ee292c64 100644 --- a/vcl/unx/generic/gdi/salbmp.cxx +++ b/vcl/unx/generic/gdi/salbmp.cxx @@ -576,6 +576,7 @@ XImage* X11SalBitmap::ImplCreateXImage( // ----------------------------------------------------------------------------- bool X11SalBitmap::ImplCreateFromDrawable( Drawable aDrawable, + void *pVisual, SalX11Screen nScreen, long nDrawableDepth, long nX, @@ -586,7 +587,7 @@ bool X11SalBitmap::ImplCreateFromDrawable( Destroy(); if( aDrawable && nWidth && nHeight && nDrawableDepth ) - mpDDB = new ImplSalDDB( aDrawable, nScreen, nDrawableDepth, nX, nY, nWidth, nHeight ); + mpDDB = new ImplSalDDB( aDrawable, pVisual, nScreen, nDrawableDepth, nX, nY, nWidth, nHeight ); return( mpDDB != NULL ); } @@ -746,7 +747,8 @@ bool X11SalBitmap::Create( const SalBitmap& rSSalBmp ) } else if( rSalBmp.mpDDB ) ImplCreateFromDrawable( rSalBmp.mpDDB->ImplGetPixmap(), - rSalBmp.mpDDB->ImplGetScreen(), + rSalBmp.mpDDB->ImplGetVisual(), + rSalBmp.mpDDB->ImplGetScreen(), rSalBmp.mpDDB->ImplGetDepth(), 0, 0, rSalBmp.mpDDB->ImplGetWidth(), rSalBmp.mpDDB->ImplGetHeight() ); @@ -785,11 +787,13 @@ bool X11SalBitmap::Create( if( xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args ) { long pixmapHandle; - if( ( args[1] >>= pixmapHandle ) && ( args[2] >>= depth ) ) { + sal_Int64 nVisualPtr; + if( args.getLength() >= 4 && ( args[1] >>= pixmapHandle ) && ( args[2] >>= depth ) && ( args[3] >>= nVisualPtr ) ) { mbGrey = bMask; bool bSuccess = ImplCreateFromDrawable( pixmapHandle, + reinterpret_cast<void*>(nVisualPtr), // FIXME: this seems multi-screen broken to me SalX11Screen( 0 ), depth, @@ -901,6 +905,7 @@ bool X11SalBitmap::GetSystemData( BitmapSystemData& rData ) // prolly not a good idea, since it's accessed from // non-platform aware code in vcl/bitmap.hxx) rData.aPixmap = (void*)mpDDB->ImplGetPixmap(); + rData.aVisual = mpDDB->ImplGetVisual (); rData.mnWidth = mpDDB->ImplGetWidth (); rData.mnHeight = mpDDB->ImplGetHeight (); return true; @@ -916,6 +921,7 @@ bool X11SalBitmap::GetSystemData( BitmapSystemData& rData ) ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable, SalX11Screen nXScreen, const SalTwoRect& rTwoRect ) : maPixmap ( 0 ) + , mpVisual ( NULL ) , maTwoRect ( rTwoRect ) , mnDepth ( pImage->depth ) , mnXScreen ( nXScreen ) @@ -947,13 +953,15 @@ ImplSalDDB::ImplSalDDB( XImage* pImage, Drawable aDrawable, ImplSalDDB::ImplSalDDB( Drawable aDrawable, + void *pVisual, SalX11Screen nXScreen, long nDrawableDepth, long nX, long nY, long nWidth, long nHeight -) : mnDepth( nDrawableDepth ) +) : mpVisual ( pVisual ) + , mnDepth( nDrawableDepth ) , mnXScreen( nXScreen ) { SalDisplay* pSalDisp = GetGenericData()->GetSalDisplay(); diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index 3a2f63fae020..7ae904abeb5b 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -99,7 +99,7 @@ void X11SalGraphics::CopyScreenArea( Display* pDisplay, else { X11SalBitmap aBM; - aBM.ImplCreateFromDrawable( aSrc, nXScreenSrc, nSrcDepth, src_x, src_y, w, h ); + aBM.ImplCreateFromDrawable( aSrc, NULL, nXScreenSrc, nSrcDepth, src_x, src_y, w, h ); SalTwoRect aTwoRect; aTwoRect.mnSrcX = aTwoRect.mnSrcY = 0; aTwoRect.mnSrcWidth = aTwoRect.mnDestWidth = w; @@ -808,8 +808,8 @@ bool X11SalGraphics::drawAlphaBitmapOpt( const SalTwoRect& rTR, const SalVisual& rSalVis = pSalDisp->GetVisual( m_nXScreen ); Display* pXDisplay = pSalDisp->GetDisplay(); - Picture aAlphaPic; - Pixmap aAlphaPM; + Picture aAlphaPic = 0; + Pixmap aAlphaPM = 0; // create source Picture int nDepth = m_pVDev ? m_pVDev->GetDepth() : rSalVis.GetDepth(); const X11SalBitmap& rSrcX11Bmp = static_cast<const X11SalBitmap&>( rSrcBitmap ); @@ -1061,7 +1061,7 @@ SalBitmap *X11SalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) nBitCount = 1; if( ! bFakeWindowBG ) - pSalBitmap->ImplCreateFromDrawable( GetDrawable(), m_nXScreen, nBitCount, nX, nY, nDX, nDY ); + pSalBitmap->ImplCreateFromDrawable( GetDrawable(), NULL, m_nXScreen, nBitCount, nX, nY, nDX, nDY ); else pSalBitmap->Create( Size( nDX, nDY ), (nBitCount > 8) ? 24 : nBitCount, BitmapPalette( nBitCount > 8 ? nBitCount : 0 ) ); |