Most efficient run/rendering loop/thread

Posts: 4
Joined: 2008.11
Post: #1
I've seen a few posts previously on these forums about rendering in an another thread. Currently I am using an NSTimer for my update loop which isn't great.

Now the iPhone is a single process machine for the most part so I can't believe starting another thread for rendering is the most efficient way to handle this - plus surely making the call to set the OpenGL context from another thread takes some time also under the hood.

Now I have also had a brief dig into SDL1.3 for the iPhone ( which seems like it maybe does what we really want by taking control of the 'message pump' of the program? My Mac/Linux/iPhone knowledge isn't great enough to understand exactly what its doing but does it have something to do with:

do {
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE);
} while(result == kCFRunLoopRunHandledSource);


What I think we really want is a situation where we can write a tight loop in the main thread that is:

ProcessPhoneEvents(); //Yield time to phone UI etc
Sleep(N); //Yield time to OS

I'm not sure where this is hidden currently in an IPhone application as it stands?

Then in RunGame() I update my game, do OpenGL drawing, stream music all in a fine tuned amount of time.

Spawning additional threads seems a bad inefficient idea for such a platform? Although it does seem it is better then using an NSTimer!
Quote this message in a reply
Posts: 869
Joined: 2003.01
Post: #2
You don't "yield", the iPhone has preemptive threads. The OS schedules things as it sees fit, and having an event-driven (as opposed to a polling) user interface is provably the better way to avoid nasty things happening, such as priority inversion.

And just because the iPhone has a single CPU, it doesn't mean that a single threaded app will be the most efficient. Threads can block, waiting on IO devices or the kernel, and while they do block, another thread can execute, thus better utilising the CPU.

If a multi or single threaded app is more efficient depends on many factors, not in the least how the threads (YOUR code) interact. And this seems to be the point that people don't usually get, that just because they've created a 2nd thread, things don't suddenly become faster.

And as far as OpenGL goes, it doesn't care a single bit if you use it from the main or another thread, as long as things are set up correctly.
Quote this message in a reply
Posts: 1,234
Joined: 2002.10
Post: #3
You do need to heed the usual warnings about ensuring that your GL context is only used from a single thread at a time. Else, death and doom await.

For example, on the desktop, if you spin your NSOpenGL rendering into a second thread, you need to be aware that the main thread will still occasionally call -drawRect (like, when you move or minimize the window) and if you haven't properly locked around these events, sooner or later you will have a corrupt command stream.
Quote this message in a reply
Posts: 93
Joined: 2008.11
Post: #4
iPhoneGG Wrote:do {
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE);
} while(result == kCFRunLoopRunHandledSource);


This code will just loop till the result is some other value than HandledSource. These are Finished, Stopped and TimedOut. You can add/remove sources on the run loop and these will be executed... there are also some timers inside the run loop implementation. Anyway in my project I made a simple runloop implementation with sources on priority basis and things work pretty much the same except that my things are simplified a lot and thus I would expect them to run a little faster.

Btw, CFRunLoopRunInMode will control the CFRunLoop object for the current thread. So threads are surely not bad for iPhone applications.
Quote this message in a reply
Posts: 4
Joined: 2008.11
Post: #5
I don't see the iPhone as beefy enough to justify another rendering thread (Especially from experience of writing multithreaded renderering engines on the PC and 360). I don't think threads are bad on the iPhone - it just seems overkill that other people have been spawing them for rendering loops to get away from using a timer as the sdk apps do - where it seems it should be more efficient to construct a better run loop in the main thread (not using timers). I can imagine just spawning another thread to handle music streaming etc.

So to continue what godexsoft said how would I set things up so my update loop can run on my main thread? As I want to eradicate the route taken by the NSTimer samples in the SDK?

I add my own high priority run loop object or something? (Apologies on being new to these platforms).

Quote this message in a reply
Posts: 93
Joined: 2008.11
Post: #6
If you don't care about multithreading you can use the CFRunLoop on the main thread and push sources which can a) update logic b) render stuff.

To play music/effects you can use the SoundEngine.cpp class which can be found in the CrashLanding example code.. i use it and it works very well.. plus it's already automatically in a separate thread.

Your input should be handled using the standard touchesBegan/Moved/Ended messages on your GL view.. of course you can dispatch your inputs to all subscribers (what i do now).

That's pretty much it I guess.. the rest depends on you and how you prefer it to be done. Keeping rendering in the main thread (using run loop) may result to animation jumps from what i have seen in my game when it was like that.. however doing all gl stuff in the main thread is definitely simpler to maintain.

Good luck!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  emulator slow when rendering from a second thread captainfreedom 1 4,421 Jan 30, 2010 05:05 PM
Last Post: ChrisD
  OpenGL render loop - NSTimer vs rendering thread smallstepforman 27 35,675 Feb 2, 2009 10:22 AM
Last Post: ThemsAllTook
  More about rendering in separate thread godexsoft 5 6,099 Dec 1, 2008 03:32 AM
Last Post: godexsoft