glXSwapBuffers blocks until new X-events are fired - multithreading

We have a really strange bug in our software. Call of glXSwapBuffers will block every now and then until some X-events are sent (mouse hovering over window/keyboard events). It seems that the bug is identical to Qt QGLWidget OpenGL rendering from thread blocks on swapBuffers() which was never properly solved. We have a same kind of situation.
In our application we create a multiple number of windows because our application needs to work with multiple screens. Each of our window is basically QWidget which has a class derived from QGLWidget as its only child. Each window has its own rendering thread attached which executes OpengGL-commands.
In this setting, application just halts every now and then. It continues normally if we feed X-events to it (moving the mouse over windows/push keyboard buttons). Based on the debugger info glXSwapBuffers() blocks somewhere inside the closed driver code.
We haven't confirmed this behaviour on NVidia cards, only with AMD-cards, and it is more likely to appear when using multiple AMD-cards. This suggests that the bug may come from the GPU-drivers.
I would like to know has any other bumped into this and has somebody even managed to solve this.

Related

Qt: Sometimes wheelEvent() is not called immediately when rotating the mouse wheel

I use Qt's wheelEvent to implement scrolling in a custom widget. Normally, this works fine.
However, when dragging the mouse and scrolling with the mouse wheel at the same time, it sometimes happens that rotating the mouse wheel by one step does not do anything at first (no wheelEvent is received). This might even randomly happen a few times successively. The next time the application does receive a wheelEvent, it comes with an accumulated event->angleDelta() of all previous events that were not reported separately. Apparently the events are buffered together in this case. Note that the wheelEvent may happen a long time after the initial mouse wheel rotation(s) in this case: it only happens once the wheel is rotated again.
This is an issue, since it means that my widget sometimes does not properly react to scrolling. Is there any way to avoid this kind of buffering and receive all wheel events immediately instead?
Notably this behavior is only well reproducible if at the same time dragging the mouse within the widget, which performs some non-trivial actions as a result. So I suspect it might happen if the event loop seems busy. But it certainly isn't busy enough to be unable to handle each wheelEvent. So I would like to disable this buffering.
I observe this on Linux with Qt 5.12.0. Any help is appreciated, thanks.
I am answering my own question here since I found the answer after writing it (but was unable to google it before).
The same problem has been reported here (with a somewhat non-descriptive title): Qt QOpenGLWidget wheelEvent strange behaviour
For me, setting Qt::AA_CompressHighFrequencyEvents (see https://doc.qt.io/qt-5/qt.html#ApplicationAttribute-enum) to false seems to have fixed the issue, as posted by #gatis paeglis as an answer to that question.

WebControl in a separate process stealing focus revisited

I need to process AJAX in my crawler and would prefer using system browser albeit I may have to change my mind. My crawler program may generally be working in background while the user can work on other stuff in other applications.
Anyhow - since WebControl leaks memory if processing JS libs that leak memory - this can cause a crawler to quickly run out of memory. (Many SO posts about this.)
So I have created a solution that uses a separate "dummy" small executable with the webcontrol that takes input/output. This is launched as a separate process by the crawler. This part seems to work great. This child process is created/destroyed as many times as needed.
However, this called process with the embedded-IE grabs focus on every page load (a least if e.g. JS code calls focus) which means if the user is doing work in e.g. Word or whatever - keyboard focus is lost.
I have already moved the embedded IE window off-screen, but I can not make it invisible in the traditional sense since then the embedded IE stops working.
I have tried to disable all parent controls before calling navigate - but it does not work for me.
Any ideas I have not tried? Maybe somehow catch a windows message that focuses webcontrol and ignore it? OR something so I can immediately refocus the earlier control that had focus?
I currently use Delphi - but this question is applicable to VB, C# .Net etc. from my earlier investigations on this matter. I will take a solution and ideas in any language.

WM_NCHITTEST and HTTRANSPARENT blocks input from message loop

We have a user definable "dashboard". It is possible to add several components into this window. Some windows are browser controls (ActiveX controls created with CLSID_WebBrowser). This browser controls can show content from different sources in the internal web.
To avoid blocking of the application each browser control is hosted in its own thread. Reason here was that the ActiveX Webbrowser control is hosted in an STA and only loads and shows data when message loop is running and this may block other parts of the UI.
So we have one parent window containing child windows of type list control, tree control, statics and group boxes, mixed with some browser controls. Except the browser control, all controls belong to the same UI thread. But the threads use one input queue and AttachThreadInput was executed for each thread to attach it to the main thread.
Now we face the following problem:
When the user designs his screen with a group box and a web control inside it. the application locks when the user moves the mouse over the browser control and clicks or uses the mouse wheel. The application locks and doesn't accept any further input. If you minimize the application and activates it again, you can work on and input is accepted again.
Reasons
With the debugger and spy++ we found out, that any mouse event causes WM_NCHITTEST to be sent to the group box. The group box returns HTTRANSPARENT. But the underlying window is of a different thread. We can see that an infinite loop occurs an WM_NCHITEST messages are fired to the group box and the input is blocked until this loop gets interrupted (minimizing by showing the desktop).
We can read in the documentation that WM_NCHITTEST and HTTRANSPARENT are limited to windows of the same thread. And I can find 2 other article in the net that describe the same or similar problem.
The simple solution
The simple solution is just to take care that the browser controls are never covered by a group box or static control. So changing the Z-order is simple and works (groupbox must follow the windows of the different thread in Z-order)
Question
I would be interested if there is another way to get around this problem. Or if there is a way to prevent such input queue deadlocks. Or if somebody knows what is happening internally when this WM_NCHITTEST must handle windows from different threads.

Why does deletion of vtkpolydatamapper cause an infinite loop in vtkclearopenglerrors?

We have a WinForms c++/cli CAD based application that uses VTK 6.1. One of the application's features is playing a script which plays back operations the user had previously done interactively. We pop a modal progress form while the script is playing and do the non-ui work of the script in a background thread. Part of the work of the background thread is creating and deleting vtkPolyDataMappers. While the background thread is going and the progress form is showing we need to update a display in the main thread by calling vtkWin32RenderWindowInteractor::Render().
We have a timer setup so Render is called every few hundred milliseconds at most in a UserControl::OnPaint event handler. This allows the view to update while the script is playing giving the user feedback.
This used to work in VTK 5. But now an infinite loop happens upon deletion of a vtkPolyDataMapper in the background thread. The infinite loop is in vtkClearOpenGLErrors:
void vtkClearOpenGLErrors()
{
while (glGetError()!=GL_NO_ERROR){;}
}
Inside the vtkpolydatamapper is a vtkOpenGLDisplayListPainter. When this gets deleted by vtkGarbageCollectorImpl::CollectInternal we get stuck in vtkClearOpenGLErrors.
Does anyone have experience with VTK and threading that could help? Do you know anything about this? It's only an apparent problem in VTK 6.1. Is it illegal to have the main UI thread calling Render on a vtkWin32RenderWindowInteractor while a background thread is doing deletes on a vtkPolyDataMapper? It isn't a timing issue. I think it might be an OpenGL context issue but not sure how to fix it. The problem does go away if we avoid calling Render on the display while the background thread is going but we'd like to give the user feedback while the script is playing.
We fixed the problem by recompiling VTK with
VTK_REPORT_OPENGL_ERRORS
turned off.

Qt GUI non responsive on Windows XP

I have a Qt application which gets serial data and displays is in a dashboard type GUI. The basic structure of the program is as follows:
EDIT
SerialPort (Inherits from QIODevice) object get created and have their readyRead signals connected to a slot.
When new data comes in, it's interpreted and sent through the program via a message handler. Eventually the data makes its way to a GUI layer, where it is displayed to the user.
The program runs fine in windows 7, however when I run it on a Panasonic toughbook, running windows XP, the program starts off fine, but after a few moments the GUI stops updating. What I mean by this is that when new data comes in, the gui won't redraw until a user clicks a button or resizes. I'm wondering what are some possible reasons for this type of behavior. I thought it could be that the Main thread was getting overwhelmed by all the serial data coming in, but I think that the GUI runs in a separate thread anyways. Am I wrong? Does anyone have any ideas as to what could be happening?
If SerialPortIO isn't in its own thread, then it might be blocking when it is waiting for new data. I haven't used that particular Serial class, but in general a stream of data probably should be in its own thread.
You can force the program to update the GUI more, by calling qApp->processEvents() periodically, and the GUI should update.
Also, put some qDebug statements in your code, especially at the top of your functions that you suspect that are getting called too frequently or not enough.
Use the following line, and it makes it really easy to follow what is happening in a multithreaded application:
qDebug() << Q_FUNC_INFO;
Hope that helps.

Resources