JuliaGraphics / QML.jl

Build Qt6 QML interfaces for Julia programs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

JuliaDisplay flickers when updated too frequently

f-ij opened this issue · comments

I'm building an interface for a simulation. I'm using the ising display type to push a matrix of pixels to the QML interface. I'm doing this asynchronously, so I'm calling a function using Threads.@Spawn on a while loop that displays the matrix. If I do this more often than about 30 times a second, the display will flicker, disappearing for a short while intermittently.

I have tried to create a minimal example in threadedcanvas.jl and threadeddisplay.jl in the qt6 branch here: https://github.com/barche/QmlJuliaExamples/tree/qt6

Unfortunately, I couldn't really get it to work. The idea is that pushing to a display (or anything in QML) directly from a separate thread is not supported. In these examples, I try to keep the display on the main GUI thread, but for some reason both the "simulation" thread (which continuously grows and shrinks a circle) needs to yield after each update, even though I am running this with -t2 and I see 2 CPUs working. On Linux, the display example doesn't work at all, the canvas example (faster theoretically) works only with yield. Without yielding, I get the frezzing problem you mentioned in issue #142.

I'm afraid I don't understand Julia threads well enough to make any more progress on this.

This is now fixed in commit barche/QmlJuliaExamples@1056ec8

The main problem (at least in my example) was that I wasn't allocating anything in the "simulation" thread, and in that situation a call to GC.safepoint() must be inserted.

So the proper way to do this is to use the QML Timer, as done in threadedcanvas.jl and threadeddisplay.jl. Note that if you are displaying an image, the canvas approach is much faster. By calling a display or canvas render function from a QML Timer, you are making sure the update happens from the main thread. You can then experiment with the rate on the timer, slower machines may need longer intervals, the display example runs too slowly on my Mac and that makes the update stutter (display function takes longer than the timer interval).

Suggestion: Add an FAQ section to the documentation and explain the solution.