NOTE: after Metal and Vulkan support lands, we can potentially simplify
the Driver API by removing some of the old VertexBuffer entry points.
This introduces a new API-level object called `BufferObject`, and a new
backend-level object called `HwBufferObject`. This encapsulates a single
VBO. It's especially useful when clients need to share data between
multiple VertexBuffer objects. (e.g. for morphing).
In the future, buffer objects could perhaps be used for non-vertex data
(e.g. for compute).
The existing `VertexBuffer` class can now be configured to use buffer
objects by calling `enableBufferObjects` on the builder. By default its
API is unchanged. If buffer objects are enabled, then clients should use
`setBufferObjectAt` (which takes a buffer object) rather than
`setBufferAt` (which takes CPU data).
OpenGL is the trickiest backend for this, due to existence of VAOs.
The implementation in this PR uses a version-tracking scheme to
figure out when to update the VAO.