Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Uli Kusterer


On 19.10.2009, at 23:58, Ben Haller wrote:


On 19-Oct-09, at 5:27 PM, Dave Keck wrote:


Would NSView's -getRectsBeingDrawn:count: help?


 Well, I'm already using it in my own code where appropriate.  (Or  
actually I'm using -needsToDrawRect:).  But the problem is that a  
whole bunch of NSTableView cells are getting drawn that never got  
invalidated.


 That's like saying: I'm using the setter, why would I need to use  
the getter?


 The dirtyRect parameter passed to drawRect: is the union of all  
redraw rectangles. So, it's the smallest rect that encloses all the  
dirty rects. drawRect: does not get called for each redraw rect. If  
you want the individual sub-rects, use getRectsBeingDrawn:count: and  
loop over all those rects and draw the individual parts.


Cheers,
-- Uli Kusterer
The witnesses of TeachText are everywhere...



___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Uli Kusterer

On 20.10.2009, at 03:02, Ben Haller wrote:
As for NSTableView, it does appear to be doing minimal drawing.  So  
I guess all the string-drawing overhead I see in Sampler is just  
from the single column that is updating, which is unfortunate since  
it means I have no room for optimization.  I never imagined it would  
take so much time just to draw the one column I dirtied.



This may help to optimize after all:

http://zathras.de/blog-cocoa-text-system-everywhere.htm

Cheers,
-- Uli Kusterer
The witnesses of TeachText are everywhere...



___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Ben Haller

On 20-Oct-09, at 6:54 AM, Uli Kusterer wrote:


On 19.10.2009, at 23:58, Ben Haller wrote:


On 19-Oct-09, at 5:27 PM, Dave Keck wrote:


Would NSView's -getRectsBeingDrawn:count: help?


Well, I'm already using it in my own code where appropriate.  (Or  
actually I'm using -needsToDrawRect:).  But the problem is that a  
whole bunch of NSTableView cells are getting drawn that never got  
invalidated.


That's like saying: I'm using the setter, why would I need to use  
the getter?


The dirtyRect parameter passed to drawRect: is the union of all  
redraw rectangles. So, it's the smallest rect that encloses all the  
dirty rects. drawRect: does not get called for each redraw rect. If  
you want the individual sub-rects, use getRectsBeingDrawn:count: and  
loop over all those rects and draw the individual parts.


  Uh, Uli, reread what I typed.  I did not say or actually I'm using  
setNeedsDisplayInRect:.  -needsToDrawRect is a shorthand for exactly  
what you propose: calling -getRectsBeingDrawn:count: and looping over  
those rects.  From the docs for -needsToDrawRect:


It gives you a convenient way to determine whether any part of a given  
graphical entity might need to be drawn. It is optimized to  
efficiently reject any rectangle that lies outside the bounding box of  
the area the receiver is being asked to draw in drawRect:.


  So whether -needsToDrawRect or -getRectsBeingDrawn:count: is a  
better solution depends mostly upon taste, and a little bit on how  
many tests you intend to do in your draw method (i.e. efficiency to  
testing).  For my purposes, doing a total of two tests, - 
needsToDrawRect is fine.


Ben Haller
Stick Software

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Graham Cox


On 20/10/2009, at 10:42 PM, Ben Haller wrote:

 So whether -needsToDrawRect or -getRectsBeingDrawn:count: is a  
better solution depends mostly upon taste, and a little bit on how  
many tests you intend to do in your draw method (i.e. efficiency to  
testing).  For my purposes, doing a total of two tests, - 
needsToDrawRect is fine.



Yes, it's fine. -needsToDrawRect: is intended for when you have a  
simple list of objects that need drawing. The other is better suited  
when you have some form of spatial database storing the things to be  
drawn, so you can extract those directly from the database based on  
the dirty rects without iterating a (potentially very large) list.


--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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Ben Haller

On 20-Oct-09, at 6:59 AM, Uli Kusterer wrote:


