Qt Threading Issues in Linux
Asked Answered
L

1

12

I have been developing with Qt for some time now on my project, and we are starting to move to a more thread-oriented design. Upon moving some GL rendering widgets to other threads I have discovered some very weird behavior. It appears that if a GL Widget begins updating from another thread (boost thread or QThread) before a widget that accepts user input (such as a QTextEdit) grabs focus, I get XCB crashes that look like:

[xcb] Too much data requested from _XRead
[xcb] This is most likely caused by a broken X extension library
[xcb] Aborting, sorry about that.
hypnotizer: ../../src/xcb_io.c:735: _XRead: Assertion ‘!xcb_xlib_too_much_data_requested’ failed.

To test this out, I actually can make a simple modification to the GLHypnotizer demo to reproduce the crash. That demo can be found here: http://qt-project.org/doc/qt-4.8/demos-glhypnotizer.html [qt-project.org]

If I add the line ‘mdiArea.addSubWindow(new QTextEdit(this));’ at around line 313 (before the call to newThread()), then when the demo starts there will be a QTextEdit and a GL Hypnotizer Widget. If I then click on the QTextEdit to grab focus I will get the above crash every time.

Can anyone reproduce the error on there Linux install using the above instructions? Has anyone encountered these types of issues on Linux using Qt and threading before?

Note: I am using Ubuntu 12 and this crash happens in VirtualBox and non VirtualBox Ubuntu installations

Latecomer answered 16/10, 2012 at 16:17 Comment(1)
Did you ever get a solution ?Sequin
G
2

OpenGL, Qt rendering and multithreading don't mix well. In particular a OpenGL context can be active in only one thread at a time. Now if the context is shared among multiple widgets (note that this different from sharing objects between contexts, I'm talking about a single context that's used for multiple windows/widgets which is legitimate) and those widgets render from different threads you're going to get into a lot of issues.

Usually the best course of action when it comes to OpenGL and multithreading is, not doing it. Use multiple threads, yes, but use them for everything that's not related to OpenGL or any kind of graphics output. Keep all graphics operations to a single thread to avoid major issues.

Gossipy answered 16/10, 2012 at 16:33 Comment(9)
Qt and multithreading don't mix well? Or is it OpenGL and multithreading that don't mix well?Seismism
@Chris: Oh, thank you, that was indeed a unintended typo. It's OpenGL that doesn't cope very well with multithreading. But Qt also has it's multithreading issues when it comes to rendering. So mixing Qt drawing functions, OpenGL and multithreading you've got a recipe for major headaches.Gossipy
The Qt demo linked looks like it's an official demo and thus "good code". More to the point, kelano said it works until a QT textedit widget is added, which I wouldn't think is OpenGL related. Also, it's an XCB error.Angiology
As the user above me pointed out, it crashes even with one single openGL thread running outside the Qt Thread, so I'm not certain it's an OpenGL from multiple threads problem.Latecomer
@kelano: Normally Qt does all it's rendering in a dedicated rendering thread. This thread also normally calls the drawing handler of QGLWidget or a descendant class. Now when a widget like QTextEdit receives focus it needs to reflect its state change visually, i.e. draw something; now it could happen that by having a OpenGL context bound in another thread and executing commands there this might break Qt or its usage of certain X extensions.Gossipy
@datenwolf: Ah, I never considered the possibility of the TextEdit on the main thread using an OpenGL context. If that's the case then I may have to rethink this structure. What still confuses me is how I can have upwards of 20 OpenGL QThreads working in the example without a hitch but the moment I click on that TextEdit it crashes..Latecomer
@kelano: This might very well be a Qt bug. But may I ask you: Why do you have 20 threads doing OpenGL? Only the most recent GPUs can actually to parallel OpenGL rendering, and not very performent. Better keep all OpenGL operations to one single thread, and maybe have one helper thread for data preparation.Gossipy
@datenwolf: In my own application there's one OpenGL dedicated rendering thread. However in the main Qt thread I have a QTextEdit that seems to cause problems, which I'm replicating in the demo. My reference to 20 threads was directed towards the Hypnotizer demo, in which I can have 20 GL threads running fine but the moment I touch a TextEdit it crashes. I'd imagine the GLThreads in the demo have some safety mechanism in place that the main thread isn't using (such as the makeCurrent call)Latecomer
Just to add in, here's the official Qt blog post claiming this is possible with a link to the demo: blog.qt.digia.com/2011/06/03/threaded-opengl-in-4-8Angiology

© 2022 - 2024 — McMap. All rights reserved.