Re: Separating elements in an NSView subclass
Re: Separating elements in an NSView subclass
- Subject: Re: Separating elements in an NSView subclass
- From: Graham Cox <email@hidden>
- Date: Fri, 8 Aug 2008 22:58:04 +1000
Are you checking the view's -needsToDrawRect: when you actually
iterate through your rectangles? For a view like this it will be
essential to avoid drawing anything that doesn't need drawing - even
checking thousands of rects for intersection with the update area is
much faster than actually drawing the same rects.
And the flip-side of that is, are you ensuring that when an individual
rectangle is moved or its contents changed, you just invalidate that
rectangle and not the whole view?
These two together should sort out your framerate problems - the
screen shot is busy but it's not unreasonable - I wouldn't expect 1.2
fps even with this many rects as long as you are doing the two key
things above. Throwing a backing layer at the problem isn't going to
magically fix it if there's a basic problem with drawing too much.
Ultimately it doesn't matter that everything is drawn in the same
view. It might make sense to break it down just to keep the code
sensible, but it won't automatically fix up drawing speed problems -
after all, you're blitting into the same pixel buffer whoever draws
them.
You mention a background view - is that really a separate view, or
just a term you're using for your grid graphics? Either way, if you
decide to invalidate the whole view at any point you are going to
stuff yourself. There's rarely a reason to ever invalidate a whole
view (except for maybe the first time it's drawn, and that's handled
by Cocoa, not you). The grid doesn't need to be repainted in its
entirety for every change for example - again, just draw the little
piece revealed by the update event. Doing that is actually less work
for you to code than not doing it - when drawRect: is called it's
already clipped to the update region, so just repaint the grid -
pixels outside the clip region are not drawn so do not impose a drag
on the drawing speed (cache the grid path also to avoid recalculating
it every time). The key is never to call setNeedsDisplay:, but ALWAYS
use setNeedsDisplayInRect:. Search your code for uses of -
setNeedsDisplay: and change it.
Incidentally, this looks like an ideal project to use my own DrawKit
framework for, if you'll permit me the shameless plug. I just tried
drawing about 460 small rects with text in them similar to yours and
on my lowly MacBook 1st gen I get no framerate problems moving them
around. Dragging a semi-transparent selection rect over them is a
little stuttery, but usable. I also have a full-view grid behind
everything (much more complex than yours too) so it's doable. I'm not
doing any CALayer backing (incidentally on 10.4 you have CGLayer which
provides similar functionality though much more basic). If you want to
look at DrawKit, you can d/l it here: http://apptree.net/
drawkitmain.htm. Even if you don't want to use the framework you may
find the code worth a look to see how I draw stuff quickly without any
tricky stuff.
hth,
Graham
On 8 Aug 2008, at 10:14 pm, Paul Bruneau wrote:
Hi-
Some time ago I got some great advice to help me optimize the
refresh rate of my NSView subclass (the answer is, just draw the
minimum that you need to).
So I am working to do this, but I am having some trouble with the
inter-dependence of various elements that appear in my view.
Here is the screenshot of it:
http://special-lite.com/satellite/Schedule.pdf
Currently, everything is a single NSView subclass that does too much
(the docs refer to such a view as "monolithic" and I'm sure mine
qualifies). I believe this is making it hard for me to draw the
minimum.
The elements consist of:
- the order steps (all those colorful rectangles)
- the list of workcenters on the left
- the grid drawn behind the order steps (including the pink grid
rectangles indicating "off-line" time)
- The timeline along the bottom
- lines that connect order steps to "sibling" order steps (you can
see an example of this on the right side--when a particular order is
selected, it is highlighted green with connecting lines)
I have started by creating a new view that has the workcenters, the
timeline, and the grid, and a second view with just the order steps
on it.
The problem that I think I have is that if the user moves an order
step, it reveals some of the "background" view below it. This will
then cause the background view to be redrawn, which, if I understand
things, is going to force the "order step" view to be completely
redrawn.
This would not help me any, since I am redrawing everything on every
update now.
I think I have read enough about CALayer to think that it could help
me with caching that it does, but I am writing for 10.4.
I'm hopeful that I am missing something, or thinking about this
incorrectly and that someone can point me in the right direction. If
you look in the lower left corner, you can see that with the
increased number of orders we have during our busy season, I am down
to an abysmal 1.2 fps.
Thank you all for you help, past and future.
_______________________________________________
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
_______________________________________________
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