[EGL] Added support for desktop GL rendering

On Linux, EGL can be used to initialize a desktop GL context.
This is especially true on KMS, Wayland and Mir.
This commit is contained in:
thefiddler 2014-06-25 09:35:20 +02:00
parent 5da5ac0fa7
commit d8adf92feb
3 changed files with 53 additions and 4 deletions

View file

@ -41,6 +41,13 @@ namespace OpenTK.Platform.Egl
using EGLSurface = IntPtr;
using EGLClientBuffer = IntPtr;
enum RenderApi
{
ES = Egl.OPENGL_ES_API,
GL = Egl.OPENGL_API,
VG = Egl.OPENVG_API
}
[Flags]
enum RenderableFlags
{
@ -229,7 +236,7 @@ namespace OpenTK.Platform.Egl
[DllImportAttribute("libEGL.dll", EntryPoint = "eglBindAPI")]
[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool BindAPI(int api);
public static extern bool BindAPI(RenderApi api);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryAPI")]
public static extern int QueryAPI();

View file

@ -60,7 +60,12 @@ namespace OpenTK.Platform.Egl
// Select an EGLConfig that matches the desired mode. We cannot use the 'mode'
// parameter directly, since it may have originated on a different system (e.g. GLX)
// and it may not support the desired renderer.
Renderable = major > 1 ? RenderableFlags.ES2 : RenderableFlags.ES;
Renderable = RenderableFlags.GL;
if ((flags & GraphicsContextFlags.Embedded) != 0)
{
Renderable = major > 1 ? RenderableFlags.ES2 : RenderableFlags.ES;
}
Mode = new EglGraphicsMode().SelectGraphicsMode(window,
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
@ -76,6 +81,13 @@ namespace OpenTK.Platform.Egl
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : IntPtr.Zero, attrib_list);
MakeCurrent(window);
RenderApi api = (Renderable & RenderableFlags.GL) != 0 ? RenderApi.GL : RenderApi.ES;
Debug.Print("[EGL] Binding rendering API {0}.", api);
if (!Egl.BindAPI(api))
{
Debug.Print("[EGL] Failed to bind rendering API. Error: {0}", Egl.GetError());
}
}
public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,

View file

@ -28,14 +28,16 @@
#endregion
using System;
using System.Diagnostics;
using OpenTK.Graphics;
namespace OpenTK.Platform.Egl
{
class EglUnixContext : EglContext
{
readonly IntPtr ES1 = OpenTK.Platform.X11.DL.Open("libGLESv1_CM", X11.DLOpenFlags.Lazy);
readonly IntPtr ES2 = OpenTK.Platform.X11.DL.Open("libGLESv2", X11.DLOpenFlags.Lazy);
IntPtr GL = OpenTK.Platform.X11.DL.Open("libGL", X11.DLOpenFlags.Lazy);
IntPtr ES1 = OpenTK.Platform.X11.DL.Open("libGLESv1_CM", X11.DLOpenFlags.Lazy);
IntPtr ES2 = OpenTK.Platform.X11.DL.Open("libGLESv2", X11.DLOpenFlags.Lazy);
public EglUnixContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
int major, int minor, GraphicsContextFlags flags)
@ -59,11 +61,19 @@ namespace OpenTK.Platform.Egl
{
return X11.DL.Symbol(ES2, function);
}
else if ((renderable & RenderableFlags.GL) != 0 && GL != IntPtr.Zero)
{
return X11.DL.Symbol(GL, function);
}
return IntPtr.Zero;
}
protected override void Dispose(bool manual)
{
if (GL != IntPtr.Zero)
{
X11.DL.Close(GL);
}
if (ES1 != IntPtr.Zero)
{
X11.DL.Close(ES1);
@ -73,7 +83,27 @@ namespace OpenTK.Platform.Egl
X11.DL.Close(ES2);
}
GL = ES1 = ES2 = IntPtr.Zero;
base.Dispose(manual);
}
public override void LoadAll()
{
// Modern unices can use EGL to create
// both GL and ES contexts, so we need
// to load all entry points. This is
// especially true on KMS, Wayland and Mir.
Stopwatch time = Stopwatch.StartNew();
new OpenTK.Graphics.OpenGL.GL().LoadEntryPoints();
new OpenTK.Graphics.OpenGL4.GL().LoadEntryPoints();
new OpenTK.Graphics.ES11.GL().LoadEntryPoints();
new OpenTK.Graphics.ES20.GL().LoadEntryPoints();
new OpenTK.Graphics.ES30.GL().LoadEntryPoints();
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
}
}
}