On 20.10.2009, at 03:02, Ben Haller wrote:
As for NSTableView, it does appear to be doing minimal drawing.  So  
I guess all the string-drawing overhead I see in Sampler is just  
from the single column that is updating, which is unfortunate since  
it means I have no room for optimization.  I never imagined it  
would take so much time just to draw the one column I dirtied.


This may help to optimize after all:

http://zathras.de/blog-cocoa-text-system-everywhere.htm


  This is interesting, and I've done this sort of thing in the past  
quite a bit actually.  I'm surprised by one bit of it, though, where  
it says:


...sometimes you need better performance than the NSStringDrawing  
category will provide...


implying that doing things this way is faster than NSStringDrawing.   
Is that actually true?  Why would that be?  NSStringDrawing does more  
or less exactly this, doesn't it, using cached a cached textstorage/ 
layout/container set?  If NSStringDrawing is less efficient than doing  
it yourself, where does that inefficiency lie, and why doesn't Apple  
fix that inefficiency?  Presumably because Apple's way has some other  
benefit?  So what is that benefit?  I.e. I'm trying to understand what  
the tradeoffs are here.


  In the past, playing around with such things, the big win I've  
noticed over NSStringDrawing comes up only if you need to both measure  
and draw the same string.  Then you set everything up with your string  
once, measure and draw, and layout needs to happen only once.  So  
drawing centered or right-aligned text is faster -- almost twice as  
fast -- doing it yourself.  If there's a way to get the same speedup  
from Apple's API's I'm not aware of it; AFAIK even - 
[NSAttributedString drawWithRect:options:] doesn't let you draw a  
string centered or right-aligned in the rect, which seems like a big  
oversight.  I've just logged 7318495 on that.


  But if you're drawing text left-aligned, and thus don't need to  
measure it, is there any speedup doing things yourself?


Cheers,

Ben Haller
Stick Software

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Graham Cox


On 20/10/2009, at 11:03 PM, Ben Haller wrote:

AFAIK even -[NSAttributedString drawWithRect:options:] doesn't let  
you draw a string centered or right-aligned in the rect, which seems  
like a big oversight.  I've just logged 7318495 on that.



That's not the case - NSAttributedString takes its left/right/center/ 
justified setting from the NSParagraphStyle attribute attached to the  
string. If it's not there, it defaults to natural alignment for the  
font (left for English).



I.e. I'm trying to understand what the tradeoffs are here.


Convenience versus speed. Setting up a text layout system  
programatically is quite involved, and for a high-level solution that  
is equivalent to olde-worlde DrawThemeTextBox the string drawing  
methods do that for you. But they have to build up and tear down a  
text system for every call, so incur this overhead and can't cache any  
layout information. I still think it's the case (borne out by  
profiling here) that glyph rendering still dominates the process  
however.


But if you're drawing text left-aligned, and thus don't need to  
measure it, is there any speedup doing things yourself?


