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: Tue, 05 Feb 2002 21:03:30 +0100
>
From: Ulrich Kortenkamp <email@hidden>
>
>
Did you file a bug on this? This helps many applications a lot if
>
somebody fixes it.
I'm still busy doing a number of Quartz related experiments for a project
I'm currently working on. I'll file bugs and enhancement requests in one go
once I'm finished, propably by the end of the week.
>
From: email@hidden
>
>
... So turn off antialiasing,
>
draw your lines, and then turn it back on so other drawing still looks
>
nice. If you're comparing DPS's line-drawing speed with Quartz's, but
>
you don't turn off anti-aliasing, you can hardly call that a fair test.
Sadly, turning off Quartz's antialiasing isn't any option if you care even
the least about aesthetics. Interestingly, it often turns out that turning
antialiasing off doesn't really help to gain much more drawing speed.
< in response to Marcel Weiher>
>
Do you have any evidence that antialiased text is actually so slow? I
>
am fairly certain that antialiased bitmaps get cached for fonts,
>
somewhere in Quartz or the underlying layers, so I would be surprised if
>
it was really that much slower than non-antialiased text.
Quartz indeed deploys a glyph cache. However, its important to always
remember that accessing the vector data for a particular glyph via
NSBezierPath's -appendBezierPathWithGlyph:inFont method can't take advantage
of the glyph cache and in fact often if not always requires a nice
round-trip to the ATS server. Though, its not a big problem to build your
own glyph cache consisting of NSBezierPath objects into your app. The only
caviat here is that you must be sure to construct all glyphs relativ to a
common current point like 0/0. Apparently, it turns out that the glyph data
is always generated relative to NSBezierPath's current point. The glyph can
then be positioned via the CTM on the virtual canvas.
>
In any case,
>
font rendering is not actually Quartz's problem, as I understand it, so
>
I *think* you're not actually complaining about the speed of Quartz
>
anyway, but of ATSUI or some other component.
ATS actually. ATSUI is in some stretched sense Carbon's version of an
NSLayoutManager.
>
I'd be interested in any benchmarks regarding speed of text drawing on
>
X that anybody has.
Take this number with a grain of salt, as it has been determined via Sampler
and a _very_ simple minded benchmark based on NSLayoutManager's
-drawGlyphsForGlyphRange:atPoint: method: around 140.000 unclipped
glyphs/sec through CGContextShowGlyphsAtPoint().
>
Quartz is the best-designed, highest-quality and fastest rendering
>
system I've ever had the pleasure of using, and I've been doing Mac
>
programming since 1984.
Definitely. It has just one HUGE disadvantage compared to QD - all the
really powerful & interesting APIs are still private.
>
From: Marcel Weiher <email@hidden>
>
>
On Monday, February 4, 2002, at 07:18 , email@hidden wrote:
>
>
> And you can do stroke adjustment for your lines yourself if you're
>
> attached to it; that's a separate issue from antialiasing.
>
>
No you can't. ...
Marcel, you might try the following function for stroke adjustment: void
CGContextSetStrokeAdjust(CGContextRef ctx, int zeroOrOne). You may also
inquire the current stroke adjustment value via int
CGContextGetStrokeAdjust(CGContextRef). These functions are currently
private Quartz API just as the void
CGContextReplacePathWithStrokedPath(CGContextRef) function is, but they are
so damned useful (especially the last one) :)
>
From: "John C. Randolph" <email@hidden>
>
>
Someone on the CG team just explained to me that ...
>
>
"Drawing 1000 individual moveto/lineto segments is essentially
>
equivalent to drawing 1000 independent thin rectangles of
>
various lengths at various orientations. Drawing a 1000 segment
>
connected/stroked path with round linejoins involves parallel
>
curve formation (including arc line joins), flattening the
>
curves, feeding the entire beast to the scan converter as a
>
huge self-intersecting polygon, resolving the self-intersections
>
to get the antialiasing right, etc...."
>
>
So, when you have a bunch of lines to draw, keep in mind that
>
intersections and line joins add up. BTW, it would appear that
>
round line caps/joints are somewhat more expensive than mitered
>
or square caps.
Actually, it doesn't matter what line join style you use. Miter and Bevel
style are just as slow as the Round join style.
It sure sounds reasonable that self-intersecting paths should be slower to
render than paths that don't have any self-intersections. The only problem
is that after having done some further experiments, I'm no longer sure about
this theory.
I) I started out with a single path consisting of 250 straight line
segments, vertex coordinates were determined via a random number generator
which resulted in a neatly self-intersecting path. I made sure that all
coordinates would fall inside my view's bounding rect so that clipping
doesn't come into play here. Drawing this path with anti-aliasing turned on
took around 1.8 secs on a Dual G4/450. After turning anti-aliasing off,
render time dropped to 0.2 secs.
II) Okay, lets assume that checking a multi-segmented path for
self-intersections would be an expensive operation. Thus, the next step was
to create a path with again 250 segments but with no self-intersections (a
circle in this case). Rendering this path took around 0.2 secs WITH
antialiasing turned on. Conclusion: either the self-intersection test has
neglectable overhead and the self-intersection removal code takes all the
time, or Quartz uses a two stage checking code, or self-intersections aren't
actually such a big problem performance wise.
One thing that is really annoying about Quartz is that whenever you turn off
antialiasing you end up with extremly ugly looking lines. This is especially
true for lines which are not strictly horizontal or vertical. Looking a bit
closer at them via the DigitalColor Meter app reveals that tilted lines have
a line width that is everything but uniform. In fact they look like as if
they would have been drawn by a Bresenham rasterizer on drugs.
It seems like as if the internal drawing routines were only designed for
antialiased rendering and that the ability to turn off named feature has
been introduced as an afterthought.
III) In order to improve the look of the self-intersecting multi-segment
path in aliased mode, I made sure that all path coordinates would fall at
the center of pixels (i.e. 100.5). This didn't help much. I than reduced the
line width to 0.5 and indeed they started to look better. Further reducing
the line width to 0.01 resulted in lines that de facto looked just like
there QD counterparts.
IV) The REALLY funny part about this longwinded story is that while I
reduced the line width and the lines looked more and more like the lines
produced by a good old graphics lib, the render time went up - in fact just
to the good old know 1.8 secs that we originally had in case (I). Remember,
this is the self-intersecting path drawn with antialiasing turned OFF. I
would have expected that Quartz realizes that because of the tiny line width
and the fact that I turned antialising off, it could switch from the generic
path renderer to a good old Bresenham line renderer which would naturally be
much faster.
I get more and more the feeling that in fact there is a really fundamental
flaw in the path render routine that is not necessarily tied to path
self-intersections. They may just make it really obvious.
Looking with Sampler at the test app it turns out that just one single
routine out of around a dozend, namely aa_render is responsible for 50% -
60% of the execution time of the CGContextDrawPath function if the current
path has no self-intersections. In case of self-intersections, aa_render
takes 98% (!) and more of the render time. The EXACT same is true for the
case described in (IV). Some people may be happy to hear that blitting the
shape that Quartz generates from a path takes only around 10% in the
standard case (and is taking advantage of Altivec).
>
From: Bruno Blondeau <email@hidden>
>
>
Another reason why Quartz is slow may be in the current math library (not by
>
a 10x factor, though).
I would have expected the same but looking through Sampler's output I can't
find any mention of a math lib function except restFP which takes an
insignificant amount of time.
>
I heard Apple is working on this, however. (well, the bug has been filed
>
numerous times, and it is in the opensource database...)
Indeed. You can find the new math lib (v5) in the Darwin CVS under
Library/Apple/mlib. Looks like that this thing is supposed to be C99
complient.
Regards,
Dietmar Planitzer
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.