- From PostScript to Quartz
- The First Steps to a New Model
- Introducing LayerKit
- CoreAnimation on the Desktop
- Animation
The First Steps to a New Model
With 10.4, Apple introduced a new feature: Quartz 2D Extreme (later rebranded as Quartz GL). This was not enabled by default, but you could turn it on in the QuartzDebug utility temporarily or permanently by editing a property list file. I did this for a bit, but turned it off again because it still contained a few bugs.
The main improvement of Quartz GL was accelerated text rendering. Drawing text is surprisingly computationally expensive on a system like OS X. Every character is stored in a TrueType font as a sequence of Bezier curves. To draw these, you have to calculate whether the curve intercepts each pixel (which requires some floating-point arithmetic for each pixel) and set it to the font color if it does. Antialiasing makes this even worse. On something like OS X, which does sub-pixel antialiasing, the curve is evaluated at small increments along its length and the pixel values are set depending on the amount of the curve that intercepts the sub-pixels. If a pixel is entirely under the curve, it will be black. If the curve goes over part of the pixel, then it will be red or blue, depending on the part of the pixel that it colors. Some additional tricks are required to make sure that the average color is the font color.
Doing this for every single character in a page of text takes quite a lot of CPU time. There are some neat tricks you can do on a modern GPU to make it faster. A couple of years ago, for example, a paper from Microsoft Research described how you could just render each Bezier as two triangleswith the two ends and one of the control points as vertexesand then use a shader program on the GPU to tidy them up. Apple used a simpler approach. Each glyph is rendered once for each size that it is used and then cached. It is then composited into the window's buffer where the glyph is needed. This is much faster and has the advantage that it can all be done on the GPU, freeing up the CPU for working out what to draw rather than having to handle the mechanics of drawing. The XRender extension in X.org uses the same mechanism.
This evolution may seem familiar. Quartz GL does for text exactly the same thing that Quartz did for windows. It's a good rule of thumb for system design that the most useful abstractions are recursive. Processes as virtual CPUs were then further abstracted by adding threads inside them. X11 supported windows containing windows from the start. OpenGL let you render to window on the screen originally, but then let you render to a texture which could be used in other OpenGL programs. It's not surprising that the evolution of Quartz should follow the same path.