Yes, if you are drawing the same string over and over again (as in  
repeated refreshes of the same string in a view). The question is  
whether the speed-up matters. If you have thousands of text objects in  
your view, probably yes. If just one or two, probably not. There's no  
need to (and you can't) draw faster than 60 fps so you have ~16mS to  
draw everything. If it takes longer, text caching etc may help.


--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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Uli Kusterer

On 20.10.2009, at 13:42, Ben Haller wrote:
So whether -needsToDrawRect or -getRectsBeingDrawn:count: is a  
better solution depends mostly upon taste, and a little bit on how  
many tests you intend to do in your draw method (i.e. efficiency to  
testing).  For my purposes, doing a total of two tests, - 
needsToDrawRect is fine.



 Oh, right. Sorry. Mixed that up.

Cheers,
-- Uli Kusterer
The witnesses of TeachText are everywhere...



___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Uli Kusterer

On 20.10.2009, at 14:03, Ben Haller wrote:
implying that doing things this way is faster than NSStringDrawing.   
Is that actually true?  Why would that be?  NSStringDrawing does  
more or less exactly this, doesn't it, using cached a cached  
textstorage/layout/container set?  If NSStringDrawing is less  
efficient than doing it yourself, where does that inefficiency lie,  
and why doesn't Apple fix that inefficiency?  Presumably because  
Apple's way has some other benefit?  So what is that benefit?  I.e.  
I'm trying to understand what the tradeoffs are here.


 Apple's code has to be generic. It can only cache the last call, or  
maybe a few. It has to be conservative in its decision whether to  
cache so it doesn't cache stuff that's actually changed. You know your  
array storage, so you could cache more aggressively. Only you know  
your code, it might not make sense there, but in a lucky case, you  
could probably keep around the text system objects for each of your  
cells, and thus draw way faster than the OS's functions could do.


 AFAIK even -[NSAttributedString drawWithRect:options:] doesn't let  
you draw a string centered or right-aligned in the rect, which seems  
like a big oversight.  I've just logged 7318495 on that.


 Haven't tried that, but have you tried setting the paragraph style  
in the attributed string to use the right alignment?


 But if you're drawing text left-aligned, and thus don't need to  
measure it, is there any speedup doing things yourself?



 If you draw the same bunch of strings repeatedly, and you know their  
lifetime, you can definitely make them draw faster.


Cheers,
-- Uli Kusterer
The witnesses of TeachText are everywhere...



___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-20 Thread Ben Haller

On 20-Oct-09, at 8:15 AM, Graham Cox wrote:


On 20/10/2009, at 11:03 PM, Ben Haller wrote:

AFAIK even -[NSAttributedString drawWithRect:options:] doesn't let  
you draw a string centered or right-aligned in the rect, which  
seems like a big oversight.  I've just logged 7318495 on that.


That's not the case - NSAttributedString takes its left/right/center/ 
justified setting from the NSParagraphStyle attribute attached to  
the string. If it's not there, it defaults to natural alignment for  
the font (left for English).


  Oh!  Good to know.  Didn't occur to me somehow!


I.e. I'm trying to understand what the tradeoffs are here.


Convenience versus speed. Setting up a text layout system  
programatically is quite involved, and for a high-level solution  
that is equivalent to olde-worlde DrawThemeTextBox the string  
drawing methods do that for you. But they have to build up and tear  
down a text system for every call, so incur this overhead and can't  
cache any layout information. I still think it's the case (borne out  
by profiling here) that glyph rendering still dominates the process  
however.


But if you're drawing text left-aligned, and thus don't need to  
measure it, is there any speedup doing things yourself?


Yes, if you are drawing the same string over and over again (as in  
repeated refreshes of the same string in a view). The question is  
whether the speed-up matters. If you have thousands of text objects  
in your view, probably yes. If just one or two, probably not.  
There's no need to (and you can't) draw faster than 60 fps so you  
have ~16mS to draw everything. If it takes longer, text caching etc  
may help.


  Ah, yes, that is true, repeated drawing of the same string would be  
a big win for this.


  Uli had much the same to say.  Good points.  Thanks guys.

Ben Haller
Stick Software

___

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


Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller
  Hi all.  I expected this to be an FAQ, but my searches have turned  
up nothing relevant, so here goes.


  I've got a window with a view hierarchy like this:

1. Superview that does no drawing and is not opaque

A. Subview #1: a tableview that is opaque
B. Subview #2: a graph view that is opaque
C. Subview #3: another graph view that is opaque

  The tableview is on top, the two graph are on the bottom, on the  
left and on the right respectively.  My app alternates calculating and  
drawing the results.  Typically, what needs to get drawn is *one*  
column of the tableview, plus both graphs.  I'm carefully calling  
setNeedsDisplayInRect: for only the bits that need to be drawn; I'm  
using [frameOfCellAtColumn:row:] to get the frame of the cells that  
need to be redrawn, and invalidating only them, for example.


  If I turn off all redrawing of the graphs, then Quartz Debug shows  
