Re: Coalesced updates and refresh rate
Re: Coalesced updates and refresh rate
- Subject: Re: Coalesced updates and refresh rate
- From: Graham Cox <email@hidden>
- Date: Thu, 16 Jun 2011 00:20:47 +1000
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.
Cool. I wasn't calling into question your experience however, since you have not given any clue as to what you're actually trying to do, I've stuck to the obvious generalities.
The bottom line is, forcing updates to graphics in the way you implied has never ever been necessary in my own experience. That said, while I do deal in many thousands of objects, most of them don't need to be repeatedly redrawn - that's the point of doing all the spatial hashing, etc - the fastest drawing is no drawing. If every single object must be updated at every frame, that isn't going to help you.
> 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.
You need to tell it that you drew something there, so it performs the flush at the end of the event cycle.
>
> 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.
So, perhaps a music app?
Have you tried compositing the entire thing off-screen to an image and drawing it all at once using the standard update? If there really is motion everywhere in your view then just doing a one-time dump of the entire thing might be the way to go? That is pretty much what the standard mechanism is trying to do - all the drawing is done to the window's backbuffer which is flushed in one go (clipped to the update region) at the end of every event cycle. But for the flush to happen you need to call -setNeedsDisplayInRect: for the updated areas, even if you draw outside of drawRect: Then whatever you draw into the backbuffer for that area gets flushed, once, capped to 60fps. If you are only getting updates when the mouse moves, it sounds like you're not doing the invalidating, so the flushing is not being performed because the view has no idea that it needs to update anything.
For objects that move, you need to flush both the old and the new areas. There's no getting around it. I'm certain that simple invalidation is the way to go, as the update regions are coalesced automatically both in space and in time. It's very doubtful you can do better. And given that, you may as well do the drawing in drawRect:, since forcing drawing is not going to make anything happen any faster. In fact, forcing a flush not only kills performance as you've seen, but is likely to promote tearing since it's not waiting for a complete frame to be rendered.
Another idea: if each meter is the same visually, but a different instance, why not precompose all the possible meter images and just blit the one you need for a given value. You probably wouldn't need that many images - I doubt if anyone would notice that there were only e.g. 20-30 different needle positions for example, when it's moving constantly. This would be worth doing if profiling demonstrated that actually rendering the meter images was taking a long time.
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden