This adds a mechanism for running generic operations at specific points
of the frame execution. This can be used by any part of the code an not
just Lua since it simply executes std::functions. It also adds an
"execution context" concept that specifies in which situation an
operation should be executed.
This is then used by the Lua Coroutines code for resuming coroutines at
specific points instead of always when the awaited promise resolves.
The original OpenGL Core changes only used a single vertex array object
for specifying the data layout of our vertex data. This uses the OpenGL
extension GL_ARB_vertex_attrib_binding to extend that so that each
vertex_layout uses a separate vertex array object which should improve
performance by reducing the CPU overhead while switching the vertex
layout. Since we need to use offsets into the vertex buffers at some
points this can not be done with the core functions since those do not
support specifying an offset when binding a vertex buffer.
GL_ARB_vertex_attrib_binding does support that and also features an
improved API for specifying the vertex layout. If that extension is not
available then the rendering engine will fall back to the current code.
In CPU intensive scenes I observed a frametime improvement of 1-2 ms.