Re: Dirty rects getting merged together makes for inefficient drawing
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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