ioscore-graphicscalayerquartz-2dgraphicscontext

On iOS, after we create a layer from context and get the layer's context, how do these contexts relate to each other?


We can create a layer from the current graphics context and then get the layer's context:

CGContextRef context = UIGraphicsGetCurrentContext();

CGLayerRef layer = CGLayerCreateWithContext(context, 
                                            CGSizeMake(self.frame.size.width,
                                                self.frame.size.height), NULL);

CGContextRef contextOfLayer = CGLayerGetContext(layer);

So we now have 2 contexts: context and contextOfLayer. How do these two contexts relate to each other? Is contextOfLayer actually part of context and context has a array of layer context pointers? If I print out their addresses using NSLog(@"%p", ...), they have different addresses, so they are not the same object. And I think contextOfLayer doesn't affect the context stack, so is it just an independent context just kind of "exist out there" by itself?


Solution

  • It helps if you understand the rationale for CGLayer. CGLayer is meant as an optimization when you repeatedly draw the same content into a particular kind of context.

    (For instance: bitmap contexts with a particular format -- e.g. 32-bit RGBA -- or PDF contexts, etc.)

    When you create the CGLayer, you pass it the context that you intend to draw the CGLayer into. This lets the CGLayer optimize itself for that kind of context.

    Later on, if you draw the CGLayer into that context, or into a different context that has the same format, the drawing will be faster.

    If you draw a CGLayer into a context with a different format, the drawing will still work, and you will not get an error. However, it may not be any faster than it would have been if you had just drawn directly into that context.

    The documentation for CGLayerCreateWithContext says:

    context

    The graphics context you want to create the layer relative to. The layer uses this graphics context as a reference for initialization.

    This means that the layer looks at the given context as a reference. It does not necessarily mean that the context is stored within the CGLayer, or permanently referenced. It might be, but you can't tell -- it's an internal implementation detail.

    The documentation for CGLayerGetContext says

    The context that’s returned is the context for the layer itself, not the context that you specified when you created the layer.

    So you should expect that context != contextOfLayer.

    Again, the API does not specify anything about how those contexts relate to each other -- they might reference each other internally, or they might not. As users of the API we should not assume anything.

    To answer your questions specifically:

    Is contextOfLayer actually part of context and context has a array of layer context pointers?

    We don't know and we can't find out. As users of the API we shouldn't write any code that assumes one way or another.

    I think contextOfLayer doesn't affect the context stack, so is it just an independent context just kind of "exist out there" by itself?

    Yes, it is an independent context. The "context stack" in UIKit is a higher-level concept. CGLayer in CoreGraphics is a lower-level API that doesn't know anything about UIKit.