summaryrefslogtreecommitdiffstats
path: root/opensuse/core/qt3/0005-qpixmap_mitshm.patch
diff options
context:
space:
mode:
Diffstat (limited to 'opensuse/core/qt3/0005-qpixmap_mitshm.patch')
-rw-r--r--opensuse/core/qt3/0005-qpixmap_mitshm.patch569
1 files changed, 0 insertions, 569 deletions
diff --git a/opensuse/core/qt3/0005-qpixmap_mitshm.patch b/opensuse/core/qt3/0005-qpixmap_mitshm.patch
deleted file mode 100644
index e6683f726..000000000
--- a/opensuse/core/qt3/0005-qpixmap_mitshm.patch
+++ /dev/null
@@ -1,569 +0,0 @@
-qt-bugs@ issue : 11790 (part of)
-applied: no
-author: Lubos Lunak <l.lunak@kde.org>
-
-NOTE: Needs #define QT_MITSHM in the matching qplatformdefs.h file. This
- patch does so only for linux-g++ and linux-g++-distcc platforms.
-
-MITSHM extension support for QPixmap<->QImage conversions.
-
-Hello,
-
- the review and apply the attached patches that improve performance of
-QImage->QPixmap conversions. They should be applied in order
-'mitshm','more_local' and 'fast', but they're independent from each other
-(well, besides merging problems).
-
- Mitshm patch adds MITSHM extension support for both
-QPixmap::convertFromImage() and QPixmap::convertToImage(). I've noticed there
-was some MITSHM support already, turned off by default, but it was used only
-for QPixmap::xForm() , and it used shared pixmaps (and I'd bet nobody uses
-it). My patch adds shared ximages support for faster pixmap<->image
-conversions. Since I don't understand the xForm() code much, and I didn't
-want to do anything with it, I added three #define's:
- - QT_MITSHM generally enabling MITSHM support, which should be set in
-qplatformsdefs.h (or wherever you setup platform specific stuff), it can be
-enabled at least on Linux
- - QT_MITSHM_CONVERSIONS - this is for my new code
- - QT_MITSHM_XFORM - this is for the xForm() code
- There's one more #define, QT_MITSHM_RMID_IGNORES_REFCOUNT. Glibc
-documentation of shmctl( ... IPC_RMID ) quite clearly says that the memory
-segment is freed only after the refcount increased by shmat() and decreased
-by shmdt() is 0. However, at least according to
-http://bugs.kde.org/show_bug.cgi?id=27517 , this doesn't happen on other
-platforms for some strange reason. Such platforms should have this #define if
-you ever consider supporting MITSHM on them.
-
- The lower limit for using MITSHM for the image is about 8KiB
-(width*height*depth > 100*100*32 ). Also, BestOptim in such case doesn't keep
-the ximage, as the shared ximage is always freed before the function returns
-(I don't know if it's worth copying it).
-
- The second patch ('more_local'), in short, does nothing. Besides improving
-performance by about 10% by making variables more "local", making few of them
-const, and also making some of them unsigned (this help gcc for some reason).
-
- The last one, 'fast', moves some if's out of the loops, and handles some most
-common case specially (15bpp, 16bpp and 32bpp ximage depths). 32bpp case, if
-the endianess matches, is simply uses memcpy(), for the 15/16bpp depth,
-variables are replaced directly by matching values, statements are a bit
-reordered and merged when suitable, and again, in case endianess matches,
-pixels are written simply as Q_INT16. Most probably it would also help to
-process two pixels at once and write them as Q_INT32, but I didn't want to
-complicate the code too much (later >;) ).
-
- The last snippet of 'fast' handles case when xi->bytes_per_line is not equal
-to width for 8bpp ximage. I'm not actually sure if that can ever happen, but
-since I've already written it *shrug*.
-
- The 'more_local' and 'fast' patches change only convertFromImage(), as I
-don't think convertToImage() is that performance critical (but it's as
-unoptimized as convertFromImage() was).
-
- Maybe some numbers. The difference is of course mainly visible with larger
-pixmaps. The two optimizations alone reduce the time to 50% for 32bpp, to 70%
-for 16bpp. The MITSHM support, when other patches are already applied too,
-for 32bpp images saves about 33%. Together, the total time is reduced to
-about 40% for 32bpp. Imlib probably still beats that, but at least this
-obsoletes KPixmapIO.
-
-
---- src/kernel/qpixmap_x11.cpp
-+++ src/kernel/qpixmap_x11.cpp
-@@ -37,7 +37,19 @@
-
- // NOT REVISED
-
-+#include "qplatformdefs.h"
-+
-+#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
-+#undef QT_MITSHM
-+#endif
-+
-+#ifdef QT_MITSHM
-+
-+// Use the MIT Shared Memory extension for pixmap<->image conversions
-+#define QT_MITSHM_CONVERSIONS
-+
- // Uncomment the next line to enable the MIT Shared Memory extension
-+// for QPixmap::xForm()
- //
- // WARNING: This has some problems:
- //
-@@ -45,14 +57,13 @@
- // 2. Qt does not handle the ShmCompletion message, so you will
- // get strange effects if you xForm() repeatedly.
- //
--// #define QT_MITSHM
-+// #define QT_MITSHM_XFORM
-
--#if defined(Q_OS_WIN32) && defined(QT_MITSHM)
--#undef QT_MITSHM
-+#else
-+#undef QT_MITSHM_CONVERSIONS
-+#undef QT_MITSHM_XFORM
- #endif
-
--#include "qplatformdefs.h"
--
- #include "qbitmap.h"
- #include "qpaintdevicemetrics.h"
- #include "qimage.h"
-@@ -91,7 +102,7 @@ inline static void qSafeXDestroyImage( X
- MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
- *****************************************************************************/
-
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
-
- static bool xshminit = FALSE;
- static XShmSegmentInfo xshminfo;
-@@ -173,8 +184,100 @@ static bool qt_create_mitshm_buffer( con
- // return FALSE;
- // }
-
--#endif // QT_MITSHM
-+#endif // QT_MITSHM_XFORM
-+
-+#ifdef QT_MITSHM_CONVERSIONS
-+
-+static bool qt_mitshm_error = false;
-+static int qt_mitshm_errorhandler( Display*, XErrorEvent* )
-+{
-+ qt_mitshm_error = true;
-+ return 0;
-+}
-+
-+static XImage* qt_XShmCreateImage( Display* dpy, Visual* visual, unsigned int depth,
-+ int format, int /*offset*/, char* /*data*/, unsigned int width, unsigned int height,
-+ int /*bitmap_pad*/, int /*bytes_per_line*/, XShmSegmentInfo* shminfo )
-+{
-+ if( width * height * depth < 100*100*32 )
-+ return NULL;
-+ static int shm_inited = -1;
-+ if( shm_inited == -1 ) {
-+ if( XShmQueryExtension( dpy ))
-+ shm_inited = 1;
-+ else
-+ shm_inited = 0;
-+ }
-+ if( shm_inited == 0 )
-+ return NULL;
-+ XImage* xi = XShmCreateImage( dpy, visual, depth, format, NULL, shminfo, width,
-+ height );
-+ if( xi == NULL )
-+ return NULL;
-+ shminfo->shmid = shmget( IPC_PRIVATE, xi->bytes_per_line * xi->height,
-+ IPC_CREAT|0600);
-+ if( shminfo->shmid < 0 ) {
-+ XDestroyImage( xi );
-+ return NULL;
-+ }
-+ shminfo->readOnly = False;
-+ shminfo->shmaddr = (char*)shmat( shminfo->shmid, 0, 0 );
-+ if( shminfo->shmaddr == (char*)-1 ) {
-+ XDestroyImage( xi );
-+ shmctl( shminfo->shmid, IPC_RMID, 0 );
-+ return NULL;
-+ }
-+ xi->data = shminfo->shmaddr;
-+#ifndef QT_MITSHM_RMID_IGNORES_REFCOUNT
-+ // mark as deleted to automatically free the memory in case
-+ // of a crash (but this doesn't work e.g. on Solaris)
-+ shmctl( shminfo->shmid, IPC_RMID, 0 );
-+#endif
-+ if( shm_inited == 1 ) { // first time
-+ XErrorHandler old_h = XSetErrorHandler( qt_mitshm_errorhandler );
-+ XShmAttach( dpy, shminfo );
-+ shm_inited = 2;
-+ XSync( dpy, False );
-+ XSetErrorHandler( old_h );
-+ if( qt_mitshm_error ) { // oops ... perhaps we are remote?
-+ shm_inited = 0;
-+ XDestroyImage( xi );
-+ shmdt( shminfo->shmaddr );
-+#ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
-+ shmctl( shminfo->shmid, IPC_RMID, 0 );
-+#endif
-+ return NULL;
-+ }
-+ } else
-+ XShmAttach( dpy, shminfo );
-+ return xi;
-+}
-+
-+static void qt_XShmDestroyImage( XImage* xi, XShmSegmentInfo* shminfo )
-+{
-+ XShmDetach( QPaintDevice::x11AppDisplay(), shminfo );
-+ XDestroyImage( xi );
-+ shmdt( shminfo->shmaddr );
-+#ifdef QT_MITSHM_RMID_IGNORES_REFCOUNT
-+ shmctl( shminfo->shmid, IPC_RMID, 0 );
-+#endif
-+}
-+
-+static XImage* qt_XShmGetImage( const QPixmap* pix, int format,
-+ XShmSegmentInfo* shminfo )
-+{
-+ XImage* xi = qt_XShmCreateImage( pix->x11Display(), (Visual*)pix->x11Visual(),
-+ pix->depth(), format, 0, 0, pix->width(), pix->height(), 32, 0, shminfo );
-+ if( xi == NULL )
-+ return NULL;
-+ if( XShmGetImage( pix->x11Display(), pix->handle(), xi, 0, 0, AllPlanes ) == False ) {
-+ qt_XShmDestroyImage( xi, shminfo );
-+ return NULL;
-+ }
-+ return xi;
-+}
-
-+#endif // QT_MITSHM_CONVERSIONS
-
- /*****************************************************************************
- Internal functions
-@@ -627,9 +730,20 @@ QImage QPixmap::convertToImage() const
- d = 32; // > 8 ==> 32
-
- XImage *xi = (XImage *)data->ximage; // any cached ximage?
-- if ( !xi ) // fetch data from X server
-+#ifdef QT_MITSHM_CONVERSIONS
-+ bool mitshm_ximage = false;
-+ XShmSegmentInfo shminfo;
-+#endif
-+ if ( !xi ) { // fetch data from X server
-+#ifdef QT_MITSHM_CONVERSIONS
-+ xi = qt_XShmGetImage( this, mono ? XYPixmap : ZPixmap, &shminfo );
-+ if( xi ) {
-+ mitshm_ximage = true;
-+ } else
-+#endif
- xi = XGetImage( x11Display(), hd, 0, 0, w, h, AllPlanes,
- mono ? XYPixmap : ZPixmap );
-+ }
- Q_CHECK_PTR( xi );
- if (!xi)
- return image; // null image
-@@ -640,15 +754,31 @@ QImage QPixmap::convertToImage() const
- QImage::LittleEndian : QImage::BigEndian;
- }
- image.create( w, h, d, 0, bitOrder );
-- if ( image.isNull() ) // could not create image
-+ if ( image.isNull() ) { // could not create image
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage )
-+ qt_XShmDestroyImage( xi, &shminfo );
-+ else
-+#endif
-+ qSafeXDestroyImage( xi );
- return image;
-+ }
-
- const QPixmap* msk = mask();
- const QPixmap *alf = data->alphapm;
-
- QImage alpha;
- if (alf) {
-- XImage *axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
-+ XImage* axi;
-+#ifdef QT_MITSHM_CONVERSIONS
-+ bool mitshm_aximage = false;
-+ XShmSegmentInfo ashminfo;
-+ axi = qt_XShmGetImage( alf, ZPixmap, &ashminfo );
-+ if( axi ) {
-+ mitshm_aximage = true;
-+ } else
-+#endif
-+ axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
-
- if (axi) {
- image.setAlphaBuffer( TRUE );
-@@ -662,6 +792,11 @@ QImage QPixmap::convertToImage() const
- src += axi->bytes_per_line;
- }
-
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_aximage )
-+ qt_XShmDestroyImage( axi, &ashminfo );
-+ else
-+#endif
- qSafeXDestroyImage( axi );
- }
- } else if (msk) {
-@@ -804,6 +939,12 @@ QImage QPixmap::convertToImage() const
- xi->bits_per_pixel );
- #endif
- image.reset();
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage )
-+ qt_XShmDestroyImage( xi, &shminfo );
-+ else
-+#endif
-+ qSafeXDestroyImage( xi );
- return image;
- }
-
-@@ -909,10 +1050,22 @@ QImage QPixmap::convertToImage() const
- delete [] carr;
- }
- if ( data->optim != BestOptim ) { // throw away image data
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage )
-+ qt_XShmDestroyImage( xi, &shminfo );
-+ else
-+#endif
- qSafeXDestroyImage( xi );
- ((QPixmap*)this)->data->ximage = 0;
-- } else // keep ximage data
-+ } else { // keep ximage data
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage ) { // copy the XImage?
-+ qt_XShmDestroyImage( xi, &shminfo );
-+ xi = 0;
-+ }
-+#endif
- ((QPixmap*)this)->data->ximage = xi;
-+ }
-
- return image;
- }
-@@ -1085,6 +1238,11 @@ bool QPixmap::convertFromImage( const QI
- bool trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor);
- int nbytes = image.numBytes();
- uchar *newbits= 0;
-+ int newbits_size = 0;
-+#ifdef QT_MITSHM_CONVERSIONS
-+ bool mitshm_ximage = false;
-+ XShmSegmentInfo shminfo;
-+#endif
-
- if ( trucol ) { // truecolor display
- QRgb pix[256]; // pixel translation table
-@@ -1113,10 +1271,18 @@ bool QPixmap::convertFromImage( const QI
- }
- }
-
-+#ifdef QT_MITSHM_CONVERSIONS
-+ xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
-+ if( xi != NULL ) {
-+ mitshm_ximage = true;
-+ newbits = (uchar*)xi->data;
-+ }
-+ else
-+#endif
- xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
-- Q_CHECK_PTR( xi );
- if (!xi)
- return false;
-+ if( newbits == NULL )
- newbits = (uchar *)malloc( xi->bytes_per_line*h );
- Q_CHECK_PTR( newbits );
- if ( !newbits ) // no memory
-@@ -1323,6 +1489,7 @@ bool QPixmap::convertFromImage( const QI
- }
-
- newbits = (uchar *)malloc( nbytes ); // copy image into newbits
-+ newbits_size = nbytes;
- Q_CHECK_PTR( newbits );
- if ( !newbits ) // no memory
- return FALSE;
-@@ -1440,11 +1607,18 @@ bool QPixmap::convertFromImage( const QI
- }
-
- if ( !xi ) { // X image not created
-+#ifdef QT_MITSHM_CONVERSIONS
-+ xi = qt_XShmCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0, &shminfo );
-+ if( xi != NULL )
-+ mitshm_ximage = true;
-+ else
-+#endif
- xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
- if ( xi->bits_per_pixel == 16 ) { // convert 8 bpp ==> 16 bpp
- ushort *p2;
- int p2inc = xi->bytes_per_line/sizeof(ushort);
- ushort *newerbits = (ushort *)malloc( xi->bytes_per_line * h );
-+ newbits_size = xi->bytes_per_line * h;
- Q_CHECK_PTR( newerbits );
- if ( !newerbits ) // no memory
- return FALSE;
-@@ -1462,6 +1636,14 @@ bool QPixmap::convertFromImage( const QI
- "(bpp=%d)", xi->bits_per_pixel );
- #endif
- }
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( newbits_size > 0 && mitshm_ximage ) { // need to copy to shared memory
-+ memcpy( xi->data, newbits, newbits_size );
-+ free( newbits );
-+ newbits = (uchar*)xi->data;
-+ }
-+ else
-+#endif
- xi->data = (char *)newbits;
- }
-
-@@ -1495,19 +1677,24 @@ bool QPixmap::convertFromImage( const QI
-
- }
-
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage )
-+ XShmPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE ),
-+ xi, 0, 0, 0, 0, w, h, False );
-+ else
-+#endif
- XPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE ),
- xi, 0, 0, 0, 0, w, h );
-
-- if ( data->optim != BestOptim ) { // throw away image
-- qSafeXDestroyImage( xi );
-- data->ximage = 0;
-- } else { // keep ximage that we created
-- data->ximage = xi;
-- }
- data->w = w;
- data->h = h;
- data->d = dd;
-
-+ XImage* axi = NULL;
-+#ifdef QT_MITSHM_CONVERSIONS
-+ bool mitshm_aximage = false;
-+ XShmSegmentInfo ashminfo;
-+#endif
- if ( image.hasAlphaBuffer() ) {
- QBitmap m;
- m = image.createAlphaMask( conversion_flags );
-@@ -1543,13 +1730,22 @@ bool QPixmap::convertFromImage( const QI
- data->alphapm->rendhd =
- (HANDLE) XftDrawCreateAlpha( x11Display(), data->alphapm->hd, 8 );
-
-- XImage *axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
-+#ifdef QT_MITSHM_CONVERSIONS
-+ axi = qt_XShmCreateImage( x11Display(), (Visual*)x11Visual(),
-+ 8, ZPixmap, 0, 0, w, h, 8, 0, &ashminfo );
-+ if( axi != NULL )
-+ mitshm_aximage = true;
-+ else
-+#endif
-+ axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
- 8, ZPixmap, 0, 0, w, h, 8, 0);
-
- if (axi) {
-+ if( axi->data==NULL ) {
- // the data is deleted by qSafeXDestroyImage
- axi->data = (char *) malloc(h * axi->bytes_per_line);
- Q_CHECK_PTR( axi->data );
-+ }
- char *aptr = axi->data;
-
- if (image.depth() == 32) {
-@@ -1567,14 +1763,48 @@ bool QPixmap::convertFromImage( const QI
- }
-
- GC gc = XCreateGC(x11Display(), data->alphapm->hd, 0, 0);
-+ #ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_aximage )
-+ XShmPutImage( dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h, False );
-+ else
-+#endif
- XPutImage(dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h);
- XFreeGC(x11Display(), gc);
-- qSafeXDestroyImage(axi);
- }
- }
- #endif // QT_NO_XFTFREETYPE
- }
-
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage || mitshm_aximage )
-+ XSync( x11Display(), False ); // wait until processed
-+#endif
-+
-+ if ( data->optim != BestOptim ) { // throw away image
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage )
-+ qt_XShmDestroyImage( xi, &shminfo );
-+ else
-+#endif
-+ qSafeXDestroyImage( xi );
-+ data->ximage = 0;
-+ } else { // keep ximage that we created
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_ximage ) { // copy the XImage?
-+ qt_XShmDestroyImage( xi, &shminfo );
-+ xi = 0;
-+ }
-+#endif
-+ data->ximage = xi;
-+ }
-+ if( axi ) {
-+#ifdef QT_MITSHM_CONVERSIONS
-+ if( mitshm_aximage )
-+ qt_XShmDestroyImage( axi, &ashminfo );
-+ else
-+#endif
-+ qSafeXDestroyImage(axi);
-+ }
- return TRUE;
- }
-
-@@ -1737,7 +1967,7 @@ QPixmap QPixmap::xForm( const QWMatrix &
- return pm;
- }
-
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
- static bool try_once = TRUE;
- if (try_once) {
- try_once = FALSE;
-@@ -1770,7 +2000,7 @@ QPixmap QPixmap::xForm( const QWMatrix &
- dbpl = ((w*bpp+31)/32)*4;
- dbytes = dbpl*h;
-
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
- if ( use_mitshm ) {
- dptr = (uchar *)xshmimg->data;
- uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
-@@ -1786,7 +2016,7 @@ QPixmap QPixmap::xForm( const QWMatrix &
- memset( dptr, Qt::white.pixel( x11Screen() ), dbytes );
- else
- memset( dptr, 0xff, dbytes );
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
- }
- #endif
-
-@@ -1817,7 +2047,7 @@ QPixmap QPixmap::xForm( const QWMatrix &
- } else {
- xbpl = (w*bpp)/8;
- p_inc = dbpl - xbpl;
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
- if ( use_mitshm )
- p_inc = xshmimg->bytes_per_line - xbpl;
- #endif
-@@ -1854,7 +2084,7 @@ QPixmap QPixmap::xForm( const QWMatrix &
- QPixmap pm( w, h );
- pm.data->uninit = FALSE;
- pm.x11SetScreen( x11Screen() );
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
- if ( use_mitshm ) {
- XCopyArea( dpy, xshmpm, pm.handle(), gc, 0, 0, w, h, 0, 0 );
- } else {
-@@ -1863,7 +2093,7 @@ QPixmap QPixmap::xForm( const QWMatrix &
- ZPixmap, 0, (char *)dptr, w, h, 32, 0 );
- XPutImage( dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
- qSafeXDestroyImage( xi );
--#if defined(QT_MITSHM)
-+#if defined(QT_MITSHM_XFORM)
- }
- #endif
-
---- mkspecs/linux-g++/qplatformdefs.h
-+++ mkspecs/linux-g++/qplatformdefs.h
-@@ -102,5 +102,6 @@
- #define QT_VSNPRINTF ::vsnprintf
- #endif
-
-+#define QT_MITSHM
-
- #endif // QPLATFORMDEFS_H