glVertexAttribPointer, glBufferSubData,glUniform4fv... basics...

For functions like glVertexAttribPointer, glBufferSubData,glUniform4fv - these all take pointers as arguments to data that is stored in the client side. At what point am I free to start modifying (or freeing) that data? From what I can tell glBufferSubData copies the data immediately, so I can free my own copy immediately (right?) But, what about the other functions I mentioned? Is it safe to free (or overwrite) the data immediately after calling them? If not, is it safe immediately after glDrawArrays (or glDrawElements)? Or might it not be safe for a while even after that?

A good question. Allow me to quote from the OpenGL Wiki article on synchornization:

To your question gonkgonk, let me also mention one gotcha on the above comment, as it is not legacy. It is applicable regardless.

Whether you’re using client arrays or VBOs (with binding or bindless), the “*Pointer” calls (e.g. glVertexAttribPointer) store off a pointer value. That pointer value is not “evaluated” until the batch call(s) that follow for which that vertex attribute is enabled.

In the case of client arrays batches, that pointer is a client side pointer (CPU pointer). In the case of VBO batches, that pointer is a server side pointer (GPU/driver pointer).

As a for instance, if using VBOs to render a batch, you can’t stream a few vtx attribs into a VBO, register them with “*Pointer” calls, then orphan the VBO (i.e. reallocate the VBO), and then stream a few more vtx attribs into a VBO, registering them with a “*Pointer” call. The orphan operation just messed up the memory under your first few vtx attrib bindings. Those pointers aren’t evaluated until the batch draw call(s).

(NOTE: I use the expression "Pointer" loosely here, as with bindless batches the corresponding call that provides the pointer is glBufferAddressRangeNV, not glVertexAttribPointer.)