Hi Graham, thanks for taking the time to put this together and I am glad to hear, you enjoyed it. Very nice graphics.
In the mean time I have also experimented with this approach, and I believe this is the right thing to do. Also, there was some misconception on my end of what is going on behind the scenes, that i understand better now. It does not help though to consider the potential blocking of the application when using CGContextFlush as design flaw. All the best Wolfgang 2011/6/24 Graham Cox <[email protected]> > 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 <[email protected]> > >> >> 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 >> > > -- Managing Director PreSonus Software Limited Bramfelder Straße 76 22305 Hamburg, Germany Phone: +49 (0) 40 - 69 70 49 32 Direct line: +49 (0) 40 - 69 70 52 45 Fax: +49 (0) 40 - 69 70 49 33 Web: www.presonussoftware.com _______________________________________________ Cocoa-dev mailing list ([email protected]) 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 [email protected]
