[Qt-interest] QGraphicsOpacityEffect performance worse than QGraphicsItem::setOpacity()

Samuel Rødal sroedal at trolltech.com
Thu Oct 15 13:31:47 CEST 2009


Josiah Bryan wrote:
> I'm incredibly excited about the new QGraphicsEffect "module" in Qt 4.6. 
> Since the release of the beta last night (today?), I've integrated two 
> of the effects (opacity and drop shadow) into the project I've been 
> working on for the past two months (http://code.google.com/p/dviz/).
> 
> What I found, especially with regards to the opacity effect, was quite 
> surprising to me. Specifically, the performance of using 
> QGraphicsOpacityEffect to cross fade between QGraphicsItem's is 
> *considerably* worse than just using QGraphicsItem::setOpacity() 
> directly. A 30 frame, 250ms-long cross fade takes > 5 - 10 seconds due 
> to painting using QGraphicsOpacityEffect. Whereas using straight 
> QGraphicsItem::setOpacity(), we hit around 275ms - 500ms from start to 
> completion of the crossfade. (The 250ms is the target time, the time 
> between steps in the crossfade is calculated as 250 / 30 (QTimer is used 
> to trigger the frames). The actual painting of the items  often causes 
> the actual time to take a bit longer than 1ms to complete each frame, 
> pushing it out past the 250ms length. When using QGraphicsOpacityEffect, 
> we're hitting north of 150ms - 250ms *per repaint*. Under straight 
> setOpacity(), its around 1 - 4ms per repaint. And this is a *simple* 
> scene - two rectangular QGraphicsItems - and thats it!
> 
> An additional blow to my excitement was the performance of 
> QGraphicsDropShadowEffect on a simple rectangular custom QGraphicsItem. 
> Changing the blur radius, for example, from 1px to 5px takes around 
> 1/2second to re-render the scene. (Whereas, when rendering a "cheap" 
> drop shadow as just using drawRect() with a different color and offset 
> is imperceptibly fast.)
> 
> Those are the two major "problems" I've seen in this Qt 4.6 beta - and 
> that is on both Windows XP Pro and Linux (FC 8), with both very high end 
> graphics cards, dual / quad processor, 4 GB RAM. So the system isn't the 
> lag - it seems the library code is (at least on this end.) Anyone else 
> seeing similar problems?
> 
> Thanks for your time!
> 
> Cheers!
> -josiah

QGraphicsOpacityEffect is usually going to be quite a bit slower than 
just setting the opacity on the item. The use case for 
QGraphicsOpacityEffect is when you want to apply opacity to a group of 
overlapping items, or to an item whose paint() function draws several 
overlapping shapes. By just using QGraphicsItem::setOpacity() the 
opacity will be set on the painter, and thus each individual paint 
command will be affected by the opacity. Thus, if you have a green item 
on top of a red item, you will see parts of the red item when setting 
opacity to 50 %, since first the red item is drawn with 50 % opacity and 
then the green item. QGraphicsOpacityEffect on the other hand paints the 
whole graphics item (+ children) to a temporary pixmap, and then draws 
the pixmap with opacity set. This will naturally be quite a bit slower 
than using setOpacity().

I wouldn't recommend using graphics effects on other than small graphics 
items when using the raster paint engine. Prefer to set a QGLWidget as 
viewport on the QGraphicsView to improve the performance of the graphics 
effects. Also, when using a QGLWidget I'd recommend using a smaller 
amount of graphics effects covering a larger area, instead of a lot of 
individual graphics effects, as each graphics effect requires binding 
and releasing an OpenGL framebuffer object, which has a slight overhead 
cost.

--
Samuel



More information about the Qt-interest-old mailing list