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 OpenTK.Graphics;
|
||||
using System.Diagnostics;
|
||||
|
||||
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