Please hear my plea to create a method to override the ThreadAccessingUIException within Xojo.
There have been many good discussions for issues when using a thread and updating Xojo controls which cause crashes and is generally not a good thing to do, and I am in complete agreement.
The exception occurs when programming a game/graphical industrial application where the only control is either a Canvas or OpenGLSurface. An option is to just use a timer with a thread. This works well on OSX and Linux, and there is a known timing issue with Windows (Limitation on Microsoft Windows. This means that the fastest speed would be 66 frames per second (1,000 milliseconds/15 milliseconds=66). This frame rate is perfectly fine for very small programs that have very little and uncomplicated formulas. As soon as the program scope increases (LOL, I think we have all had our stories of scope creep), then some calculations can take 15 milliseconds. This decreases the framerate down to (1,000 milliseconds/30 milliseconds=33) 33. Another heavy calculation would further decrease this framerate which causes flickering and pausing of perceived graphical movement.
My plea is to as Xojo to create a #Pragma DisableThreadAccessingUIException or some other way for professional programmers to use the full speed and features of Xojo for graphical programming, while also knowing that a #Pragma is overriding actions and warnings as stated in the Pragma Directives.
Within the directives the beginning paragraph states:
Used to suspend and/or override actions to improve code execution times, issue warnings or error messages, and change/modify other normal operations.
My interpretation (albeit biased) is that when a #Pragma directive is issued then the responsibility for an unstable program then rests on the programmer.
The reason for my request is that programming graphical apps on Windows has reached a point where the timer:thread pair is not quick enough and has poor quality on medium to larger applications. With the Xojo limitation on the timer within the Windows OS, then implementation of graphics is limited to turn-based programs and less complicated coding.
Maybe Xojo has an option to this issue that I am unaware. Until there is another option, then my request is to add a mechanism to override the ThreadAccessingUIException error with #Pragma DisableThreadAccessingUIException or some other mechanism.
You of course realize that the inability to draw to the UI from a non-main thread is not one we impose ?
It’s imposed on us by ALL UI toolkits
We dont have any magic way to make what is restricted at the OS UI toolkit layer suddenly legal
Sorry, didn’t realize that Norman. Thanks for your reply.
Its kind of sucky but it is reality
And I get why making a ui toolkit that is thread safe is really hard since you dont know at what point some thread is going to try & draw etc etc
That said IF you create one picture or surface & have several threads draw to that then only have one timer to flush that surface / picture to the screen as fast as possible you should be able to get higher frame rates
LOL, I understand. I am not familiar with the internal workings, and it sure would be nice to be able to increase the performance somehow.
Yes, this makes complete sense. Having multiple threads can definitely have a program get into a large amount of trouble very quickly when part of the code in a method has been executed, memory has only some data written and read, are partially drawn.
This makes sense when the timer is able to refresh quickly.
As background information, because many stumble upon this and see it as a limitation caused by Xojo (from the Mac point of view, but I think other systems must be quite similar): In Carbon days, it was completely fine to change the UI from a thread because there was no real multi-threading: Carbon used a time-slice model to give each thread time where it could execute, so you could be quite sure about the state of an UI object.
With the advance of real multi-core and parallel CPUs, Apple restricted access to the UI to only the main thread, because otherwise you couldnt be sure about the current state of the UI when multiple threads tried to change it simultaneously. Just like any other exception: In theory, you could try to continue with your algorithm. But because you cannot be sure it is based on a valid fundament it could take your code anywhere, which isnt a good idea, even more in Internet and virus/exploit times.
Edit: Norman beat it to me. Sorry for redundancies!
[quote=295516:@Ulrich Bogun]As background information, because many stumble upon this and see it as a limitation caused by Xojo (from the Mac point of view, but I think other systems must be quite similar): In Carbon days, it was completely fine to change the UI from a thread because there was no real multi-threading: Carbon used a time-slice model to give each thread time where it could execute, so you could be quite sure about the state of an UI object.
It just happened to NOT cause your program to crash quite as often. It was still possible to get your program to crash though
And much of that was due to the cooperative threading of the OS (but even then there were ways to write preemptive code and man could you ever get things to die)
The Vertical Retrace Interrupt comes to mind
[quote=295517:@Norman Palardy]It wasn’t
It just happened to NOT cause your program to crash quite as often. It was still possible to get your program to crash though[/quote]
Even more that I knew, but generally what I tried to say; You may come out lucky, but (at least from a programmer’s point of view) its no good idea to rely on luck. Thanks, Norman!
EDIT: That was what came to my mind while I was writing my statement: If the system time-sliced the execution, how on Earth could you be certain about the state of an UI object when another thread took command in between? O hell!
If you google for something like “why are UI toolkits not thread safe” you get some very interesting reading across many ui toolkits and platforms
Sounds to me like you need to separate the logic from the drawing somehow.
Is it possible to use a thread to update the geometry and such, while the timer only refreshes the portal?
][quote=295530:@Sam Rowlands]Sounds to me like you need to separate the logic from the drawing somehow.Is it possible to use a thread to update the geometry and such, while the timer only refreshes the portal?[/quote]
Yes, I have performed much of the calculations and placed as much as possible into the computers memory to be only pushed to the memory card by a few commands that take very little time. Below is a teaser video of one of the OpenGL games, Tetris.
LOL, I am not a good player, but the program works well. When a simple program such as the OpenGL example that is with Xojo runs (Examples\Graphics and Multimedia\OpenGL\FluidsDemo.xojo_binary_project), there is a pause which almost looks like a heartbeat. On OSX this is not as large of a studder. When more complicated graphics are used then this studder becomes more noticeable. A great deal of optimization is needed to minimize this pause which makes the graphics not smooth or fluid-like.
Thanks for the great suggestions Sam, and if there is a solution out there, then I am more than willing to listen
Edit: Tetris has a timer:timer pair, and most examples have been optimized to perform the math in a thread, and update graphics in the timer.
Didi quickly run this OpenGL example, and I don’t see the delay when clicking around on the “fluids”. Tested it on an iMac (2008), a MacBook Pro 17" (2012), and don’t laugh a Digital HiNote Ultra 2000 from 1998 with Windows XP (I compiled the example with Xojo 2014).
If you make the window resizable then you get a pause each time you resize it maybe you mean this?
Thanks for running the OpenGL demo program on a few of your computers. The pause I am mentioning is when the program is running without resizing, On a mac the small white moving particles continue moving in a slow-fast-slow motion.
I used your good idea and tried this on a few different computers. With Windows OS I tried this on Surface book, surface pro I, a newer fast ASUS computer(really bad on ASUS), and a Lenovo, and all had the studder. On Mac I used a newer mac mini, and dusted off an old mac mini (Used to be a snow leopard server in 2009 with dual drives and now has yosemite) and installed Xojo 2016 r3 on it and it was also running smooth (no studder) with the fluid program.
One way that I can describe the studder is to look at a segment of the program over a 1-second time period. It seems that the program moves the particles at regular speed for 0.4 seconds, stops for 0.1 seconds, moves at regular speed again for 0.4 seconds, stops another 0.1 seconds, etc. There was no resizing or touching of the keyboard. I’ll try and take a video to show you what I mean…
Thanks for taking the time to try it on a few computers.
Here is a video of the studder on a 24 GB ASUS with an added 4GB of video card memory. This recording was taken from the laptop, and there are no external programs running or external screens.
Watch the white particles speed up and slow down.
Another way that it seems (which may be completely incorrect) is that the program is running and fills the graphics pipe at a slower rate than the computer is able to draw the graphics. The computer seems to be waiting for more bits and bytes to draw and when the graphics pipeline is partially full the graphics card draws it all at once (speeds up) and then waits for the next bits and bytes to enter the pipeline (pauses/delays).
This may explain why the graphics seem to look smooth on the old WIndows XP computer that the program was running, but it seems to studder on faster machines.
Just a guess…
Here are some test results for running the http://www.mediafire.com/file/qpfg6sf7wy7x7rl/GLSpeedTest.xojo_binary_project program which refreshes the drawing rate as fast as possible through a thread and only uses the timer to show the frames per second.
WARNING - DO NOT USE THREADS FOR REFRESHING OPENGL - THIS IS A TEST ONLY
The below computers had Xojo 2016 r3 installed and two measurements were made: 1) without mouse movement, 2) with mouse movement. Mouse movement was simply taking the cursor and rapidly moving it back-and-forth over the OpenGLSurface control while running. fps = frames per second
Computer No Mouse Movement (fps) Mouse Movement (fps)
Surface Book 1700-1900 2500-2800
Mac Mini (Late 2009) 50-61 56-61
Mac Mini (Late 2012) 60 61
ASUS 1000-2300 3100-3300
Surface Pro I 900-1400 1300-1500
There seems to be quite a difference between speeds.
Do I read correctly that you actually get more frames per second when the mouse is jiggled ? Then you need to figure a way to jiggle it by code
Maybe Microsoft computers have ‘soul’ and need a little jiggling to be more stable
If your screen has a 5msec refresh speed anything above 200 FPS is wasted as it will be generated and never drawn to the screen
A quick google suggests the refresh rate of the built in display on a Surface is about 60hz so drawing faster than 60 frames a second it again pointless
I used to work with a fellow who claimed he could detect differences in the animations when FPS was > 120
So we did a test using his own code and no he couldn’t when it went over the refresh rate of the monitor (not surprisingly)