[Drawkit] Scaling issues

Graham Cox graham.cox at bigpond.com
Fri May 23 17:47:27 PDT 2008


On 24 May 2008, at 9:05 am, Brad Larson wrote:

> The problem is more that 1-point-wide grid lines get blown up into  
> 50-pixel-wide lines at that zoom factor.  This will happen to a  
> lesser degree with anyone zooming in on a fine feature at a higher  
> magnification than the one at which the grid lines were originally  
> drawn.  Scaling the entire grid, including linewidth, can be  
> problematic, which is why I think redrawing the grid at a  
> magnification change is the way to go.  Testing it out, I don't  
> think it will be that much of a performance hog.

Actually they are not that wide, but the point is valid. Since the  
linewidth can be set independently of actually constructing the grid  
cache it would be easy to set this on the fly taking into account the  
zoom without invalidating the cache itself. I'll have a look at that  
this morning.

> Sorry, zoomed out.  After running the program through Instruments,  
> it looks like the a whole lot of processor cycles are being spent in  
> [DKDrawableObject pathBitmapInRect].  That method appears to  
> rasterize the object shapes to perform hit detection, and the size  
> of the bitmap seems to be set by the original zoom factor, so huge  
> bitmaps are being created as you drag the mouse for the selection  
> rectangle on this drawing.  Maybe the bitmap hit testing could take  
> the scale into account, creating bitmaps whose size only matches the  
> size in pixels of that area at the current scale factor, then  
> translate that scaled bitmap to the hit testing coordinates being  
> fed in.

Yes, the bitmap creation is a bottleneck. It has got a lot better  
though, since the bitmaps are formed from the intersection of the  
selection rect and the object and then *only* when they overlap, not  
if one wholly contains the other. And the "hit" is detected as soon as  
a pixel is found to be set, which very often means that only a couple  
need to be tested. However, there's no easy way to avoid the need to  
make the bitmap in the first place and that's where you are seeing  
time spent.

Currently the bitmap creation just uses the native object co-ordinate  
space, so zoom is ignored altogether. This is a great advantage when  
you are zoomed well *in*, because the objects are not being rendered  
at the blown-up size you see, but their original size. However, for  
the zoomed *out* case, you are right that this means a large area of  
the drawing is being considered. If you have many small objects it's  
probably fine, but large ones will hurt you if they overlap the  
selection rect. So your suggestion for taking the zoom into account is  
probably worthwhile for scales < 1, especially as in this case very  
fine hit detection is not really necessary. Again, I'll look into it.

> What caused you to go with a variant of the method described here:  http://lists.apple.com/archives/cocoa-dev/2004/Sep/msg00698.html 
>  as opposed to the mathematical model you proposed here: http://lists.apple.com/archives/cocoa-dev/2004/Sep/msg00696.html 
>  ?  I haven't checked fully, but did you go with some of the  
> optimizations that Uli Kusterer suggested in that thread?

Wow, that's an old thread ;-) At that time I was working on a very  
early bit of code that eventually evolved into DrawKit. At that time,  
I thought that plain strokes and fills would be all I'd end up using.  
As they grew more complex, the mathematical hit testing got less  
usable, so I switched over to using pixel-oriented hit testing, which  
always works regardless of the stylistic variations, with the drawback  
that it can be slower. The short story: I realised I was wrong and the  
alternative approach was better.

DrawKit currently optimises to only perform the bitmap hit test after  
culling the bounds rect for both exclusion and complete inclusion -  
only the cases where an object overlaps the edge of the selection rect  
generates a bitmap. The zoom is ignored, so there's a potential  
optimisation I've missed. The bitmap isn't cached, it's created for  
each hit test. That's another potential place to make an improvement,  
though the cache management gets complicated-ish. I guess I could flag  
the need to cache at the start of the selection drag and simply  
discard at the end - that way *during* the drag the bitmaps are only  
ever created once. That might be a good compromise between the complex  
cache management I used to have and the current "hands free" approach.  
I imagine applying both of these optimisations would speed things  
substantially especially for your situation.



Anyway, this is the sort of feedback I've been hoping this list would  
help generate - real world cases and a flagging up of the bottlenecks  
they show up.

cheers, Graham


More information about the Drawkit mailing list