mono / opentk

OpenTK is a set of bindings to OpenGL, OpenCL and OpenAL. This is not the main repository, just a temporary import to allow Mono developers to make changes to this module. Please do not contribute changes here, contribute them to the upstream maintainers at http://www.opentk.com
http://www.opentk.com
115 stars 66 forks source link

[OpenTK.Android] Support opengl context sharing across threads #9

Closed dellis1972 closed 10 years ago

dellis1972 commented 10 years ago

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.

dellis1972 commented 10 years ago

All done

dellis1972 commented 10 years ago

@radekdoulik this should be ready to merge in now :)

radekdoulik commented 10 years ago

Ah, missed it. Thanks a lot! Merged.