I have an application which does some simulation, and renders the result. Because the render can sometimes be very slow, I separated it into another thread, and the main thread calls gtk_widget_queue_draw once it's ready. If it's not finished drawing yet, the extra requests get discarded (since queue_draw only invalidates it, and it's impossible to be "more" invalid).
The result is that with large complicated systems, simulation maxes out a thread, and render maxes out another thread, and everything works.
I just ran into a different problem, and I don't see why it's happening: A sufficiently simple simulation and render (6 5-point lines) causes it to break.
The first few (I've seen everywhere from around 60 to 400) steps render fine (in a fraction of a second), until one step renders twice. After that, it ignores the queue_draw, until I do something like drag a window over the render window, after which it restarts (until it breaks again).
If I artificially slow down the requests (usleep(10000) is around enough), this does not happen.
This is a completely unacceptable solution however, because the process of displaying is not allowed to interfere with the normal simulation thread (No delays, no mutexes, etc. etc.). I need a solution that makes the render thread do "as well as possible", given that it is working with volatile data. It does not have to be perfectly accurate--I really don't care if a frame renders a little wrong (half of frame i, half of i+1 is fine), as long as it does render.
Why is this happening, and how do I fix it?
You are having a race condition.
Since GTK3.6, you need to call gtk_widget_queue_draw like this:
g_idle_add((GSourceFunc)gtk_widget_queue_draw,(void*)window);
or like this:
gdk_threads_add_idle((GSourceFunc)gtk_widget_queue_draw,(void*)window);
where window is the GtkWidget* you want to draw.
Use the gdk_threads_add_idle if you're not sure whether libraries or code used by your app use the deprecated (since 3.6) gdk_threads_enter and gdk_threads_leave functions.
See: https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk3-Threads.description
Before GTK3.6, gdk_threads_enter and gdk_threads_leave had to be used to acquire the lock for GTK calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With