When should I use which of these? Is it simply that you should use contexts unless you need to tune for performance?
Contexts do two things: let you draw into an image other than the display's frame buffer, and save/restore the various global drawing settings like color, draw mode, and line width. One example of where you'd use push/popContext() is if you're writing a function that does some drawing and you need to change the drawing state. You'll want to restore the state when you're done so that it doesn't interfere with code outside the function, so you call pushContext() at the beginning of your function and popContext() at the end.
lock/unlockFocus() is nearly identical to push/popContext() but lockFocus() pops any other contexts from the stack that were pushed with previous lockFocus() calls before pushing its own. That means you can have a bunch of lockFocus() calls in a row without worrying about unlocking them until the very last one. Honestly, I don't remember what problem that's supposed to solve.
Pushing and popping contexts has a bit of overhead, has to copy all those parameters in and out, so maybe a function to change the drawing target without dealing with the confusing stack stuff would be useful. I'll file that.. and either consider it for a future release or completely forget about it.
Ha ha ha! That made me chuckle.