Let me shortly describe the current situation: We have a window and inside this 
window is a layer-hosting NSView. This view is supposed to permanently display 
a never ending OpenGL animation. Why did we use CALayers for that? For no 
specific reason, it just sounded like starting with 10.5 CALayers is the way to 
go and maybe one day we also want to make use of CALayer animation 
capabilities, so why not? So we did as Apple told us: Subclass CAOpenGLLayer 
and override the appropriate methods. To not overload the main thread, all 
calculations are performed on a background thread, that updates all necessary 
parameters of our CALayer, when done, it waits some time (to avoid the 
animation is running too fast) and finally updates the content of the CALayer 
by calling setNeedsDisplay on main thread (performSelectorOnMainThread). This 
works pretty well, we are quite happy with the results.

Now to our problem: If the main thread is blocking for a short while or 
temporarily not running its runloop, which can happen for various reasons, the 
animation starts to "stutter". It doesn't even have to block for a very long 
amount of time, it only needs to block longer than the time difference between 
two animation updates. This is by far not long enough to get a spinning mouse 
cursor for this application. We try to do everything asynchronously and never 
block the main thread for one millisecond longer than absolutely necessary, but 
nonetheless only reacting to all kind of user input can sometimes make the 
animation less smooth than we would like it to be. Of course that is expected, 
because without the main loop performing the CALayer update, no update will 
happen and when the next update is performed, any number of animation frames 
might have been skipped.

What we want is that this animation is always smooth, no matter how busy the 
main thread might be. Even if it blocks for a whole second it should be smooth, 
at least as long as the CPU has enough resources to keep the animation updating 
on time (otherwise there is no way to avoid that frames are skipped, but if the 
system is at its limits, that is absolutely okay). With normal NSViews, you can 
also perform updates from background threads, as far as I understand the 
documentation, by directly locking focus from the background thread 
(lockFocusIfCanDraw), directly drawing to the view and unlocking focus again. 
There seems no way to lock focus for a CALayer and no way to paint into and 
thus update the content of a CALayer from any other thread, but the main thread.

So what are we supposed to do? Is there something I'm overlooking here or 
should we maybe stop using CALayers and instead use NSOpenGLView or maybe even 
manage our own OpenGL Context, render into a background buffer (e.g. some kind 
of image) and then directly paint this image from within the background thread 
into the view whenever we want to? If so, what image is most effective for such 
a task? NSImage, CGImage, CIImage? Any advise is highly appreciated.

-- 
Markus Hanauska
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to