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

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.

Related

Scala 3 with ScalaFX thread related problem

I have an application that has multiple screens and a process that needs to get UI info from some and update others.
Tried many methods but the result always is always "not a Java FX thread". Without using some kind of thread the UI does not update Because of the multi screen nature of the app (not practical to change) I need to fundamentally change the application architecture which is why I am not posting any code - its all going to change.
What I cant work out is the best way to do this and as any changes are likely to require substantial work I am reluctant to try something that has little chance of success.
I know about Platform.runLater and tried adding that to the updates but that was complex and did not seem to be effective.
I do have the code on GitHub - its a personal leaning project that started in Scala 2 but if you have an interest in learning or pointing out my errors I can provide access.
Hope you have enjoyed a wonderful Christmas.
PS just make the repo public https://github.com/udsl/Processor6502
The problem is not that the Platform.runLater was not working its because the process is being called form a loop in a thread and without a yield the JavaFX thread never gets an opportunity to run. It just appeared to be failing – again I fall foul of an assumption.
The thread calls a method from within a loop which terminates on a condition set by the method.
The process is planned to emulate the execution of 6502 processor instructions in 2 modes run and run-slow, run-slow is run with a short delay after each instruction execution.
The updates are to the main screen the PC, status flags and register contents. The run (debug) screen gets the current instruction display updated and other items will be added. In the future.
The BRK instruction with a zero-byte following is captures and set the execution mode to single-step essentially being a break point though in the future it will be possible via the debug screen to set a breakpoint and for the execution of the breakpoint to restore the original contents. This is to enable the debugging of a future hardware item – time and finances permitting – it’s a hobby after all 😊
It terns out that the JavaFX thread issue only happens when a FX control is written to but not when read from. Placing all reads and writes in a Platform.runLater was too complex which is why I was originally searching for an alternative solution but now only needed it protect the writes is much less a hassle.
In the process loop calling Thread.’yield’() enables the code in the Platform.runLater blocks to be executed on the JavaFX thread so the UI updates without an exception.
The code in the Run method:
val thread = new Thread {
override def run =
while runMode == RunMode.Running || runMode == RunMode.RunningSlow do
executeIns
Thread.`yield`()
if runMode == RunMode.RunningSlow then
Thread.sleep(50) // slow the loop down a bit
}
thread.start
Note that because yield is a Scala reserved word needs to quote it!

No OpenGL context found in the current thread

I am using LibGDX to make a game. I want to simultaneously load/unload assets on the fly as needed. However, waiting for assets to load in the main thread causes lag. In order to remedy this, I've created a background thread that monitors which assets need to be loaded (textures, sounds, etc.) and loads/unloads them appropriately.
Unfortunately, I get the following error when calling AssetManager.update() from that thread.
com.badlogic.gdx.utils.GdxRuntimeException: java.lang.RuntimeException: No OpenGL context found in the current thread.
I've tried runing the background thread in the main thread in the beginning and just dealing with the first few screens, and everything works fine. I can also change the algorithm to just load everything into memory from the start in the same thread, and that works as well. However, neither works in the background thread.
When I run this on Android with OpenGL ES 2.0 (which is flexible in odd ways) instead of on Windows, everything runs fine, and I can even get the pixel dimensions of the images - but the textures render black.
My searches have told me that this is an issue of the OpenGL context being bound to a single thread, but not much else. This explains why everything works when I shove it in the main thread, and not when I put it in a different one. How do I fix this context problem?
First things first, you should not access the OpenGL context outside of the rendering thread.
I assume you have looked at these already, but just to make sure read up on the AssetManager wiki article, which talks a bit about how to use the AssetManager for asynchronous managing of assets. In addition to the wiki article, check out the AssetManagerTest to better understand how to use it. The asset manager test is probably your best bet into loading at how to dynamically load assets.
If you are loading a ton of stuff, you may want to look into creating a loading bar to load anything large upfront. It might work to check assets and such from another thread (and set a flag to call update), but at the end of the day you will need to call update() on the rendering thread.
Keeping in mind you have to call update() it from a different thread, I don't see why you would want another thread to check conditions and set a flag. There is probably more overhead using another thread and synchronizing the update() call than to just do it all on the rendering thread. Also, the update() method only pauses for a couple milliseconds at a time as it incrementally loads files. Typically, you would simply call load() for your asset, then check isLoaded() on your asset. If it isn't loaded you would then call update() once per frame until isLoaded() returns true. Once it returns true, you can then call get() and get whatever asset you were loading. This can all be done via the main rendering thread without having the app lag while its loading.
If you really want your other thread to call update(), you need to create a Runnable object and call postRunnable() such as how they have it described in the wiki article on multi-threading with libGDX. However, this defeats the whole point of using other threads because anything you use with postRunnable runs synchronously on the rendering thread.

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.

glXSwapBuffers blocks until new X-events are fired

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.

Delphi 6 : breakpoint triggered on non-VCL thread stops main thread repaints

I have a multi-threaded Delphi 6 Pro application that I am currently working on heavily. If I set a breakpoint on any code that runs in the context of the Main thread (VCL thread) I don't have any problems. However, if a breakpoint is triggered on any code in one of my other threads, after I continue the application from the breakpoint, all repaints to the VCL components on the main thread (including the main form) don't happen anymore. The application isn't dead because other background code keeps running, just the main thread. It's as if the windows message dispatcher has been corrupted or rendered dormant.
Note, in this application I allocate my own WndProc() via allocateHwnd() on the main form because I need to catch certain registered messages. From that WndProc() I dispatch any custom messages I handle and if the current message is not handled by my code, I pass the message on by calling the main form's inherited WndProc(). If I do handle the current message I simply return from my WndProc() with Msg.Result set to 1 to tell the dispatcher that the message was handled. I can't simply override the TForm WndProc() instead of allocating my own WndProc() because for some reason the Delphi VCL does not pass through registered messages instantiated with the Windows API RegisterWindowMessage() call.
Has anybody experienced this in similar context and if so, what did you do to fix it?
-- roscherl
Since you call AllocateHWnd, that means you've created another window. You mustn't just take the messages that were addressed to that window and forward them to your form's window. Doing that, you're bound to screw things up in your program, although I'm not sure exactly how. Painting problems sound plausible. You should make sure it's really just painting problems and not that your main thread is still suspended. The debugger should be able to tell you that. (You should call DefWindowProc to make your allocated window handle messages you're not prepared to handle yourself. And returning 1 doesn't tell the dispatcher anything; the dispatcher doesn't care β€” whoever called SendMessage wants to know the result.)
I promise you that forms are completely capable of receiving registered window messages. Override WndProc or assign a new value to the WindowProc property (and remember to save the old value so you can call it after handling your own messages). The source of your problem lies elsewhere.
UPDATE: I'm not saying the way I got past the problem is a good solution. I need to take Rob Kennedy's notes and do some refactoring. However, to get past the problem for now I gave the thread it's own Window and WndProc() and at the top of the thread Execute loop I have a PeekMessage() while loop with calls to TranslateMessage() and DispatchMessage(). I no longer have a problem with setting breakpoints in the thread, but obviously this compounding of WndProc() methods indicates a structural problem in my code. I wanted to add this reply to fill out the discussion. I'm hoping that once I put Rob's suggestions to work when I clean up my WndProc() methods on the relevant forms, especially the main form, I can get rid of the this new WndProc() that I just added to the thread.
Robert.

Resources