[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