As the documentation mentions, a transparency layer allows subsequent drawing to be rendered in a separate, fully transparent buffer before being composited to the destination context. In the absence of a clipping region, this buffer is the same size as the destination context, requiring a context-sized buffer regardless of the actual drawing bounds. Creating a transparency layer for a small section of content, then drawing this layer in a window, for example, results in a window-sized buffer for the layer. When the layer is composited into the destination, the entire buffer must be composited — CoreGraphics doesn’t keep track of where the actual drawing is.
This, of course, is slow, especially for several transparency layers.
To help speed things up, clip the context to the bounds of any drawing in a transparency layer before beginning the transparency layer, such as below:
CGRect artRect = CGRectMake(50,50,100,50); CGContextClipToRect(context, artRect); CGContextBeginTransparencyLayer(context, NULL); /* Draw layer content here */ CGContextEndTransparencyLayer(context);
I’ve created a demonstration program to illustrate the effects of clipped vs. unclipped transparency layers. To see the effects, open Quartz Debug (/Developer/Applications/Graphics Tools/Quartz Debug.app) and turn on “Flash screen updates.” Then, open the Transparency Layer program. There are two windows, the left showing the drawing without clipping and the right clipping to the approximate art bounds. The views are redrawing four times per second. Notice that the unclipped view redraws its entire content while the clipped view redraws only the actual art.
-[NSView setNeedsDisplayInRect:] clips the drawing to the specified rect.