views:

783

answers:

1

For a custom UIView I've implemented, I want to display some graphics in multiple CALayers that are added as subviews of my UIViews layer.

I cannot use my UIView as the delegate for the sublayers. A UIView may only be the delegate for one layer and that is the layer the UIView already has from the get go. Since I also didn't want to subclass CALayer or create a dedicated delegate, I thought that doing my rendering to an image and setting that as the sublayer's content would be a good idea.

Initial experiments show that I can make the whole thing work by going through something like this:

-(void) initCustomLayer: {
    UIGraphicsBeginImageContext(self.bounds.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext ();
    // ... do the drawing in ctx ...
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    customLayer = [[CALayer alloc] init];
    customLayer.bounds.size = self.bounds.size;
    customLayer.contents = image.CGImage;
    [self.layer addSublayer customLayer];
    [customLayer release];
}

In the documentation it says that using a CGLayer for offscreen rendering is the preferred way of doing offscreen rendering. So I would like to do the drawing in a CGLayer.

What I can't seem to find out is whether there is a way of setting the CALayer's content from the CGLayer?

Is this possible and does it even make sense? Should I just stop worrying and go with the UIImage/CGImageRef based approach?

+1  A: 

Although the documentation doesn't say that CALayers work similarly to CGLayers, the Graphics and Imaging Overview says that Core Animation is “GPU-accelerated”, which I think we can safely interpret as saying that it puts CALayer content on the video card whenever it can. That's what CGLayer does, too.

So, I would expect a CALayer backed by a CGImage to provide roughly the same performance benefit as a CGLayer, as long as you don't change out the image frequently.

If you want to be absolutely sure that you'll get the same caching-as-textures behavior as CGLayer, make a subclass of CALayer that has a property to hold a CGLayer, and responds to drawInContext: by drawing the CGLayer.

The catch is that if CALayer caches the dynamically-drawn content on the video card (and I don't know whether it does), you'll have it there twice, wasting video memory. For all you and I know, the context CALayer gives you to draw in is a CGLayer context.

Peter Hosey