Re: Smooth animation
Re: Smooth animation
- Subject: Re: Smooth animation
- From: Douglas Davidson <email@hidden>
- Date: Thu, 12 Dec 2002 09:54:47 -0800
On Thursday, December 12, 2002, at 04:36 AM, Simon Stapleton wrote:
Well, drawing text in Cocoa is relatively slow, for reasons that stem
from the way Quartz renders paths. This part, at least, has been
discussed ad nauseum on the list, and I'd rather not open that can of
worms again... Needless to say, you could trawl the list archives to
find out why.
However, compositing images is way fast.
So, what I'd suggest is drawing the text into an NSImage and keeping
that cached, then compositing that into your screensaver view. Should
speed things up no end.
If you need the text to change (say, for example, you're displaying a
clock and need it to change text every second), simply recreate the
image at the point the text needs to change.
There are many levels at which one can do this, corresponding to the
different processes that are required to display text. Before text can
be rendered on the screen it first must be (a) laid out. That is, the
Cocoa text system must take a string of characters and associated
attributes, and produce from that a list of glyphs to be rendered and a
position for each glyph. Then it must be (b) rasterized. That is,
Quartz must take this list of glyphs and positions and convert it into
an array of color values for individual pixels. Finally, it must be
(c) composited into a window, and (d) the window composited onto the
screen.
The speed of text drawing depends heavily on how many of these
processes can be avoided. If the text changes, then there is no help
for it; all of this must be done. But if the text does not change,
then some of these processes can be avoided, depending on how much work
you are willing to do and what you are willing to trade off. If you
simply use the convenience methods like -[NSString
drawAtPoint:withAttributes:], then potentially all of these steps will
be done--not necessarily every time, since there is some caching at
various levels--but certainly some of the time. If you create an
NSLayoutManager and have it lay out the text once, then tell it to draw
it multiple times, you will avoid repeating step (a), but the remaining
steps will be repeated--again, not necessarily completely every time,
because of caching, but definitely some of the time. The CircleView
example uses this strategy, so you can fairly easily see how it is done
and take a look at how it performs.
If you render the text into an image and then composite the image into
a view, then you can avoid repeating steps (a) and (b), and only repeat
(c) and (d). There is another option that might work in this case, and
that is to draw the text into a window (in this case, perhaps a window
transparent except for the text), and to move the window on the screen
rather than moving the text in the window. In that case, you could
avoid repeating (a), (b), and (c), and only repeat (d). Moving windows
is almost always fast, and if Quartz Extreme is available, it may even
be accelerated. That is probably the option I would consider first if
I had an isolated piece of text to move rapidly around the screen.
Finally, you could consider rendering the text into an OpenGL texture,
and using OpenGL to get the texture to the screen. In that case also
you would avoid repeating (a), (b), and (c), and in addition you could
get acceleration even without Quartz Extreme. The advantage of
acceleration is that it moves much of the workload from the CPU to the
GPU, which under most circumstances has plenty of excess capacity for
this sort of thing, and is better suited to graphics operations than
the CPU anyway. Applications with a real need for graphics speed, such
as graphic-intensive games, usually use OpenGL for this reason. There
are also additional effects that OpenGL could give you that would be
difficult to obtain by other means.
I should emphasize that all of these strategies have tradeoffs. As you
move toward lower-level, higher-performing APIs, you obviously pay a
price in terms of ease of development, but there is also a more
fundamental loss of flexibility. Depending on your application, you
may or may not be able to use one of these strategies. There are also
space tradeoffs--creating an extra window for your text has a memory
cost, even if it is not immediately obvious. If you were trying to
move hundreds of pieces of text around, and created a window for each
one, it would definitely be significant.
Douglas Davidson
_______________________________________________
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.