[Qt-interest] Qt4.4.3 paintEvent thread-safe

Prasanta Sadhukhan Prasanta.Sadhukhan at Sun.COM
Mon Dec 22 13:33:22 CET 2008


Oliver.Knoll at comit.ch wrote:
> Prasanta Sadhukhan wrote on Monday, December 22, 2008 10:14 AM:
>
>   
>> Hi,
>>
>> I want to know if is it alright to introduce mutex lock/unlock inside
>> a widget PaintEvent function?
>>     
>
> You should not need this, see below.
>
>   
>> But, one problem after I introduced this lock, is one of our
>> benchmark test is running 4 times slower (90secs compared to 22secs
>> without lock/unlock). Can anyone shed some light?
>>     
>
> Aquiring a lock is *expensive*, so doing this in a paint method (which gets called dozens of times per second) degrades your performance considerably (I wouldn't have expected an impact of 90s vs 22s though...).
>
> So the question is: from which thread are you calling your paint method? If it is any other thread than the *GUI thread* (aka "main" thread), then the answer is: don't do this! ;)
>
> Painting/widget modification in Qt is *not* thread-safe (one reason being performance), so you are only allowed to call them from within the GUI thread (the thread which originates from your main() function).
>
> So the typical solution: if you have any other worker threads, make them signal that some work is done and ready to be displayed. Use "queued connections" (http://doc.trolltech.com/4.4/qt.html#ConnectionType-enum) as to synchronise your (worker) threads with the GUI thread.
>
>   
Thanks.
And yes, I do all the paintings into offscreen surface in main thread 
[which executes main()] and relegated the flushing of "offscreen" to 
"screen" in paintEvent in the thread which created QApplication and 
executes exec(). I cannot creat QApplication/exec in "main" thread as 
the stack is designed in such a way [the main thread initialises all 
network, i/o, graphics etc, so all the graphics painting will be done in 
"main" thread]. You can get the idea from the attached qt app.
As such, the above design of doing all the paintings into "offscreen" 
surface [QImage] and then sending update() back to exec() thread where 
paintEvent flushes the offscreen into QPainter screen is working and our 
testsuite also passed, except for this 1 benchmark which shows slowdown
Can you tell me how can I modify the app to use queued connection? or 
maybe point to some example

Regards
Prasanta
> Then when your widget receives the signal in the corresponding slot ("updateGui" or whatever) it is safe to paint without any mutex locking.
>
> This is a typical question which pops up in regular intervals here on qt-interest at trolltech.com, so you might also want to consult the archive (http://lists.trolltech.com/qt-interest/) / google.
>
>
> Cheers, Oliver
>
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest
>   

-------------- next part --------------
A non-text attachment was scrubbed...
Name: drawline.cpp
Type: text/x-c++src
Size: 6575 bytes
Desc: not available
Url : http://lists.qt-project.org/pipermail/qt-interest-old/attachments/20081222/77393f2b/attachment.bin 


More information about the Qt-interest-old mailing list