--- /dev/null
+using System;
+using OpenTK.Graphics;
+using OpenTK.Platform.Windows;
+
+namespace OpenTK.Platform.Egl
+{
+ using EGLSurface = IntPtr;
+ /// <summary>
+ /// A window info for angle.
+ /// </summary>
+ public interface IAngleWindowInfo : IWindowInfo
+ {
+ /// <summary>
+ /// Query the underlying platform pointer / handle for this window's
+ /// default surface or IntPtr.Zero
+ /// </summary>
+ IntPtr QuerySurfacePointer();
+ /// <summary>
+ /// Create an additional rendering surface that shares the display
+ /// of this window.
+ /// </summary>
+ /// <param name="width">width in pixels</param>
+ /// <param name="height">height in pixels</param>
+ /// <returns>A reference to the new surface</returns>
+ EGLSurface CreateSurface(int width, int height);
+ /// <summary>
+ /// Destroy a surface created with CreateSurface and clears the passed reference.
+ /// </summary>
+ /// <param name="surface">Reference to the surface.</param>
+ void DestroySurface(ref EGLSurface surface);
+ /// <summary>
+ /// MakeCurrent the custom surface created with CreateSurface.
+ /// </summary>
+ /// <param name="surface">Reference to the surface.</param>
+ void MakeCurrent(EGLSurface surface);
+ /// <summary>
+ /// Query the underlying platform pointer / handle for an EGLSurface
+ /// created with CreateSurface.
+ /// </summary>
+ /// <param name="surface"></param>
+ IntPtr QuerySurfacePointer(EGLSurface surface);
+ }
+
+ internal interface IAngleWindowInfoInternal : IAngleWindowInfo
+ {
+ IWindowInfo PlatformWindow { get; }
+ IntPtr Display { get; }
+ IntPtr Surface { get; }
+ EglContext EglContext { get; set; }
+ EglWindowInfo EglWindowInfo { get; set; }
+ IntPtr DeviceContext { get; }
+ }
+
+ internal class AngleWindowInfo : IAngleWindowInfoInternal
+ {
+ private readonly IWindowInfo _platform_window;
+ private bool _disposed;
+
+ public AngleWindowInfo(IWindowInfo platform_window)
+ {
+ _platform_window = platform_window;
+ }
+
+ public IWindowInfo PlatformWindow
+ {
+ get { return _platform_window; }
+ }
+
+ public IWindowInfo WindowInfo
+ {
+ get { return EglWindowInfo; }
+ }
+
+ public IntPtr DeviceContext
+ {
+ get
+ {
+ var win_win = _platform_window as WinWindowInfo;
+ if (win_win != null)
+ {
+ return win_win.DeviceContext;
+ }
+ return IntPtr.Zero;
+ }
+ }
+
+ public EglContext EglContext { get; set; }
+ public EglWindowInfo EglWindowInfo { get; set; }
+
+ public IntPtr Display
+ {
+ get { return EglWindowInfo.Display; }
+ }
+
+ public IntPtr Surface
+ {
+ get { return EglWindowInfo.Surface; }
+ }
+
+ public void Dispose()
+ {
+ Dispose(false);
+ }
+
+ public IntPtr Handle
+ {
+ get { return _platform_window.Handle; }
+ }
+
+ ~AngleWindowInfo()
+ {
+ Dispose(true);
+ }
+
+ private void Dispose(bool called_from_finalizer)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+ if (!called_from_finalizer)
+ {
+ _platform_window.Dispose();
+ }
+ // dispose unmanaged
+
+ _disposed = true;
+ GC.SuppressFinalize(this);
+ }
+
+ public IntPtr QuerySurfacePointer()
+ {
+ return QuerySurfacePointer(Surface);
+ }
+
+ public EGLSurface CreateSurface(int width, int height)
+ {
+ IntPtr surface;
+ EglWindowInfo.CreatePbufferSurface(
+ EglContext.GraphicsMode.Index.Value,
+ width, height,
+ out surface);
+ return surface;
+ }
+
+ public void DestroySurface(ref EGLSurface surface)
+ {
+ EglWindowInfo.DestroySurface(ref surface);
+ }
+
+ public void MakeCurrent(EGLSurface surface)
+ {
+ Egl.MakeCurrent(Display, surface, surface, EglContext.HandleAsEGLContext);
+ }
+
+ public IntPtr QuerySurfacePointer(IntPtr surface)
+ {
+ if (UsesDirect3DBackend())
+ {
+ return QuerySurfacePointer(surface,
+ Egl.EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE);
+ }
+ return IntPtr.Zero;
+ }
+
+ private IntPtr QuerySurfacePointer(IntPtr surface, int attrib)
+ {
+ IntPtr surface_pointer;
+ if (Egl.QuerySurfacePointerANGLE(
+ Display, surface, attrib, out surface_pointer))
+ {
+ return surface_pointer;
+ }
+ return IntPtr.Zero;
+ }
+
+ private bool UsesDirect3DBackend()
+ {
+ var d3d_flags = GraphicsContextFlags.AngleD3D9 | GraphicsContextFlags.AngleD3D11;
+ return ((EglContext.GraphicsContextFlags & d3d_flags) != 0);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+#region License
+
+//
+// The Open Toolkit Library License
+//
+// Copyright (c) 2006 - 2015 the Open Toolkit library.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+// the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#endregion
+
+using System;
+using OpenTK.Graphics;
+using OpenTK.Input;
+
+namespace OpenTK.Platform.Egl
+{
+ internal class EglAnglePlatformFactory : PlatformFactoryBase
+ {
+ private readonly IPlatformFactory _platform_factory;
+ #region Public Members
+
+ public EglAnglePlatformFactory(IPlatformFactory platform_factory)
+ {
+ _platform_factory = platform_factory;
+ }
+
+ public override INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode,
+ GameWindowFlags options, DisplayDevice device)
+ {
+ return _platform_factory.CreateNativeWindow(x, y, width, height, title,
+ mode, options, device);
+ }
+
+ public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
+ {
+ return _platform_factory.CreateDisplayDeviceDriver();
+ }
+
+ public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window,
+ IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
+ {
+ var angle_window = (IAngleWindowInfoInternal) window;
+ var egl_window = CreateWindowInfo(angle_window, major, flags);
+ var egl_context = new EglWinContext(mode, egl_window, shareContext, major, minor, flags);
+ angle_window.EglContext = egl_context;
+ return egl_context;
+ }
+
+ public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window,
+ IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
+ {
+ var angle_window = (IAngleWindowInfoInternal) window;
+ var egl_window = CreateWindowInfo(angle_window, major, flags);
+ var egl_context = new EglWinContext(handle, egl_window, shareContext, major, minor, flags);
+ angle_window.EglContext = egl_context;
+ return egl_context;
+ }
+
+ public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
+ {
+ return (GraphicsContext.GetCurrentContextDelegate)delegate
+ {
+ return new ContextHandle(Platform.Egl.Egl.GetCurrentContext());
+ };
+ }
+
+ public override IKeyboardDriver2 CreateKeyboardDriver()
+ {
+ return _platform_factory.CreateKeyboardDriver();
+ }
+
+ public override IMouseDriver2 CreateMouseDriver()
+ {
+ return _platform_factory.CreateMouseDriver();
+ }
+
+ public override IJoystickDriver2 CreateJoystickDriver()
+ {
+ return _platform_factory.CreateJoystickDriver();
+ }
+
+ #endregion
+
+ #region Private Members
+
+ private static bool FlagEnabled(GraphicsContextFlags flags, GraphicsContextFlags flag)
+ {
+ return (flags & flag) != 0;
+ }
+
+ private EglWindowInfo CreateWindowInfo(IAngleWindowInfoInternal window_info,
+ int major, GraphicsContextFlags flags)
+ {
+ var egl_display = GetAngleDisplay(window_info.DeviceContext, flags, major);
+ var egl_window = new EglWindowInfo(window_info.Handle, egl_display);
+ window_info.EglWindowInfo = egl_window;
+ return egl_window;
+ }
+
+ private IntPtr GetAngleDisplay(IntPtr dc, GraphicsContextFlags flags, int major)
+ {
+ // default to D3D9 for ES2, but use D3D11 for ES3 as required by Angle.
+ var platform_type = major == 2
+ ? Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9
+ : Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11;
+ if (FlagEnabled(flags, GraphicsContextFlags.AngleD3D11))
+ {
+ platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11;
+ }
+ else if (FlagEnabled(flags, GraphicsContextFlags.AngleD3D9))
+ {
+ platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9;
+ }
+ else if (FlagEnabled(flags, GraphicsContextFlags.AngleOpenGL))
+ {
+ platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_OPENGL;
+ }
+ else
+ {
+ // make sure the correct flag is set.
+ switch (platform_type)
+ {
+ case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9:
+ flags |= GraphicsContextFlags.AngleD3D9;
+ break;
+ case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11:
+ flags |= GraphicsContextFlags.AngleD3D11;
+ break;
+ case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_OPENGL:
+ flags |= GraphicsContextFlags.AngleOpenGL;
+ break;
+ }
+ }
+
+ var attribs = new[]
+ {
+ Platform.Egl.Egl.PLATFORM_ANGLE_TYPE, platform_type,
+ Platform.Egl.Egl.PLATFORM_ANGLE_MAX_VERSION_MAJOR, Platform.Egl.Egl.DONT_CARE,
+ Platform.Egl.Egl.PLATFORM_ANGLE_MAX_VERSION_MINOR, Platform.Egl.Egl.DONT_CARE,
+ Platform.Egl.Egl.PLATFORM_ANGLE_DEVICE_TYPE, Platform.Egl.Egl.PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE,
+ Platform.Egl.Egl.NONE
+ };
+
+ return Platform.Egl.Egl.GetPlatformDisplay(
+ Platform.Egl.Egl.PLATFORM_ANGLE,
+ dc,
+ attribs
+ );
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file