Currently the proc pointer for each gl proc is cached in a static mut variable. This works fine if there's only one context active during the lifetime of the program, but will break pretty spectacularly if the user tries to create multiple contexts that have incompatible proc pointers. In order to support multiple contexts we'll need to instead provide a container type that caches the proc pointers. This allows us to have one cache per context, ensuring that the user can safely create multiple incompatible contexts at once.
Achieving this will require that we rework how the procs are declared. Current we use the gl_proc! macro to declare each proc separately, with one macro invocation per gl proc. In order to be able to generate a single struct that contains all the procs we'll need change this to a single macro invocation for all the procs (ironically this is what we were doing initially). gl_proc! should be reworked to take an arbitrary number of procs, and then generate a struct ProcCache instead of a module for each cache. It should be possible to instantiate a ProcCache with a Context object, though you should be able to create a context without a proc cache (if you're a masochist).
ProcCache should expose a public fn for each proc, but we want each proc to also have helper methods like load() and is_loaded(). To achieve this we could make each proc public, but rather than exposing them as raw pointer types we do something like this:
This would allow us to call the proc directly (cache.bind_buffer()) and access the helpers associated with each proc (cache.bind_buffer.is_loaded()). This is far more complex in terms of code generation but it solves the problem while retaining ergonomics and all functionality.
Removing the static proc caches also improves thread-safety by removing the ability to share a context between threads. That said, it's not clear at this point thread-safety guarantees bootstrap-gl should be providing so this may ultimately be an ill-advised change in that regard.
Currently the proc pointer for each gl proc is cached in a
static mut
variable. This works fine if there's only one context active during the lifetime of the program, but will break pretty spectacularly if the user tries to create multiple contexts that have incompatible proc pointers. In order to support multiple contexts we'll need to instead provide a container type that caches the proc pointers. This allows us to have one cache per context, ensuring that the user can safely create multiple incompatible contexts at once.Achieving this will require that we rework how the procs are declared. Current we use the
gl_proc!
macro to declare each proc separately, with one macro invocation per gl proc. In order to be able to generate a single struct that contains all the procs we'll need change this to a single macro invocation for all the procs (ironically this is what we were doing initially).gl_proc!
should be reworked to take an arbitrary number of procs, and then generate a structProcCache
instead of a module for each cache. It should be possible to instantiate aProcCache
with aContext
object, though you should be able to create a context without a proc cache (if you're a masochist).ProcCache
should expose a public fn for each proc, but we want each proc to also have helper methods likeload()
andis_loaded()
. To achieve this we could make each proc public, but rather than exposing them as raw pointer types we do something like this:This would allow us to call the proc directly (
cache.bind_buffer()
) and access the helpers associated with each proc (cache.bind_buffer.is_loaded()
). This is far more complex in terms of code generation but it solves the problem while retaining ergonomics and all functionality.Removing the static proc caches also improves thread-safety by removing the ability to share a context between threads. That said, it's not clear at this point thread-safety guarantees bootstrap-gl should be providing so this may ultimately be an ill-advised change in that regard.