mono/opentk — pull request #9 by dellis1972 (2014-07-21 10:32:35+00:00)
Title: [OpenTK.Android] Support opengl context sharing across threads

Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=2139

Added support for creating an additional opengl context.
This is accomplished by creating a PBuffer surface to which
the new context can be attached. The PBuffer should be
created with a fixed power of 2 size for maximum compatability
across devices. The actual size of the PBuffer does not really
matter as the background context is not usually used for
rendering but for loading graphical assets such as textures
and shaders. If the device does not support PBuffers then
a secondary context will not work. Support for PBuffers is
checked by querying the SurfaceType attribute in the Graphics
Mode config and ensuring that the PBUFFER_BIT is set. If
PBuffers are not supported or when creating the new PBuffer
it returns a NoSurface value, an exception will be thrown.

Note that for GLES 1.1 some devices report that they support
PBuffers but actually lock up when trying to use them. This
seems limited to mainly NVIDIA chips. However this does not
seem to be the case for GLES 2.0+

With the new PBuffer surface, the context can also be created.
The context should use the same config and attributes as the
main context otherwise the context creation will fail with
an BAD_MATCH error. If for some reason the seconday context
cannot be created an exception will be thrown.

To create a seconday context use the following code

backgroundContext = new AndroidGraphicsContext (GraphicsMode, WindowInfo, GraphicsContext, this.ContextRenderingApi, GraphicsContextFlags.Embedded);

To use the background context you MUST first make sure that
the primary context is not going to render. This can be accomplished
by using a sync/lock object. Next you MUST clear the current context
using

backgroundContext.MakeCurrent (null);

If this is not done any attempt to use the background context will
fail. While skipping this step might work on some GPU's its
better to do it to make sure you don't get errors. Next you can
call

backgroundContext.MakeCurrent(WindowInfo);

and use the context. I would as recommend calling MakeCurrent(null)
again at the end of the background processing just to make
sure everything is ready for the primary context to start again.