Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, November 2006
Fastest scaling: QImage, QPixmap or QPainter?


Message 1 in thread

Hi,
I'm writing a Qt 4.2 based spectrogram app that will display scolling
FFT data in real time. I'm using Qt/X11 on Linux. After rendering the
FFT to an image, I want to scale it for display.

To keep the main/GUI thread responsive, I'm going to use a separate
rendering thread that will render the FFT and maybe scale the rendered
image, then pass (signal->slot) the resulting QImage or QPixmap to the
GUI thread to be displayed (painted to a QLabel widget being used as a
display area).

My question is what is the fastest way to do the scaling? Ideally I'd
like to have it done by my graphics card (Radeon 9200) if possible. It
seems that the scaling options are:

1) QImage::smoothScale()
2) QPixmap::xForm()
3) QPainter::scale()

Which one of these is fastest? Do QPixmaps (being server based in Qt
X11) get xForm'd in hardware? What about QPainter::scale() - does that
take advantage of graphics hardware acceleration? What about scaled
painting to a QGLWidget - would that invoke OpenGL hardware scaling?

Any overall advice on what combination of QImage, QPixmap and display
widget (QLabel or perhaps QGLWidget) to use? I was basically thinking
of rendering to a QImage since that gives fast direct pixel access,
then scaling to a QPixmap (still in the rendering thread) to pass to
the main/GUI thread to paint to the display widget.

Thanks for any advice anyone can offer. Any partial replies very welcome!

Ben

--
 [ signature omitted ] 

Message 2 in thread

Ben Bridgwater wrote:
> Hi,
> I'm writing a Qt 4.2 based spectrogram app that will display scolling
> FFT data in real time. I'm using Qt/X11 on Linux. After rendering the
> FFT to an image, I want to scale it for display.
>
> To keep the main/GUI thread responsive, I'm going to use a separate
> rendering thread that will render the FFT and maybe scale the rendered
> image, then pass (signal->slot) the resulting QImage or QPixmap to the
> GUI thread to be displayed (painted to a QLabel widget being used as a
> display area).
>
> My question is what is the fastest way to do the scaling? Ideally I'd
> like to have it done by my graphics card (Radeon 9200) if possible. It
> seems that the scaling options are:
>
> 1) QImage::smoothScale()
> 2) QPixmap::xForm()
> 3) QPainter::scale()
>
> Which one of these is fastest? Do QPixmaps (being server based in Qt
> X11) get xForm'd in hardware? What about QPainter::scale() - does that
> take advantage of graphics hardware acceleration? What about scaled
> painting to a QGLWidget - would that invoke OpenGL hardware scaling?
>
> Any overall advice on what combination of QImage, QPixmap and display
> widget (QLabel or perhaps QGLWidget) to use? I was basically thinking
> of rendering to a QImage since that gives fast direct pixel access,
> then scaling to a QPixmap (still in the rendering thread) to pass to
> the main/GUI thread to paint to the display widget.
>
> Thanks for any advice anyone can offer. Any partial replies very welcome!
>
> Ben
You can't use QPixmap in the non-GUI thread. You can use QImage (once Qt
4.2.2 comes out, QImage is not re-entrant in Qt 4.2.1 and earlier
versions either -- there are a bunch of race conditions). I think your
best bet is to render the image into your own pixel buffer and use that
as an OpenGL texture. Then, setup OpenGL viewing, and draw a texture
mapped quad -- OpenGL will do the hardware scaling for you.

    Paul.

--
 [ signature omitted ] 

Message 3 in thread

Am Mittwoch, 1. November 2006 23:05 schrieb Paul Koshevoy:
> You can't use QPixmap in the non-GUI thread. You can use QImage (once Qt
> 4.2.2 comes out, QImage is not re-entrant in Qt 4.2.1 and earlier
> versions either -- there are a bunch of race conditions). I think your
> best bet is to render the image into your own pixel buffer and use that
> as an OpenGL texture. Then, setup OpenGL viewing, and draw a texture
> mapped quad -- OpenGL will do the hardware scaling for you.
this works even easier: subclass QGLWidget, re-implement paintEvent and do a 
drawImage( ... ) with according parameters. Your scaled image will be shown 
within a few milliseconds if OpenGL is HW-accellerated. This way I even 
realized a simple dia-show with alpha-blended 2048x1536-images scaled down to 
display-resolution with about 20fps...
If OpenGL is not desired, QImage::smoothScale for Qt >= 4.2.0 (or Qt 3.X) 
should be quite fast and fit your needs. It uses and optimized 
scaling-algorithm (running on CPU) although alpha-channel-support adds a bit 
overhead if alpha-channels are not needed. (I also have a faster version 
without alpha-channel-support if you're interested in it)

toby

Attachment:

Attachment: pgpMNNP5WYFjY.pgp
Description: PGP signature