PDA

View Full Version : Drawing to an offscreen buffer



Dutch112
5th May 2009, 15:40
The application I'm working on has several animating objects (rotating in a circle) and I'm looking to lower the CPU consumed. I'm using the graphicsview framework and most objects on the screen, including the animating objects are derived from QGraphicsWidget.

I do set the viewport to QGLWidget so I get some OpenGL acceleration but that isn't lowering the CPU enough.

I see setting the viewport to QGLWidget changes the paint engine to QOpenGLPaintEngine and translates a lot of the painter calls to OpenGL calls. Looking through the source and stepping through in debug, I come across this function of particular interest:



void QGLDrawable::setDevice(QPaintDevice *pdev)
{
...
if (pdev->devType() == QInternal::Widget)
widget = static_cast<QGLWidget *>(pdev);
else if (pdev->devType() == QInternal::Pbuffer)
buffer = static_cast<QGLPixelBuffer *>(pdev);
else if (pdev->devType() == QInternal::FramebufferObject)
fbo = static_cast<QGLFramebufferObject *>(pdev);
else if (pdev->devType() == QInternal::UnknownDevice)
...
}


It looks like this paint engine has the ability to render into a framebuffer object and this would probably give me a nice gain in performance (platform does support framebuffer objects).

The only problem is I don't see how to change an object's PaintDevice. For all my objects the PaintDevice is of type Widget, which is expected.

Does anyone know how I can change the PaintDevice to FramebufferObject?

I've thought of changing this file to always use frame buffers but it seems there should be a way to set this.

wysota
5th May 2009, 20:36
Don't mess with such low level solutions. Instead turn on caching for your items - it will result in a performance boost which will probably be even better than using a framebuffer.

Dutch112
5th May 2009, 21:09
Don't mess with such low level solutions. Instead turn on caching for your items - it will result in a performance boost which will probably be even better than using a framebuffer.

I already use ItemCoordinateCache for all of my items.

The problem is the animations are sucking a lot of CPU.

To give you an idea of the application, it has 36 rotating images at 25 frames per second along with other static widgets and buttons.

My target hardware is a 1 GHZ netbook with a via unichrome graphics chip.

The above uses 90+% CPU.

I can run Qt's framebufferobject2 example, texturing the quads with the same image used above and rotating them in the same way at 50 frames per second. And this uses only 15% or so CPU.

That is the kind of gain I am looking for and the reason I thought getting frame buffers enabled would improve performance.

wysota
5th May 2009, 23:02
I already use ItemCoordinateCache for all of my items.
Using the framebuffer won't help then. You might switch to DeviceCoordinateCache but I wouldn't expect miracles.


To give you an idea of the application, it has 36 rotating images at 25 frames per second along with other static widgets and buttons.
Are you performing the animation using QGraphicsScene::advance()?


I can run Qt's framebufferobject2 example, texturing the quads with the same image used above and rotating them in the same way at 50 frames per second. And this uses only 15% or so CPU.
It doesn't involve Graphics View, so no collision detection or transformations.


That is the kind of gain I am looking for and the reason I thought getting frame buffers enabled would improve performance.

Try profiling your application to see what is causing the slowdowns. I think the bottleneck is not rendering.

Dutch112
6th May 2009, 16:34
Are you performing the animation using QGraphicsScene::advance()?

No, right now the animations are each a QGraphicsWidget that use the QGraphicsItemAnimation.



It doesn't involve Graphics View, so no collision detection or transformations.


Could I disable collision detection?




Try profiling your application to see what is causing the slowdowns. I think the bottleneck is not rendering.

What profilers do you recommend?

wysota
6th May 2009, 16:49
No, right now the animations are each a QGraphicsWidget that use the QGraphicsItemAnimation.
Try switching to advance, it should be faster.



Could I disable collision detection?
If you're not moving the items too much then it's enough to set the "interactive" property of the view to false. If you are moving items but you don't care about collisions, disable indexing for the scene.


What profilers do you recommend?

Callgrind (part of Valgrind package) or gprof if you're running a supported platform. I don't profile on Windows so I can't recommend anything there.