Re: Speed of Quartz (was: optimizing compilers)
Re: Speed of Quartz (was: optimizing compilers)
- Subject: Re: Speed of Quartz (was: optimizing compilers)
- From: Dietmar Planitzer <email@hidden>
- Date: Mon, 04 Feb 2002 16:36:04 +0100
>
From: "Phil Barrett" <email@hidden>
>
>
Absolutely. We have exactly the same problem with Quartz speed. One of our
>
apps needs to draw a sound waveform, fast enough to allow it to scroll in
>
real time while the sound is playing. The waveform is drawn as two series of
>
line segments, one segment for each horizontal pixel. In Quartz this is
>
simply:
>
>
NSBezierPath * path = [ NSBezierPath bezierPath ];
>
[path setLineWidth:1.0];
>
[path moveToPoint: NSMakePoint(x,y)];
>
{ // loop over points
>
[path lineToPoint: NSMakePoint(x,y)];
>
}
>
[path stroke];
Just a bit of nit-picking: You're actually not using Quartz directly, rather
a Cocoa convenience class. The 'problem' with NSBezierPath, depending on how
complex the graphic you're drawing is, that NSBezierPath does a lot of extra
stuff which might get in the way performance-wise. It always saves the
current gstate before it starts drawing and restores it afterwards; further
it always sets the gstate to its internal attribute values before drawing
and finally it always has to determine the CGContextRef for every drawing
operation.
For more complex graphics, its often better to use the Quartz API located in
the ApplicationServices.framework/CoreGraphics.framework directly. Because
that way you get full control over gstate management and you don't
constantly have to re-fetch the CGContextRef which you acquire just once via
the NSGraphicsContext -graphicsPort method and then simply pass into each
CGContextXXX call subsequently.
Now, your code above unfortunately triggers a quite severe performance
bug/problem inside Quartz. Apparently Quartz has currently its psychological
problems with paths which consist of more than roughly 100 lineto/curveto
elements. In some experiments that I did just a few days ago, I had the
pleasure to find out that the drawing time will grow seemingly exponentially
with the number of elements in a path.
A possible workaround is that you simply create and stroke individual 1
element paths. In my case the time of rendering a line strip consisting of
500 line segments went down from 11.13 seconds to 0.22 seconds. Some people
might call this a bit of a performance improvement...
The only disadvantage with this workaround is that you can no longer control
the line join behavior, but you couldn't do that with OpenGL or QD either.
Regards,
Dietmar Planitzer