[Qt-interest] Qt, DirectX and MultiThreading

Ender EREL erelender at yahoo.com
Thu Apr 15 09:30:34 CEST 2010


Hello everyone,

Yeah, i know, i am walking in very dangerous, murky waters here so if 
you want, you can close this message now. But if you like challenges, 
stay tuned in for a bucket-load of fun!

I am developing on Win7 using Qt 4.5.3 & MSVC2008.

We have a 3D Engine that uses DirectX and i am given the task of 
integrating this with Qt. My aim is to enable DirectX rendering on a 
QWidget surface. I completed this successfully by giving the HWND of my 
widget to the engine where my colleagues take over. Victory!

Everything was going perfectly, until i opened a modal dialog 
(QFileDialog to be exact), which stops the execution of Qt's Event Loop, 
which manages QTimers including the most important QTimer for me: the 
QTimer (a zero-timer) that triggers the DirectX rendering. I facepalm'd.

So, when a modal dialog is opened (or QApplication event-loop is blocked 
in some way) my rendering stops, which is not critical, but creates an 
unpleasant experience.

Then i decided to dive deeper into this. I said to myself: "Hey, why not 
trigger the rendering in another thread? Everthing will be perfect!". I 
was wrong.

Yes, this is the background part for my problem. here comes the unveiling:

When the app is first launched, everything is fine. Both threads (main & 
rendering) do their job happily. Until i interact with the GUI in any 
way. The main thread locks up but the rendering thread does its job nicely.

I did what any developer would do. I debugged. And found out that my 
main thread hangs at QRasterWindowSurface::flush(), line 185, where it 
calls BitBlt. Examining the stack trace, i saw that the widget that 
causes the hanging is not my DirectX Widget but its parent's parent, 
which is a top level window. I will paste the stack trace below, if 
anyone is still reading and wants to take a look.

Stack trace:

  gdi32.dll!75ca5f3e() 	
  [Frames below may be incorrect and/or missing, no symbols loaded for 
gdi32.dll]	
  gdi32.dll!75ca5f3e() 	
  gdi32.dll!75ca5f1d() 	
  QtGuid4.dll!QRasterWindowSurface::flush(QWidget * widget=0x01f90340, 
const QRegion & rgn={...}, const QPoint & offset={...})  Line 187
  QtGuid4.dll!qt_flush(QWidget * widget=0x01f90340, const QRegion & 
region={...}, QWindowSurface * windowSurface=0x0232ee28, QWidget * 
tlw=0x003efc18, const QPoint & tlwOffset={...})  Line 99
  QtGuid4.dll!QWidgetBackingStore::flush(QWidget * widget=0x00000000, 
QWindowSurface * surface=0x00000000)  Line 1344 + 0x27 bytes
  QtGuid4.dll!QWidgetBackingStore::endPaint(const QRegion & 
cleaned={...}, QWindowSurface * windowSurface=0x0232ee28, BeginPaintInfo 
* beginPaintInfo=0x003ed77c)  Line 384
  QtGuid4.dll!QWidgetBackingStore::sync()  Line 1317
  QtGuid4.dll!QWidgetPrivate::syncBackingStore()  Line 1605
  QtGuid4.dll!QWidget::event(QEvent * event=0x0206a358)  Line 7833
  ...


So, does anyone have any idea why this is happening? Or how this can be 
solved?

Thank you for your time,

Best Regards
-- 
Ender EREL


Next episode on murky waters: "DirectX rendering as background of 
QGraphicsView." In multithreaded vision!



More information about the Qt-interest-old mailing list