PDA

View Full Version : Graphical Performance Slowed When Migrating from Qt 4.52 to Qt 4.6.1



dchow
28th January 2010, 01:06
The project I'm working on uses a QGraphicsView, with a QGraphicsScene, and thousands (10K to >100K worst case) QGraphicsItems. The scene is interactive allowing for selection and drag and drop of some of the items. After much refinement, through displaying only what absolutely needed to be displayed and creating QGraphicsItems only when absolutely needed, I was able to bring performance to an acceptable level despite having a large number of QGraphicsItems displayed in the scene at one time.

Then, I switched from Qt 4.5.2 to Qt 4.6.1. After making the necessary updates of removing obsoleted member functions and replacing them with the updated ones, I noticed that the redraw performance was significantly slower.

For example, when selecting an object, using Qt 4.5.2 it would change to its selection color (red) basically immediately. Now, after changing to Qt 4.6.1, it takes anywhere from 1-2 seconds. Even worse, when drawing a QRubberband for doing area selection, using Qt 4.5.2, the QRubberband would track fairly well with the mouse. Now, with Qt 4.6.1, the QRubberband takes about 2-3 seconds to first display the rubber band, and then only after I stop moving the mouse for 1-2 seconds does it display the updated rectangle.

Just to provide some more information. I have tried removing the graphical items in the scene. There are essentially two types of items in my scene. One type is placed regularly around the scene (QGraphicsRectItem), and when I draw just these performance is okay. The other type is about 10x smaller (also QGraphicsRectItem), and they are packed closer together, but scattered in different areas around the scene. When drawing just the smaller item type, then graphical performance suffers. What is peculiar is that for one case, the number of large items is about 6K and the number of small items is 1.5K. This is odd, because it seems like it is not the number of items, but rather that the smaller items are treated differently by Qt. To narrow it down and eliminate my paint function, I also commented out my custom paint code so it would only call 'drawRect' and still saw a significant performance hit.

Has anyone else seen a similar issue with their move to 4.6? If so, what did you do to fix it?

Thanks very much!

dchow
2nd February 2010, 19:54
I think I've figured out what was causing the slowdown -

I had reimplemented QGraphicsRectItem::boundingRect() for the smaller rectangles, and in it, instead of just returning a saved QRectF, I was calculating the bounding rectangle every time it was getting called. When I changed the implementation to just return a saved QRectF (calculated beforehand and saved), then the performance jumped up dramatically! This approach should work, since my graphical items do not move or rotate, so I think the bounding rectangle should not ever need to be changed.

However, now things don't seem to be getting redrawn correctly, but it could have more to do with my bounding rectangle not being entirely correct. This also makes me wonder why this had worked fine before, but not any more...

So, just a note to others then: if you reimplement boundingRect() make sure it's as efficient as possible, since Qt calls it many times during redraws of the scene.

pitonyak
2nd February 2010, 22:57
Can you clarify one point for me. Does the slower version draw correctly, or does it also exhibit the incorrect draw behavior?

I am running the stock version of 4.6.1 on 64-bit fedora 12. QT Creator has numerous redraw issues on my platform with my video driver.

dchow
4th February 2010, 19:10
Sure! I've been playing with all the different variants and it looks like it might be something with Qt 4.6.1. I put back my old slow code and ran it with Qt 4.6.1 and saw the same incorrect drawing behavior. Just to clarify, the incorrect drawing behavior is that when scrolling very quickly, or zooming in, the items are not being redrawn until another paint event is triggered.

When I went back and tried rerunning the old code with Qt 4.5.2 everything was getting drawn correctly... I haven't tried using my updated code with Qt 4.5.2 though, it's not worth it since I need to move to 4.6.1 anyway.