Initial implementation.
This commit is contained in:
parent
46632376a8
commit
f031e34ecf
3 changed files with 277 additions and 40 deletions
|
@ -28,13 +28,141 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using OpenTK.Graphics;
|
using OpenTK.Graphics;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace OpenTK.Platform.Egl
|
namespace OpenTK.Platform.Egl
|
||||||
{
|
{
|
||||||
public class EglContext /*: IGraphicsContext*/
|
class EglContext : IGraphicsContext
|
||||||
{
|
{
|
||||||
public EglContext()
|
#region Fields
|
||||||
|
|
||||||
|
EglWindowInfo window;
|
||||||
|
EGLContext context;
|
||||||
|
GraphicsMode mode;
|
||||||
|
bool vsync = true; // Default vsync value is defined as 1 (true) in EGL.
|
||||||
|
bool disposed = false;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public EglContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||||
|
int major, int minor, GraphicsContextFlags flags)
|
||||||
|
{
|
||||||
|
if (mode == null)
|
||||||
|
throw new ArgumentNullException("mode");
|
||||||
|
if (window == null)
|
||||||
|
throw new ArgumentNullException("window");
|
||||||
|
|
||||||
|
EglContext shared = (EglContext)sharedContext;
|
||||||
|
|
||||||
|
Egl.Initialize(window.Display, out major, out minor);
|
||||||
|
|
||||||
|
EGLConfig config = new EGLConfig(mode.Index);
|
||||||
|
|
||||||
|
if (window.Surface.Handle == EGLSurface.None.Handle)
|
||||||
|
window.CreateWindowSurface(config);
|
||||||
|
|
||||||
|
context = Egl.CreateContext(window.Display, config, shared.context, null);
|
||||||
|
MakeCurrent(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IGraphicsContext Members
|
||||||
|
|
||||||
|
public void SwapBuffers()
|
||||||
|
{
|
||||||
|
Egl.SwapBuffers(window.Display, window.Surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MakeCurrent(IWindowInfo window)
|
||||||
|
{
|
||||||
|
EglWindowInfo egl = (EglWindowInfo)window;
|
||||||
|
Egl.MakeCurrent(egl.Display, egl.Surface, egl.Surface, context);
|
||||||
|
this.window = egl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsCurrent
|
||||||
|
{
|
||||||
|
get { return Egl.GetCurrentContext().Handle == context.Handle; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public event DestroyEvent<IGraphicsContext> Destroy;
|
||||||
|
|
||||||
|
public bool VSync
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Egl.GetSwapInterval does not exist, so store and return the current interval.
|
||||||
|
// The default interval is defined as 1 (true).
|
||||||
|
return vsync;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (Egl.SwapInterval(window.Display, value ? 1 : 0))
|
||||||
|
vsync = value;
|
||||||
|
else
|
||||||
|
Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", window.Display, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(IWindowInfo window)
|
||||||
|
{
|
||||||
|
// Do nothing.
|
||||||
|
}
|
||||||
|
|
||||||
|
public GraphicsMode GraphicsMode
|
||||||
|
{
|
||||||
|
get { return mode; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: implement this!
|
||||||
|
public bool ErrorChecking
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
set
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: cross-reference the specs. What should happen if the context is destroyed from a different
|
||||||
|
// thread?
|
||||||
|
void Dispose(bool manual)
|
||||||
|
{
|
||||||
|
if (!disposed)
|
||||||
|
{
|
||||||
|
if (manual)
|
||||||
|
{
|
||||||
|
Egl.MakeCurrent(window.Display, window.Surface, window.Surface, EGLContext.None);
|
||||||
|
Egl.DestroyContext(window.Display, context);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, context.Handle);
|
||||||
|
}
|
||||||
|
disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~EglContext()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
46
Source/OpenTK/Platform/Egl/EglGraphicsMode.cs
Normal file
46
Source/OpenTK/Platform/Egl/EglGraphicsMode.cs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using OpenTK.Graphics;
|
||||||
|
|
||||||
|
namespace OpenTK.Platform.Egl
|
||||||
|
{
|
||||||
|
class EglGraphicsMode : IGraphicsMode
|
||||||
|
{
|
||||||
|
#region IGraphicsMode Members
|
||||||
|
|
||||||
|
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
|
||||||
|
{
|
||||||
|
EGLConfig[] configs = new EGLConfig[1];
|
||||||
|
int[] attribList = new int[]
{
Egl.SURFACE_TYPE, Egl.WINDOW_BIT,
Egl.RED_SIZE, color.Red,
Egl.GREEN_SIZE, color.Green,
Egl.BLUE_SIZE, color.Blue,
Egl.ALPHA_SIZE, color.Alpha,
Egl.DEPTH_SIZE, depth > 0 ? depth : Egl.DONT_CARE,
Egl.STENCIL_SIZE, stencil > 0 ? stencil : Egl.DONT_CARE,
Egl.SAMPLE_BUFFERS, samples > 0 ? 1 : 0,
Egl.SAMPLES, samples > 0 ? samples : 0,
Egl.NONE, Egl.NONE
};
|
||||||
|
|
||||||
|
// Todo: what if we don't wish to use the default display?
|
||||||
|
EGLDisplay display = Egl.GetDisplay(EGLNativeDisplayType.Default);
|
||||||
|
|
||||||
|
int num_configs;
|
||||||
|
Egl.GetConfigs(display, configs, configs.Length, out num_configs);
|
||||||
|
if (num_configs == 0)
|
||||||
|
throw new NotSupportedException("The requested GraphicsMode is not supported.");
|
||||||
|
|
||||||
|
// See what we really got
|
||||||
|
EGLConfig active_config = configs[0];
|
||||||
|
int r, g, b, a;
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.RED_SIZE, out r);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.GREEN_SIZE, out g);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.BLUE_SIZE, out b);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.ALPHA_SIZE, out a);
|
||||||
|
int d, s;
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.DEPTH_SIZE, out d);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.STENCIL_SIZE, out s);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.BLUE_SIZE, out b);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.ALPHA_SIZE, out a);
|
||||||
|
int sample_buffers;
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers);
|
||||||
|
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out samples);
|
||||||
|
|
||||||
|
return new GraphicsMode(active_config.Handle.Value, new ColorFormat(r, g, b, a), depth, stencil, sample_buffers > 0 ? samples : 0, 0, 2, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
63
Source/OpenTK/Platform/Egl/EglWindowInfo.cs
Normal file
63
Source/OpenTK/Platform/Egl/EglWindowInfo.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenTK.Platform.Egl
|
||||||
|
{
|
||||||
|
// Holds information about an EGL window.
|
||||||
|
class EglWindowInfo : IWindowInfo
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
IntPtr handle;
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLSurface surface;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructiors
|
||||||
|
|
||||||
|
public EglWindowInfo(IntPtr handle, EGLDisplay display, EGLSurface surface)
|
||||||
|
{
|
||||||
|
Handle = handle;
|
||||||
|
Display = display;
|
||||||
|
Surface = surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Public Members
|
||||||
|
|
||||||
|
public IntPtr Handle { get { return handle; } private set { handle = value; } }
|
||||||
|
|
||||||
|
public EGLDisplay Display { get { return display; } private set { display = value; } }
|
||||||
|
|
||||||
|
public EGLSurface Surface { get { return surface; } private set { surface = value; } }
|
||||||
|
|
||||||
|
public void CreateWindowSurface(EGLConfig config)
|
||||||
|
{
|
||||||
|
Surface = Egl.CreateWindowSurface(Display, config, Handle, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//public void CreatePixmapSurface(EGLConfig config)
|
||||||
|
//{
|
||||||
|
// Surface = Egl.CreatePixmapSurface(Display, config, Handle, null);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public void CreatePbufferSurface(EGLConfig config)
|
||||||
|
//{
|
||||||
|
// Surface = Egl.CreatePbufferSurface(Display, config, null);
|
||||||
|
//}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue