OK, I needed a diversion from serious work and was intrigued to find out how 
practical it is to animate many instances of an analogue meter and how far you 
can go with the standard view update mechanism. Think of it as putting my money 
where my mouth is. I claimed it should be possible to get smooth animation 
using the standard mechanism if you are careful and play by the rules.

So, here's an app project that attempts to do that.

http://apptree.net/code/LED3.zip

I hope this is reasonably realistic for your particular situation. I have two 
windows, one which has a bargraph display somewhat like a spectrum analyser and 
2 large VU meters, and a second which has 36 smaller instances of the same VU 
meters. Each of these is an autonomous view, and entirely looks after its own 
simulation, including the meter ballistics by simulating a RC circuit. These 
are all animated using a common timer instance running at 30 frames per second. 
You can opt to set the VU view to be layer backed as well if you want - the 
four instances on the far left are layer backed and the layer transform is 
additionally animated. To turn this on, just check the layer backing checkbox 
in IB - another motivation for this was to get some more experience of using 
Core Animation - but note that overall I'm not using Core Animation to perform 
the majority of the animation you see, just a standard timer which updates the 
view periodically using the standard update mechanism. No threads, no smoke and 
mirrors.

I measured the drawing time for rendering a single VU meter (large) and it 
settled down to an average of about 220 µS. This is on my fairly up to date mid 
range Mac - a 27" iMac with 3.2 GHz i3 CPU and ATI Radeon 5670 graphics, 64-bit 
debugging build. So, your mileage will vary. But at 220µS, I have time to 
render about 75 instances of the meter in the 16.7mS timeslot available at 60 
fps (though I animate these at only 30 fps which seems adequate for fluid 
movement). The image used to draw the meter background is a PDF and it does not 
seem to cache this within the NSImage in another form - whether there is some 
other caching going on behind the scenes I don't know, but the same image is 
used for all instances, scaled to fit. I also used a common timer for all 
instances; that did seem to make a difference - having one timer per instance 
was slower, with a noticeable slowing of the apparent framerate.

Is it good enough? I don't know. Maybe 36 instances is far fewer than you have 
- you can easily add more by simply duplicating them in IB. Maybe your hardware 
is much slower, and of course, this app is not doing anything else in between 
frames except going to sleep. A real audio processing app would have much more 
work to do, but in theory it should have plenty of time to do it.

Well, it might give you some starting point or something to compare against. 
Anyway, it was fun :)

--Graham




On 15/06/2011, at 11:42 PM, Wolfgang Kundrus wrote:

> Thanks for taking the time to respond. I am certainly not a newbie, being a 
> Mac programmer since 1987 having brought three major applications with 
> millions of customers to market that all run cross platform. 
> 
> That aside, I am trying to understand, why Cocoa does not flush the graphics, 
> if there has been drawn something to the window with the a method that works 
> well otherwise. I understand coalescing updates and I want to stay away from 
> CGContextFlush as this would cause the application to block, if another flush 
> has to happen.
> 
> We do use the invalidate/draw wherever appropriate. In this specific base, 
> invalidate does not help, because it is not a simple redraw operation, but 
> rather moving an object by a few pixel without tearing. The other case where 
> we use direct drawing is the potentially hundreds of meter object that need 
> to be updated in a very specific way at a rate that is perceived as fluent.
> 
> All the best
> 
> Wolfgang
> 
> 
> 2011/6/15 Graham Cox <graham....@bigpond.com>
> 
> On 15/06/2011, at 10:30 PM, Wolfgang Kundrus wrote:
> 
> > We have to update a lot of small onscreen objects and performance is way 
> > better, when we travers them outside the Cocoa view tree. If we would use 
> > invalidating, we would have to go thru our complete view tree and check for 
> > overlaps with the update rect.
> >
> 
> Does each object have its own view? If so, then that's definitely not a good 
> idea. If not, then there really shouldn't be a problem  - checking for 
> overlap with the update rect is a simple matter of a) invalidating the update 
> rect(s) and b) at DRAW time, call [NSView needsToDrawRect:] to test for 
> overlap. Invariably it is drawing that dominates performance for this type of 
> scenario, so a simple YES/NO test of this type is well worthwhile and is very 
> fast.
> 
> If you have, say < 1000 objects that need updating, a linear list of these 
> will probably suffice on a modern machine. If you have more, a spatial 
> hashing scheme such as BSP can give useful improvements, and NSView has the 
> method -getRectsBeingDrawn:count: that can be used as an input to a spatial 
> hash. I use this technique in DrawKit, and unless the objects are especially 
> complex in what they draw, it's easy to achieve a refresh of many thousands 
> of objects within 16mS (which equates to 60fps).
> 
> If you have found performance to be bad using Cocoa's drawing mechanism, I 
> suggest you must have overlooked something or made a newbie error such as 1 
> view per object, because in my experience it is adequate in terms of 
> scheduling the updates and testing for objects needing to be drawn. Cocoa 
> caps the framerate at 60fps anyway so you will never do better than that, but 
> it sounds like you're way off base, so there's a long way to go before giving 
> up on the standard mechanism.
> 
> --Graham

_______________________________________________

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