me that my invalidating in the tableview is minimal; only the column  
that needs to be drawn flashes.  If I turn off all redrawing of the  
tableview, QuartzDebug similarly shows that my invalidating in the  
graphs is minimal.  So taken separately, it's all good.  But when  
drawing of all the views is turned on, somebody is merging together  
the dirty rects and causing pretty much the entire content of the  
window to redraw.  This means that a ton of extra table cells are  
redrawing unnecessarily, and I see the overhead from this very clearly  
in Instruments/Sampler (text drawing is not fast!).


  So my question is: is there any way I can exert any control over  
the merging of dirty rects?  I thought maybe adding some vertical  
space between the tableview and the graph views would disconnect  
them and make the dirty rects get handled separately; but no dice;  
even adding 100 pixels of vertical space doesn't prevent the merge.   
Is the merging dependent upon the view hierarchy or opacity in some  
way?  Or are there CG calls somewhere in the bowels that I could use  
to change a merge threshold or something?


  I'm not sure whether this is a Cocoa or a CG question really, but  
since I'm using nothing but Cocoa calls at present, I figured I'd try  
this list first...


  Thanks!

Ben Haller
Stick Software

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Dave Keck
Would NSView's -getRectsBeingDrawn:count: help?
___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Greg Guerin

Ben Haller wrote:


1. Superview that does no drawing and is not opaque

A. Subview #1: a tableview that is opaque
B. Subview #2: a graph view that is opaque
C. Subview #3: another graph view that is opaque



Obvious experiment: set the superview to be opaque.

  -- GG

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 5:27 PM, Dave Keck wrote:


Would NSView's -getRectsBeingDrawn:count: help?


  Well, I'm already using it in my own code where appropriate.  (Or  
actually I'm using -needsToDrawRect:).  But the problem is that a  
whole bunch of NSTableView cells are getting drawn that never got  
invalidated.  I would certainly hope that NSTableView is using one of  
these minimal-drawing mechanisms, and I assume that it is.


  I think the problem is deeper (based upon what flashes under Quartz  
Debug): I think the dirty rects are actually getting consolidated such  
that NSTableView no longer has the information it needs to do minimal  
drawing.  I could be mistaken about that, though, if the flashes in  
Quartz Debug show only the area that Quartz is choosing to blit over,  
and not necessarily the area that was considered dirty and redrawn.   
(i.e. if it brings over merged areas for efficiency, for some reason;  
but that seems unlikely...)


Ben Haller
Stick Software

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Andy Lee
On Monday, October 19, 2009, at 05:58PM, Ben Haller 
bhcocoa...@sticksoftware.com wrote:
On 19-Oct-09, at 5:27 PM, Dave Keck wrote:

 Would NSView's -getRectsBeingDrawn:count: help?

   Well, I'm already using it in my own code where appropriate.  (Or  
actually I'm using -needsToDrawRect:).  But the problem is that a  
whole bunch of NSTableView cells are getting drawn that never got  
invalidated.  I would certainly hope that NSTableView is using one of  
these minimal-drawing mechanisms, and I assume that it is.

   I think the problem is deeper (based upon what flashes under Quartz  
Debug): I think the dirty rects are actually getting consolidated such  
that NSTableView no longer has the information it needs to do minimal  
drawing.

To test this theory, might it help to use a subclass of NSTableView whose 
drawRect: method prints the rectangle passed to it, and see what happens when 
your graph views do and do not do any drawing?  And maybe the result of 
getRectsBeingDrawn:count: as well?

I'm curious too if you've tried Greg Guerin's suggestion.

--Andy


  I could be mistaken about that, though, if the flashes in  
Quartz Debug show only the area that Quartz is choosing to blit over,  
and not necessarily the area that was considered dirty and redrawn.   
(i.e. if it brings over merged areas for efficiency, for some reason;  
but that seems unlikely...)

Ben Haller
Stick Software

___

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/aglee%40mac.com

This email sent to ag...@mac.com


___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 5:58 PM, Greg Guerin wrote:


Ben Haller wrote:


