Transparency Layer Slowdowns
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.
Finally, using -[NSView setNeedsDisplayInRect:]
clips the drawing to the specified rect.
1 comments:
Pavel at 2012-10-18 10:17:11 -0400
I found your post 4 years later but it helped me a lot to get an idea what's wrong with my iOS app. I was just drawing some icons using transparency layer and it was terribly slow... thanks for the tip, now my app is fast as it should be :)