[Development] QT_XCB_NATIVE_PAINTING makes worse that without of it

Uwe Rathmann Uwe.Rathmann at tigertal.de
Sun Mar 24 11:27:41 CET 2019

On 3/23/19 11:09 PM, Allan Sandfeld Jensen wrote:

> Software implementation is the default for X11 painting, with accelerated
> paths being addons.

Having those addons is usually pronounced as: the system supports the GPU.

Sure there are systems, where this is not the case and things fall back 
to software rendering - but we shouldn't give the impression, that this 
is the average situation of systems running X11.
> But for most applications Qt raster engine is faster.

The use case of Denis is about QPainter::drawPolyline - so let's have 
some numbers for Qt 5.12 and QT_XCB_NATIVE_PAINTING enabled ( code 
inlined at the end ):

- Raster: 6780
- X11: 683

( When using a pen width of 0 raster is only 3 times worse )

Without the extra copying out of the pixmap ( QPixmap::toImage() ) I 
have this number:

- X11: 200

The main effect here is that application and X server run in parallel. 
For the use case of Denis this is relevant as the application could work 
on creating the points for the next frame.


So this is obviously a use case, where Raster is worse - when doing 
remote X11 you have another important one. On the other hand I have 
never seen a paper, where this "for most applications Qt raster engine 
is faster" message is coming from or what type of use case it refers to.

Maybe it is only me who missed this information, but if you know more or 
have numbers supporting your statement: please share them.

Actually the information what graphic pipeline is best for which type of 
use case should be found in the Qt docs - in the best case with a solid 
explanation. Otherwise this myth about software rendering being faster 
continues to be told again and again.



#include <QApplication>
#include <QPainter>
#include <QPixmap>
#include <QElapsedTimer>
#include <QDebug>

void draw( const QPolygonF &points, QPaintDevice &paintDevice )
     QPainter painter( &paintDevice );
     painter.setPen( QPen( Qt::black, 2 ) );

     painter.drawPolyline( points );

QImage renderRaster( const QPolygonF &points )
     QImage img( 1000, 1000, QImage::Format_RGB32 );
     img.fill( Qt::white );

     QElapsedTimer timer;

     draw( points, img );

     qDebug() << "Raster" << timer.elapsed();

     return img;

QImage renderX11( const QPolygonF &points )
     QPixmap pm( 1000, 1000 );
     pm.fill( Qt::white );

     QElapsedTimer timer;

     draw( points, pm );

     const QImage img = pm.toImage();
     qDebug() << "X11" << timer.elapsed();

     return img;

int main( int argc, char *argv[] )
     QApplication app( argc, argv );

     QPolygonF points;

     for ( int i = 0; i < 100000; i++ )
         points += QPointF( qAbs( random() ) % 1000, qAbs( random() ) % 
1000 );

     const QImage img1 = renderRaster( points );
     const QImage img2 = renderX11( points );

     qDebug() << ( img1 == img2 );

More information about the Development mailing list