1. Superview that does no drawing and is not opaque

A. Subview #1: a tableview that is opaque
B. Subview #2: a graph view that is opaque
C. Subview #3: another graph view that is opaque



Obvious experiment: set the superview to be opaque.


 Indeed.  Already tried it (right after posting), and it makes no  
difference.  I'd try rearranging the view hierarchy to test the  
effects of that, but that isn't trivial, because it is arranged  
programmatically, so I'm hoping someone has already explored this...
 More generally, I am interested in knowing how this mechanism works,  
beyond just fixing my immediate problem, so I hope somebody can  
comment on that more generally.  And whether there is any way to  
affect it, beyond my immediate case.  I find nothing in the docs about  
it.


Ben Haller
Stick Software

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Graham Cox


On 20/10/2009, at 8:58 AM, Ben Haller wrote:

 I think the problem is deeper (based upon what flashes under Quartz  
Debug): I think the dirty rects are actually getting consolidated  
such that NSTableView no longer has the information it needs to do  
minimal drawing.  I could be mistaken about that, though, if the  
flashes in Quartz Debug show only the area that Quartz is choosing  
to blit over, and not necessarily the area that was considered dirty  
and redrawn. (i.e. if it brings over merged areas for efficiency,  
for some reason; but that seems unlikely...)



