CALayers v. CGLayers, or, Which Layer, Player?

What’s the Deal?

An evergreen source of confusion for developers new to graphics on iOS is the existence of multiple Apple-provided graphics frameworks, and multiple “layer” objects within those frameworks.  We’re told to use Core Animation for compositing and animation, and Core Graphics for two-dimensional bitmap drawing (as well as rarer things like low-level text layout and PDF rendering).  Core Animation’s basic class is the CALayer, and Core Graphics has its own CGLayer object.  Surely they are analogous!  Might we construct an SAT-style comparison?

CALayer : CA :: CGLayer : CG?

Despite one’s intuition, not even close.  This is just an unfortunate naming scheme that has wasted countless developer hours and spawned innumerable forum threads.  Let’s take a look at the differences.

CALayer

Yup, this one you’ll want to know about.  CALayer is one of the most important classes on iOS, right up there with UITableView.  The entire windowing system on iOS runs on top of Core Animation; this means that every single thing you see on screen lives in a CALayer.  They can be positioned, transformed in three(ish*) dimensional space, and a bunch of other neat stuff.  Perhaps most importantly, they can be filled with arbitrary bitmap content – and this is where the confusion sets in.  That bitmap content is often provided by Core Graphics!  When putting Core Graphics content into a CALayer, surely a CGLayer is the right way to go?

No.

Haven’t you been listening?

CGLayer

CGLayers are super cool drawing optimization objects – on the desktop.  Their main use is to cache drawing stuff – either bits or, for instance, PDF drawing commands – for re-use.  They make things like drawing a sprite for a game much faster, for a few reasons.  First, their contents can be stored on the graphics card, meaning that drawing them to the screen is super fast as compared to a bitmap stored in memory.  Second, they are constructed with a specific drawing context in mind, so they can optimize their contents for the format of that context.  And third, since drawing them into a context is so much faster than drawing an arbitrary bitmap, they can enable high-speed animation the Core Graphics way (re-rendering the screen each frame).

Thing is, these advantages don’t carry over to iOS.  When you set a CALayer’s contents, or draw into it, that bitmap is always stored on the graphics card.  That’s just the nature of Core Animation, as a framework built on top of OpenGL.  And practically speaking, there is really only one format you’ll be drawing into – that’s the nature of a closed ecosystem of devices with one optimal pixel format.  (If your app constructs PDFs on the device, this is not the blog post for you.)  As far as animation goes, well, it’s called Core Animation for a reason.  What it comes down to is that in iOS, using a CGLayer buys you nothing but additional complexity.

TL;DR

Don’t use CGLayers on iOS.

* a subject for another post!

About Joel Kin

Developing on Apple platforms for, holy shit, like twenty years now. Find me on linkedin and twitter. My personal website is joelk.in.
This entry was posted in Explanation and tagged , , , . Bookmark the permalink.