[Development] Charts and DataVis Questions

Uwe Rathmann Uwe.Rathmann at tigertal.de
Sat Jan 23 13:45:04 CET 2016


Hi,

> The OpenGL acceleration in Charts module is really impressive ...

Unfortunately part of the truth is, that the performance of the software 
renderer does not necessarily be that far behind.

An example: in a test program I'm creating a polygon of 10000 points in 
an area of 1000x1000 using (qAbs(random) % 1000) and then I'm drawing it 
this way:

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


As I want to compare hardware vs. software renderer I'm using Qt 4.8 with 
X11 ( "native" ) as backend. Here drawing to a QImage uses the software 
renderer, while drawing to a pixmap is usually hardware accelerated.

To make it comparable I'm converting the pixmap to an image, so that I 
have the same input and the same output.  ( in case you are interested I 
added the code at the end of this posting. )

O.k. this is what I see with Qt 4.8:

- Raster 735ms
- X11 120ms

When doing the same with a Qt-5.6 beta:

- Raster 775ms
- X11 775ms ( no surprise )


Next I modified the draw method a bit:

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

    const int numPoints = 100;
    const int numChunks = points.size() / numPoints;
    for ( int i = 0; i < numChunks; i++ )
    {
        painter.drawPolyline( points.constData() + i * numPoints, 
numPoints );
    }
    painter.end();
}

( of course this is not exactly the same as the pixels to join the chunks 
at there ends are missing ).

Now the result is:

Raster ( Qt 4.8 ): 382ms
Raster ( Qt 5.6 ): 403ms

When using a chunk size ( = numPoints ) of 10 I have:

Raster ( Qt 4.8 ): 192
Raster ( Qt 5.6 ): 181
X11    ( Qt 4.8 ):  93

In the end the implementation of a chart package is full of finding and 
implementing workarounds and optimizations like this one - at least this 
is my experience with being the maintainer of a chart package ( Qwt ) 
over the years.

Uwe

--


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;
}




More information about the Development mailing list