* This lets us distinguish framebuffer object 1 on context A from
FBO 1 on context B.
* At the moment we assume that all shareable objects are shared between
all contexts. I think this is sensible and fairly common, but it will
break if some contexts don't share as the objects will alias.
* This is really a spot optimisation but I have a feeling it might be
useful for more programs.
* If a program uses a single VAO and updates the attrib pointers/enables
and disables them, then this will prevent an unbounded number of chunks
building up pointlessly while READING and pushing into the record.
* A 'better' fix for this would be to gather pointer/enabled state as
initial contents and not tracking any of this except for in CAPFRAME,
but that isn't happening at the moment.
* This could be improved and moved further down, not all functions would
need a lock (only things modifying shared resources), but it suffices
for now.
* It was the wrong way around. When not capturing frame we save uniform
sets to the program's record, but really we shouldn't do this and we
should grab these as 'initial state' of the program resources
* Even if the app only queries some subset of extensions, we may need
more (e.g. need the DSA extensions). GetRealFunctions does a
PopulateHooks which will fill out the extensions that we need.
* Normal selector functions are implemented via these, which requires
EXT_direct_state_access to be available, but this isn't hard to work
around with some wrapper functions should that become necessary.
* Sync objects need special handling because the identifier is an opaque
pointer and so we can't use the existing GLResource stuff. Instead to
handle this, we assign a GLuint ourselves and keep a mapping around
to map GLuint<->GLsync. Everything else works as usual from the GLuint
* Remove legacy wrapped functions that were only hacked-in to get
glxgears working as a proof of concept.
* Split out groups of wrapped functions into separate files by type