[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.
Uwe
---
#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 );
painter.end();
}
QImage renderRaster( const QPolygonF &points )
{
QImage img( 1000, 1000, QImage::Format_RGB32 );
img.fill( Qt::white );
QElapsedTimer timer;
timer.start();
draw( points, img );
qDebug() << "Raster" << timer.elapsed();
return img;
}
QImage renderX11( const QPolygonF &points )
{
QPixmap pm( 1000, 1000 );
pm.fill( Qt::white );
QElapsedTimer timer;
timer.start();
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