Introduction of gl.Context into x/mobile/gl

With golang.org/cl/13431 I introduced a gl.Context object to carry what had been functions as methods. In retrospect I should have provided more warning about this change, as it requires users change their code.

So I’ll try out this new forum as a place to publicize it, and to try and explain why I made the change.

The old gl package assumed a single process-global context. This is fine for straightforward mobile apps, which only have one window. But it is problematic for a complex app (possibly a 3D engine) that wants to have a separate background goroutine loading textures. It is also incompatible with x/exp/shiny, in which a desktop process can have multiple windows, each of which would ideally have its own GL context.

As an extra benefit, other packages can implement gl.Context, which could provide support for systems we don’t want to merge into an x/mobile package. (For example, gopherjs is pretty cool and could use the gl package, but it seems like the gl package would have to find a new repository before that would make sense. Now something compatible can be implemented somewhere else without us having to work out all the details around what package goes where.)

Any solution that kept the package functions would either have had to serialize context access (which mostly defeats the value of multiple contexts) or replicate the functions as both package functions and gl.Context methods. I opted for just methods to remove the risk of accidentally calling a function from the wrong place and using the wrong context. (There are a lot of subtle bugs possible when you can jump between contexts that can take a long time to appear and be hard to debug.)

The change to user’s code looks something like this:

Before:

import "golang.org/x/mobile/gl"

func start() {
          buf := gl.CreateBuffer()
          ...
}

After:

import "golang.org/x/mobile/gl"

func start(glctx gl.Context) {
          buf := glctx.CreateBuffer()
          ...
}

// Aquire the glctx value from x/mobile/event/lifecycle.

For now, a gl.Context instance is provided by x/mobile/app and x/exp/shiny via a lifecycle event. This will probably change in the future, we would like to have an app.GL() method. But we cannot do that without replacing the Events channel with a NextEvent function (so the state of the App object can match the current event). I’ll probably hold off on that change until the new year when Nigel is back, unless some compelling need arises.

Once the design of this gl package stabilizes (and I think we are getting close), I intend to auto-generate a lot of it from a spec, and then attempt to use the auto-generator to go after Vulkan bindings.

13 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.