I think what you're observing is right. If you invalidate two disjoint  
rects in a view, while Quartz keeps track of those separate areas, its  
overall union is calculated and passed to any -drawRect: methods  
(intersected with that view's frame) that get called as a result. Many  
simple views will not bother to break that down. If the disjoint areas  
are far apart, that can be a considerable area. (As an aside, I think  
Cocoa does miss an efficiency trick there, because it could intersect  
each view's frame with the original dirty rect list for the window,  
then union the result to pass to -drawRect:, rather than with the  
union of that list as it appears to do - i.e. if it did intersect +  
union it would come up with smaller areas for each view than union +  
intersect, but there may be other factors such as backward  
compatibility and speed of calculating these rects to consider).


I suspect its likely that NSTableView is just taking its -drawRect:  
parameter as what it needs to update and doing that, rather than  
further examining the individual dirty rects. I think the ability to  
maintain and test the individual dirty rects was only added in 10.3 or  
so, possibly earlier, but certainly wasn't inherited from OpenStep.  
The flashes in Quartz Debug may also be representing areas that other  
parts of the view (the background, say) are responding to which is  
masking what NSTableView is updating. I'm not sure if QD has any way  
to separate out the two (it can't know how a specific view is  
responding to -drawRect:, whether it is further testing against the  
dirty rects) so it might not be showing you the true picture.


However, maybe you shouldn't get too hung up on this. If your own  
custom views do complex drawing, then using -needsToDrawRect: and/or - 
getRectsBeingDrawn:count: are well worth using and you can trust them  
to do the right thing, regardless of what QD shows is the update rect.  
There's nothing to lose by using these methods really, but equally  
there may be nothing to gain either. You might not be able to do much  
about NSTableView whatever it's doing internally. Does profiling  
indicate that drawing updates are too slow?


--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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 6:53 PM, Andy Lee wrote:

On Monday, October 19, 2009, at 05:58PM, Ben Haller bhcocoa...@sticksoftware.com 
 wrote:

 I think the problem is deeper (based upon what flashes under Quartz
Debug): I think the dirty rects are actually getting consolidated  
such

that NSTableView no longer has the information it needs to do minimal
drawing.


To test this theory, might it help to use a subclass of NSTableView  
whose drawRect: method prints the rectangle passed to it, and see  
what happens when your graph views do and do not do any drawing?   
And maybe the result of getRectsBeingDrawn:count: as well?


  Just did this.  The results are interesting.  Two points of note:

- my tableview does seem to be getting passed a nicely limited dirty  
rect, even though Quartz Debug flashes a much larger area.  So  
apparently flashes in Quartz Debug are only indicative of what Quartz  
is choosing to blit over to the screen, not what is actually getting  
updated.  If so, it would be useful to have a new checkbox in Quartz  
Debug that flashed only the areas actually getting marked as dirty, I  
think, so that one could check one's minimal-redraw correctness.  I  
logged 7317630 on this.


- there do seem to be some weirdnesses in the dirty rect accumulation  
code.  For example, when I call -getRectsBeingDrawn:count: and log the  
results, I typically see something like this:


count == 2
rects[0] == {{47, 12}, {45, 215}}
rects[1] == {{47, 0}, {45, 12}}

  So abutting rects of the same width are not getting merged  
together.  Oddly, the dividing line between these rects is not at a  
line boundary in my tableView; a bunch of lines get accumulated  
together into the tall rect, and then the topmost line gets split  
between the tall rect and the little rect.  I have no theory as to why  
this would be.


  As for NSTableView, it does appear to be doing minimal drawing.  So  
I guess all the string-drawing overhead I see in Sampler is just from  
the single column that is updating, which is unfortunate since it  
means I have no room for optimization.  I never imagined it would take  
so much time just to draw the one column I dirtied.


  So, sorry for the false alarm.  The main take-home point I get out  
of all this is that Quartz Debug flashes the areas being blitted over,  
which are not the same as the areas marked dirty or the areas  
requested to be redrawn!


Ben Haller
Stick Software

___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Andy Lee
Come to think of it, another experiment would have been to add logging  
to the cells used for the other table columns, to see if their drawing  
code was actually being called.q


Sorry if I missed this, but is the string-drawing overhead noticeable  
to the user?  If so, and it's because you're redrawing very  
frequently, maybe you could throttle redrawing to, say, 2-4 times per  
second.  There's something called coalesced updates that might help.


Does the table column's cell have to do much work to get the string it  
needs to draw (a gross example would be querying a database)?  Maybe  
caching would help.


I don't know how much overhead is in cell drawing, but maybe you could  
write your own cell class that doesn't, for example, check whether the  
string needs to be truncated.


There's a section in the docs on optimizing drawing.  I must admit I  
haven't read it, but maybe it contains something that would help in  
your case?


Sorry for all the might's and maybe's --I'm hoping one of my stabs in  
the dark will help.


--Andy

On Oct 19, 2009, at 9:02 PM, Ben Haller bhcocoa...@sticksoftware.com  
wrote:



On 19-Oct-09, at 6:53 PM, Andy Lee wrote:

On Monday, October 19, 2009, at 05:58PM, Ben Haller bhcocoa...@sticksoftware.com 
 wrote:

I think the problem is deeper (based upon what flashes under Quartz
Debug): I think the dirty rects are actually getting consolidated  
such
that NSTableView no longer has the information it needs to do  
minimal

drawing.


To test this theory, might it help to use a subclass of NSTableView  
whose drawRect: method prints the rectangle passed to it, and see  
what happens when your graph views do and do not do any drawing?   
And maybe the result of getRectsBeingDrawn:count: as well?


 Just did this.  The results are interesting.  Two points of note:

- my tableview does seem to be getting passed a nicely limited dirty  
rect, even though Quartz Debug flashes a much larger area.  So  
apparently flashes in Quartz Debug are only indicative of what  
Quartz is choosing to blit over to the screen, not what is actually  
getting updated.  If so, it would be useful to have a new checkbox  
in Quartz Debug that flashed only the areas actually getting marked  
as dirty, I think, so that one could check one's minimal-redraw  
correctness.  I logged 7317630 on this.


- there do seem to be some weirdnesses in the dirty rect  
accumulation code.  For example, when I call - 
getRectsBeingDrawn:count: and log the results, I typically see  
something like this:


count == 2
rects[0] == {{47, 12}, {45, 215}}
rects[1] == {{47, 0}, {45, 12}}

 So abutting rects of the same width are not getting merged  
together.  Oddly, the dividing line between these rects is not at a  
line boundary in my tableView; a bunch of lines get accumulated  
together into the tall rect, and then the topmost line gets split  
between the tall rect and the little rect.  I have no theory as to  
why this would be.


 As for NSTableView, it does appear to be doing minimal drawing.  So  
I guess all the string-drawing overhead I see in Sampler is just  
from the single column that is updating, which is unfortunate since  
it means I have no room for optimization.  I never imagined it would  
take so much time just to draw the one column I dirtied.


 So, sorry for the false alarm.  The main take-home point I get out  
of all this is that Quartz Debug flashes the areas being blitted  
over, which are not the same as the areas marked dirty or the areas  
requested to be redrawn!


Ben Haller
Stick Software


___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Ben Haller

On 19-Oct-09, at 10:40 PM, Andy Lee wrote:

Come to think of it, another experiment would have been to add  
logging to the cells used for the other table columns, to see if  
their drawing code was actually being called.


  Yeah, I did that.  See my previous post.  The upshot is that the  
table is correctly doing minimal redraws.


Sorry if I missed this, but is the string-drawing overhead  
noticeable to the user?  If so, and it's because you're redrawing  
very frequently, maybe you could throttle redrawing to, say, 2-4  
times per second.  There's something called coalesced updates that  
might help.


  I'll check it out.  I kinda want it to redraw a lot really really  
fast, though, because it looks cool.  ;-  I'm throttling my drawing  
to 60 frames per second at present, and then I'm trying to optimize  
the drawing code so that it takes as little time as possible, so that  
as much of each 1/60th second is left to calculate in as possible.   
Maybe I will make the tableView update every 1/30th of a second, and  
update everything else every 60th since it all draws faster.  :-


Does the table column's cell have to do much work to get the string  
it needs to draw (a gross example would be querying a database)?   
Maybe caching would help.


  Nope, all the time is in the string-drawing stuff inside AppKit.

I don't know how much overhead is in cell drawing, but maybe you  
could write your own cell class that doesn't, for example, check  
whether the string needs to be truncated.


  IIRC it wasn't stuff like that.  It was setting up the text storage  
and the typesetter, and then doing the actual drawing, I think.   
Nothing I could reasonably optimize, I think, without getting  
extremely dirty.


There's a section in the docs on optimizing drawing.  I must admit I  
haven't read it, but maybe it contains something that would help in  
your case?


  Read that.  Useful tips, and it did prompt me to put in checks for  
whether parts of my views are inside the dirty rects or not, and to  
make more of my views opaque.


Sorry for all the might's and maybe's --I'm hoping one of my stabs  
in the dark will help.


  Well, I'm curious about the coalesced update thing.  The only ref I  
find through Google is here:


http://developer.apple.com/mac/library/documentation/Performance/Conceptual/Drawing/Articles/CocoaDrawingTips.html

and I don't think that's what you're referring to.  AppKiDo (which I  
still love :-) doesn't find any APIs with coalesce in their name  
that are drawing-related.  Can you give me a pointer?


  Thanks!

Ben Haller
Stick Software


___

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


Re: Dirty rects getting merged together makes for inefficient drawing

2009-10-19 Thread Andy Lee

On Oct 19, 2009, at 11:00 PM, Ben Haller wrote:
 Well, I'm curious about the coalesced update thing.  The only ref I  
find through Google is here:


http://developer.apple.com/mac/library/documentation/Performance/Conceptual/Drawing/Articles/CocoaDrawingTips.html

and I don't think that's what you're referring to.  AppKiDo (which I  
still love :-)


:)

doesn't find any APIs with coalesce in their name that are drawing- 
related.  Can you give me a pointer?


Odd, I got these as the first hits for coalesced updates:

http://developer.apple.com/mac/library/technotes/tn2005/tn2133.html

http://developer.apple.com/mac/library/documentation/Performance/Conceptual/Drawing/Articles/FlushingContent.html 



I'd try to elaborate, but I'd probably embarrass myself because I  
haven't actually looked closely at this.  I just remembered someone  
mentioning it once or twice upon a time.


--Andy

___

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