Merge branch 'develop' of github.com:opentk/opentk into develop

This commit is contained in:
varon 2017-05-08 22:50:38 +02:00
commit de6a4a796f
17 changed files with 663 additions and 86 deletions

View file

@ -20,11 +20,11 @@ namespace Bind
OverridesFiles = new List<string>(); OverridesFiles = new List<string>();
} }
public string DefaultInputPath = "../../../Source/Bind/Specifications"; public string DefaultInputPath = "../../../Generator.Bind/Specifications";
public string DefaultOutputPath = "../../../Source/OpenTK/Graphics/OpenGL"; public string DefaultOutputPath = "../../../Source/OpenTK/Graphics/OpenGL";
public string DefaultOutputNamespace = "OpenTK.Graphics.OpenGL"; public string DefaultOutputNamespace = "OpenTK.Graphics.OpenGL";
public string DefaultDocPath = "../../../Source/Bind/Specifications/Docs"; public string DefaultDocPath = "../../../Generator.Bind/Specifications/Docs";
public string DefaultFallbackDocPath = "../../../Source/Bind/Specifications/Docs/GL"; public string DefaultFallbackDocPath = "../../../Generator.Bind/Specifications/Docs/GL";
public string DefaultLicenseFile = "License.txt"; public string DefaultLicenseFile = "License.txt";
public string DefaultLanguageTypeMapFile = "csharp.tm"; public string DefaultLanguageTypeMapFile = "csharp.tm";
public string DefaultKeywordEscapeCharacter = "@"; public string DefaultKeywordEscapeCharacter = "@";

View file

@ -97,6 +97,23 @@ namespace OpenTK.Graphics
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
/// </remarks> /// </remarks>
public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags)
: this(mode, window, FindSharedContext(), major, minor, flags)
{
}
/// <summary>
/// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window.
/// </summary>
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
/// <param name="shareContext">The GraphicsContext to share resources with, or null for explicit non-sharing.</param>
/// <param name="major">The major version of the new GraphicsContext.</param>
/// <param name="minor">The minor version of the new GraphicsContext.</param>
/// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param>
/// <remarks>
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
/// </remarks>
public GraphicsContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, int major, int minor, GraphicsContextFlags flags)
{ {
lock (SyncRoot) lock (SyncRoot)
{ {
@ -112,6 +129,18 @@ namespace OpenTK.Graphics
if (minor < 0) if (minor < 0)
minor = 0; minor = 0;
// Angle needs an embedded context
const GraphicsContextFlags useAngleFlag = GraphicsContextFlags.Angle
| GraphicsContextFlags.AngleD3D9
| GraphicsContextFlags.AngleD3D11
| GraphicsContextFlags.AngleOpenGL;
var useAngle = false;
if ((flags & useAngleFlag) != 0)
{
flags |= GraphicsContextFlags.Embedded;
useAngle = true;
}
Debug.Print("Creating GraphicsContext."); Debug.Print("Creating GraphicsContext.");
try try
{ {
@ -121,8 +150,6 @@ namespace OpenTK.Graphics
Debug.Print("GraphicsContextFlags: {0}", flags); Debug.Print("GraphicsContextFlags: {0}", flags);
Debug.Print("Requested version: {0}.{1}", major, minor); Debug.Print("Requested version: {0}.{1}", major, minor);
IGraphicsContext shareContext = FindSharedContext();
// Todo: Add a DummyFactory implementing IPlatformFactory. // Todo: Add a DummyFactory implementing IPlatformFactory.
if (designMode) if (designMode)
{ {
@ -133,8 +160,12 @@ namespace OpenTK.Graphics
IPlatformFactory factory = null; IPlatformFactory factory = null;
switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
{ {
case false: factory = Factory.Default; break; case false:
case true: factory = Factory.Embedded; break; factory = Factory.Default;
break;
case true:
factory = useAngle ? Factory.Angle : Factory.Embedded;
break;
} }
// Note: this approach does not allow us to mix native and EGL contexts in the same process. // Note: this approach does not allow us to mix native and EGL contexts in the same process.

View file

@ -56,6 +56,30 @@ namespace OpenTK.Graphics
/// <summary> /// <summary>
/// Indicates that this GraphicsContext is targeting OpenGL|ES. /// Indicates that this GraphicsContext is targeting OpenGL|ES.
/// </summary> /// </summary>
Embedded = 0x0004 Embedded = 0x0004,
/// <summary>
/// Indicates that this GraphicsContext is intended for offscreen rendering.
/// </summary>
Offscreen = 0x0008,
/// <summary>
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
/// and that angle-specific extensions are available.
/// </summary>
Angle = 0x0010,
/// <summary>
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
/// and uses Direct3D9 as rendering backend.
/// </summary>
AngleD3D9 = 0x0020,
/// <summary>
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
/// and uses Direct3D11 as rendering backend.
/// </summary>
AngleD3D11 = 0x0040,
/// <summary>
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
/// and uses OpenGL as rendering backend.
/// </summary>
AngleOpenGL = 0x0080,
} }
} }

View file

@ -238,7 +238,7 @@ namespace OpenTK
event EventHandler<EventArgs> WindowStateChanged; event EventHandler<EventArgs> WindowStateChanged;
/// <summary> /// <summary>
/// Occurs whenever a keybord key is pressed. /// Occurs whenever a keyboard key is pressed.
/// </summary> /// </summary>
event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown; event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown;

View file

@ -635,7 +635,7 @@ namespace OpenTK
public event EventHandler<EventArgs> IconChanged = delegate { }; public event EventHandler<EventArgs> IconChanged = delegate { };
/// <summary> /// <summary>
/// Occurs whenever a keybord key is pressed. /// Occurs whenever a keyboard key is pressed.
/// </summary> /// </summary>
public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown = delegate { }; public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyDown = delegate { };
@ -859,7 +859,7 @@ namespace OpenTK
#region OnKeyDown #region OnKeyDown
/// <summary> /// <summary>
/// Occurs whenever a keybord key is pressed. /// Occurs whenever a keyboard key is pressed.
/// </summary> /// </summary>
protected virtual void OnKeyDown(KeyboardKeyEventArgs e) protected virtual void OnKeyDown(KeyboardKeyEventArgs e)
{ {
@ -884,7 +884,7 @@ namespace OpenTK
#region OnKeyUp #region OnKeyUp
/// <summary> /// <summary>
/// Called when a keybord key is released. /// Called when a keyboard key is released.
/// </summary> /// </summary>
/// <param name="e">The <see cref="OpenTK.Input.KeyboardKeyEventArgs"/> for this event.</param> /// <param name="e">The <see cref="OpenTK.Input.KeyboardKeyEventArgs"/> for this event.</param>
protected virtual void OnKeyUp(KeyboardKeyEventArgs e) protected virtual void OnKeyUp(KeyboardKeyEventArgs e)

View file

@ -132,9 +132,11 @@
<Compile Include="Math\Matrix4x3d.cs" /> <Compile Include="Math\Matrix4x3d.cs" />
<Compile Include="Platform\Common\Hid.cs" /> <Compile Include="Platform\Common\Hid.cs" />
<Compile Include="Platform\DisplayDeviceBase.cs" /> <Compile Include="Platform\DisplayDeviceBase.cs" />
<Compile Include="Platform\Egl\AngleWindowInfo.cs" />
<Compile Include="Platform\Egl\EglException.cs" /> <Compile Include="Platform\Egl\EglException.cs" />
<Compile Include="Platform\Egl\EglUnixContext.cs" /> <Compile Include="Platform\Egl\EglUnixContext.cs" />
<Compile Include="Platform\Egl\EglWinContext.cs" /> <Compile Include="Platform\Egl\EglWinContext.cs" />
<Compile Include="Platform\Egl\EglAnglePlatformFactory.cs" />
<Compile Include="Platform\MappedGamePadDriver.cs" /> <Compile Include="Platform\MappedGamePadDriver.cs" />
<Compile Include="Platform\Windows\Bindings\HidProtocol.cs" /> <Compile Include="Platform\Windows\Bindings\HidProtocol.cs" />
<Compile Include="Platform\Windows\WinInputBase.cs" /> <Compile Include="Platform\Windows\WinInputBase.cs" />

View file

@ -27,6 +27,7 @@ using Android.Views;
using Android.Runtime; using Android.Runtime;
using Android.Graphics; using Android.Graphics;
using OpenTK.Platform.Egl; using OpenTK.Platform.Egl;
using SurfaceType = Android.Views.SurfaceType;
namespace OpenTK.Platform.Android namespace OpenTK.Platform.Android
{ {
@ -493,8 +494,8 @@ namespace OpenTK.Platform.Android
DateTime prevRenderTime; DateTime prevRenderTime;
DateTime curUpdateTime; DateTime curUpdateTime;
DateTime curRenderTime; DateTime curRenderTime;
FrameEventArgs updateEventArgs; FrameEventArgs updateEventArgs = new FrameEventArgs();
FrameEventArgs renderEventArgs; FrameEventArgs renderEventArgs = new FrameEventArgs();
// this method is called on the main thread if RenderOnUIThread is true // this method is called on the main thread if RenderOnUIThread is true
void RunIteration (CancellationToken token) void RunIteration (CancellationToken token)
@ -505,21 +506,19 @@ namespace OpenTK.Platform.Android
if (!ReadyToRender) if (!ReadyToRender)
return; return;
updateEventArgs = new FrameEventArgs ();
curUpdateTime = DateTime.Now; curUpdateTime = DateTime.Now;
if (prevUpdateTime.Ticks != 0) { if (prevUpdateTime.Ticks != 0) {
var t = (curUpdateTime - prevUpdateTime).TotalSeconds; var t = (curUpdateTime - prevUpdateTime).TotalSeconds;
updateEventArgs.Time = t < 0 ? 0 : t; updateEventArgs.Time = t;
} }
UpdateFrameInternal (updateEventArgs); UpdateFrameInternal (updateEventArgs);
prevUpdateTime = curUpdateTime; prevUpdateTime = curUpdateTime;
renderEventArgs = new FrameEventArgs ();
curRenderTime = DateTime.Now; curRenderTime = DateTime.Now;
if (prevRenderTime.Ticks == 0) { if (prevRenderTime.Ticks == 0) {
var t = (curRenderTime - prevRenderTime).TotalSeconds; var t = (curRenderTime - prevRenderTime).TotalSeconds;
renderEventArgs.Time = t < 0 ? 0 : t; renderEventArgs.Time = t;
} }
RenderFrameInternal (renderEventArgs); RenderFrameInternal (renderEventArgs);

View file

@ -0,0 +1,183 @@
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);
}
}
}

View file

@ -78,6 +78,17 @@ namespace OpenTK.Platform.Egl
CONTEXT_LOST = 12302, CONTEXT_LOST = 12302,
} }
enum SurfaceType
{
PBUFFER_BIT = 0x0001,
PIXMAP_BIT = 0x0002,
WINDOW_BIT = 0x0004,
VG_COLORSPACE_LINEAR_BIT = 0x0020,
VG_ALPHA_FORMAT_PRE_BIT = 0x0040,
MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200,
SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400,
}
static partial class Egl static partial class Egl
{ {
public const int VERSION_1_0 = 1; public const int VERSION_1_0 = 1;
@ -199,6 +210,10 @@ namespace OpenTK.Platform.Egl
// EGL_ANGLE_query_surface_pointer // EGL_ANGLE_query_surface_pointer
[DllImport("libEGL.dll", EntryPoint = "eglQuerySurfacePointerANGLE")] [DllImport("libEGL.dll", EntryPoint = "eglQuerySurfacePointerANGLE")]
public static extern bool QuerySurfacePointerANGLE(EGLDisplay display, EGLSurface surface, int attribute, out IntPtr value); public static extern bool QuerySurfacePointerANGLE(EGLDisplay display, EGLSurface surface, int attribute, out IntPtr value);
[DllImport("libEGL.dll", EntryPoint = "eglGetPlatformDisplayEXT")]
public static extern EGLDisplay GetPlatformDisplay(int platform, EGLNativeDisplayType displayId, int[] attribList);
// EGL_ANGLE_software_display // EGL_ANGLE_software_display
public static readonly EGLNativeDisplayType SOFTWARE_DISPLAY_ANGLE = new EGLNativeDisplayType(-1); public static readonly EGLNativeDisplayType SOFTWARE_DISPLAY_ANGLE = new EGLNativeDisplayType(-1);
// EGL_ANGLE_direct3d_display // EGL_ANGLE_direct3d_display
@ -224,6 +239,8 @@ namespace OpenTK.Platform.Egl
// EGL_ANGLE_platform_angle_opengl // EGL_ANGLE_platform_angle_opengl
public const int PLATFORM_ANGLE_TYPE_OPENGL_ANGLE = 0x320D; public const int PLATFORM_ANGLE_TYPE_OPENGL_ANGLE = 0x320D;
public const int PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE = 0x320E; public const int PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE = 0x320E;
// See EGL_ANGLE_surface_d3d_texture_2d_share_handle
public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200;
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetError")] [DllImportAttribute("libEGL.dll", EntryPoint = "eglGetError")]
public static extern ErrorCode GetError(); public static extern ErrorCode GetError();

View file

@ -0,0 +1,172 @@
#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_ANGLE
: Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
if (FlagEnabled(flags, GraphicsContextFlags.AngleD3D11))
{
platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
}
else if (FlagEnabled(flags, GraphicsContextFlags.AngleD3D9))
{
platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
}
else if (FlagEnabled(flags, GraphicsContextFlags.AngleOpenGL))
{
platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
}
else
{
// make sure the correct flag is set.
switch (platform_type)
{
case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
flags |= GraphicsContextFlags.AngleD3D9;
break;
case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
flags |= GraphicsContextFlags.AngleD3D11;
break;
case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
flags |= GraphicsContextFlags.AngleOpenGL;
break;
}
}
var attribs = new[]
{
Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_ANGLE, platform_type,
Platform.Egl.Egl.PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, Platform.Egl.Egl.DONT_CARE,
Platform.Egl.Egl.PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, Platform.Egl.Egl.DONT_CARE,
Platform.Egl.Egl.PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, Platform.Egl.Egl.PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
Platform.Egl.Egl.NONE
};
return Platform.Egl.Egl.GetPlatformDisplay(
Platform.Egl.Egl.PLATFORM_ANGLE_ANGLE,
dc,
attribs
);
}
#endregion
}
}

View file

@ -28,6 +28,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Graphics.ES20;
namespace OpenTK.Platform.Egl namespace OpenTK.Platform.Egl
{ {
@ -36,9 +37,11 @@ namespace OpenTK.Platform.Egl
#region Fields #region Fields
protected readonly RenderableFlags Renderable; protected readonly RenderableFlags Renderable;
protected EglWindowInfo WindowInfo; internal EglWindowInfo WindowInfo;
IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } } internal GraphicsContextFlags GraphicsContextFlags { get; set; }
internal IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } }
int swap_interval = 1; // Default interval is defined as 1 in EGL. int swap_interval = 1; // Default interval is defined as 1 in EGL.
#endregion #endregion
@ -53,6 +56,8 @@ namespace OpenTK.Platform.Egl
if (window == null) if (window == null)
throw new ArgumentNullException("window"); throw new ArgumentNullException("window");
EglContext shared = GetSharedEglContext(sharedContext);
WindowInfo = window; WindowInfo = window;
// Select an EGLConfig that matches the desired mode. We cannot use the 'mode' // Select an EGLConfig that matches the desired mode. We cannot use the 'mode'
@ -83,19 +88,38 @@ namespace OpenTK.Platform.Egl
Debug.Print("[EGL] Failed to bind rendering API. Error: {0}", Egl.GetError()); Debug.Print("[EGL] Failed to bind rendering API. Error: {0}", Egl.GetError());
} }
Mode = new EglGraphicsMode().SelectGraphicsMode(window, bool offscreen = (flags & GraphicsContextFlags.Offscreen) != 0;
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
mode.AccumulatorFormat, mode.Buffers, mode.Stereo, SurfaceType surfaceType = offscreen
? SurfaceType.PBUFFER_BIT
: SurfaceType.WINDOW_BIT;
Mode = new EglGraphicsMode().SelectGraphicsMode(surfaceType,
window.Display, mode.ColorFormat, mode.Depth, mode.Stencil,
mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
Renderable); Renderable);
if (!Mode.Index.HasValue) if (!Mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
IntPtr config = Mode.Index.Value; IntPtr config = Mode.Index.Value;
if (window.Surface == IntPtr.Zero) if (window.Surface == IntPtr.Zero)
{
if (!offscreen)
{
window.CreateWindowSurface(config); window.CreateWindowSurface(config);
}
else
{
window.CreatePbufferSurface(config);
}
}
int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE }; int[] attribList = { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
HandleAsEGLContext = Egl.CreateContext(window.Display, config, sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero, attrib_list); var shareContext = shared?.HandleAsEGLContext ?? IntPtr.Zero;
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shareContext, attribList);
GraphicsContextFlags = flags;
} }
public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext, public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
@ -131,6 +155,11 @@ namespace OpenTK.Platform.Egl
{ {
if (window is EglWindowInfo) if (window is EglWindowInfo)
WindowInfo = (EglWindowInfo) window; WindowInfo = (EglWindowInfo) window;
#if !ANDROID
else if (window is IAngleWindowInfoInternal)
WindowInfo = ((IAngleWindowInfoInternal) window).EglWindowInfo;
#endif
if (!Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, HandleAsEGLContext)) if (!Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, HandleAsEGLContext))
{ {
throw new GraphicsContextException(string.Format("Failed to make context {0} current. Error: {1}", Handle, Egl.GetError())); throw new GraphicsContextException(string.Format("Failed to make context {0} current. Error: {1}", Handle, Egl.GetError()));
@ -171,6 +200,19 @@ namespace OpenTK.Platform.Egl
} }
} }
public override void Update(IWindowInfo window)
{
MakeCurrent(window);
// ANGLE updates the width and height of the back buffer surfaces in the WaitClient function.
// So without this calling this function, the surface won't match the size of the window after it
// was resized.
// https://bugs.chromium.org/p/angleproject/issues/detail?id=1438
if (!Egl.WaitClient())
{
Debug.Print("[Warning] Egl.WaitClient() failed. Error: {0}", Egl.GetError());
}
}
#endregion #endregion
#region IGraphicsContextInternal Members #region IGraphicsContextInternal Members
@ -216,6 +258,21 @@ namespace OpenTK.Platform.Egl
} }
} }
private EglContext GetSharedEglContext(IGraphicsContext sharedContext)
{
if (sharedContext == null)
{
return null;
}
var internalContext = sharedContext as IGraphicsContextInternal;
if (internalContext != null)
{
return (EglContext) internalContext.Implementation;
}
return (EglContext) sharedContext;
}
#endregion #endregion
} }
} }

View file

@ -26,8 +26,6 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Graphics; using OpenTK.Graphics;
namespace OpenTK.Platform.Egl namespace OpenTK.Platform.Egl
@ -46,13 +44,24 @@ namespace OpenTK.Platform.Egl
public GraphicsMode SelectGraphicsMode(EglWindowInfo window, public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
ColorFormat color, int depth, int stencil, ColorFormat color, int depth, int stencil,
int samples, ColorFormat accum, int buffers, bool stereo, int samples, ColorFormat accum, int buffers, bool stereo,
RenderableFlags renderable_flags) RenderableFlags renderableFlags)
{
return SelectGraphicsMode(
SurfaceType.WINDOW_BIT,
window.Display,
color, depth, stencil, samples, accum, buffers, stereo, renderableFlags);
}
public GraphicsMode SelectGraphicsMode(SurfaceType surfaceType,
IntPtr display, ColorFormat color, int depth, int stencil,
int samples, ColorFormat accum, int buffers, bool stereo,
RenderableFlags renderableFlags)
{ {
IntPtr[] configs = new IntPtr[1]; IntPtr[] configs = new IntPtr[1];
int[] attribList = new int[] int[] attribList = new int[]
{ {
Egl.SURFACE_TYPE, Egl.WINDOW_BIT, Egl.SURFACE_TYPE, (int) surfaceType,
Egl.RENDERABLE_TYPE, (int)renderable_flags, Egl.RENDERABLE_TYPE, (int)renderableFlags,
Egl.RED_SIZE, color.Red, Egl.RED_SIZE, color.Red,
Egl.GREEN_SIZE, color.Green, Egl.GREEN_SIZE, color.Green,
@ -68,29 +77,27 @@ namespace OpenTK.Platform.Egl
Egl.NONE, Egl.NONE,
}; };
IntPtr display = window.Display; int numConfigs;
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out numConfigs) || numConfigs == 0)
int num_configs;
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out num_configs) || num_configs == 0)
{ {
throw new GraphicsModeException(String.Format("Failed to retrieve GraphicsMode, error {0}", Egl.GetError())); throw new GraphicsModeException(String.Format("Failed to retrieve GraphicsMode, error {0}", Egl.GetError()));
} }
// See what we really got // See what we really got
IntPtr active_config = configs[0]; IntPtr activeConfig = configs[0];
int r, g, b, a; int r, g, b, a;
Egl.GetConfigAttrib(display, active_config, Egl.RED_SIZE, out r); Egl.GetConfigAttrib(display, activeConfig, Egl.RED_SIZE, out r);
Egl.GetConfigAttrib(display, active_config, Egl.GREEN_SIZE, out g); Egl.GetConfigAttrib(display, activeConfig, Egl.GREEN_SIZE, out g);
Egl.GetConfigAttrib(display, active_config, Egl.BLUE_SIZE, out b); Egl.GetConfigAttrib(display, activeConfig, Egl.BLUE_SIZE, out b);
Egl.GetConfigAttrib(display, active_config, Egl.ALPHA_SIZE, out a); Egl.GetConfigAttrib(display, activeConfig, Egl.ALPHA_SIZE, out a);
int d, s; int d, s;
Egl.GetConfigAttrib(display, active_config, Egl.DEPTH_SIZE, out d); Egl.GetConfigAttrib(display, activeConfig, Egl.DEPTH_SIZE, out d);
Egl.GetConfigAttrib(display, active_config, Egl.STENCIL_SIZE, out s); Egl.GetConfigAttrib(display, activeConfig, Egl.STENCIL_SIZE, out s);
int sample_buffers; int sampleBuffers;
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers); Egl.GetConfigAttrib(display, activeConfig, Egl.SAMPLES, out sampleBuffers);
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out samples); Egl.GetConfigAttrib(display, activeConfig, Egl.SAMPLES, out samples);
return new GraphicsMode(active_config, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false); return new GraphicsMode(activeConfig, new ColorFormat(r, g, b, a), d, s, sampleBuffers > 0 ? samples : 0, 0, 2, false);
} }
} }
} }

View file

@ -64,8 +64,8 @@ namespace OpenTK.Platform.Egl
Display = display; Display = display;
int dummy_major, dummy_minor; int dummyMajor, dummyMinor;
if (!Egl.Initialize(Display, out dummy_major, out dummy_minor)) if (!Egl.Initialize(Display, out dummyMajor, out dummyMinor))
{ {
throw new GraphicsContextException(String.Format("Failed to initialize EGL, error {0}.", Egl.GetError())); throw new GraphicsContextException(String.Format("Failed to initialize EGL, error {0}.", Egl.GetError()));
} }
@ -98,21 +98,67 @@ namespace OpenTK.Platform.Egl
public void CreatePbufferSurface(IntPtr config) public void CreatePbufferSurface(IntPtr config)
{ {
Surface = Egl.CreatePbufferSurface(Display, config, null); int[] attribs = new int[]{Egl.NONE};
Surface = Egl.CreatePbufferSurface(Display, config, attribs);
if (Surface == IntPtr.Zero)
{
throw new GraphicsContextException(String.Format(
"[EGL] Failed to create pbuffer surface, error {0}.", Egl.GetError()));
}
}
public void CreatePbufferSurface(IntPtr config, int width, int height)
{
if (surface != IntPtr.Zero)
{
DestroySurface();
}
CreatePbufferSurface(config, width, height, out surface);
}
public void CreatePbufferSurface(IntPtr config, int width, int height, out IntPtr bufferSurface)
{
int[] attribs = new int[]
{
Egl.WIDTH, width,
Egl.HEIGHT, height,
Egl.TEXTURE_TARGET, Egl.TEXTURE_2D,
Egl.TEXTURE_FORMAT, Egl.TEXTURE_RGBA,
Egl.NONE
};
bufferSurface = Egl.CreatePbufferSurface(Display, config, attribs);
if (bufferSurface == IntPtr.Zero)
{
throw new GraphicsContextException(String.Format(
"[EGL] Failed to create pbuffer surface, error {0}.", Egl.GetError()));
}
} }
public void DestroySurface() public void DestroySurface()
{ {
if (Surface != IntPtr.Zero) DestroySurface(ref surface);
{ }
if (Egl.GetCurrentSurface(Egl.DRAW) == Surface)
Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); public void DestroySurface(ref IntPtr bufferSurface)
{
if (bufferSurface == IntPtr.Zero)
{
return;
}
if (Egl.GetCurrentSurface(Egl.DRAW) == Surface)
{
Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}
if (Egl.DestroySurface(Display, bufferSurface))
{
bufferSurface = IntPtr.Zero;
return;
}
if (!Egl.DestroySurface(Display, Surface))
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface); Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
Surface = IntPtr.Zero; Surface = IntPtr.Zero;
} }
}
public void TerminateDisplay() public void TerminateDisplay()
{ {

View file

@ -26,9 +26,7 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Text;
namespace OpenTK.Platform namespace OpenTK.Platform
{ {
@ -39,8 +37,10 @@ namespace OpenTK.Platform
{ {
#region Fields #region Fields
bool disposed; private bool disposed;
static IPlatformFactory default_implementation, embedded_implementation; private static IPlatformFactory defaultImplementation;
private static IPlatformFactory embeddedImplementation;
private static IPlatformFactory angleImplementation;
#endregion #endregion
@ -102,11 +102,18 @@ namespace OpenTK.Platform
else if (Configuration.RunningOnAndroid) Embedded = new Android.AndroidFactory(); else if (Configuration.RunningOnAndroid) Embedded = new Android.AndroidFactory();
#endif #endif
else Embedded = new UnsupportedPlatform(); else Embedded = new UnsupportedPlatform();
#if ANDROID
Angle = new UnsupportedPlatform();
#else
Angle = new Egl.EglAnglePlatformFactory(Embedded);
#endif
} }
#endif #endif
else else
{ {
Embedded = new UnsupportedPlatform(); Embedded = new UnsupportedPlatform();
Angle = Embedded;
} }
if (Default is UnsupportedPlatform && !(Embedded is UnsupportedPlatform)) if (Default is UnsupportedPlatform && !(Embedded is UnsupportedPlatform))
@ -119,14 +126,20 @@ namespace OpenTK.Platform
public static IPlatformFactory Default public static IPlatformFactory Default
{ {
get { return default_implementation; } get { return defaultImplementation; }
private set { default_implementation = value; } private set { defaultImplementation = value; }
} }
public static IPlatformFactory Embedded public static IPlatformFactory Embedded
{ {
get { return embedded_implementation; } get { return embeddedImplementation; }
private set { embedded_implementation = value; } private set { embeddedImplementation = value; }
}
public static IPlatformFactory Angle
{
get { return angleImplementation; }
private set { angleImplementation = value; }
} }
#endregion #endregion
@ -136,60 +149,60 @@ namespace OpenTK.Platform
public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title,
GraphicsMode mode, GameWindowFlags options, DisplayDevice device) GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
{ {
return default_implementation.CreateNativeWindow(x, y, width, height, title, mode, options, device); return defaultImplementation.CreateNativeWindow(x, y, width, height, title, mode, options, device);
} }
public IDisplayDeviceDriver CreateDisplayDeviceDriver() public IDisplayDeviceDriver CreateDisplayDeviceDriver()
{ {
return default_implementation.CreateDisplayDeviceDriver(); return defaultImplementation.CreateDisplayDeviceDriver();
} }
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
return default_implementation.CreateGLContext(mode, window, shareContext, directRendering, major, minor, flags); return defaultImplementation.CreateGLContext(mode, window, shareContext, directRendering, major, minor, flags);
} }
public IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags) public IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{ {
return default_implementation.CreateGLContext(handle, window, shareContext, directRendering, major, minor, flags); return defaultImplementation.CreateGLContext(handle, window, shareContext, directRendering, major, minor, flags);
} }
public GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext() public GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
{ {
return default_implementation.CreateGetCurrentGraphicsContext(); return defaultImplementation.CreateGetCurrentGraphicsContext();
} }
public IKeyboardDriver2 CreateKeyboardDriver() public IKeyboardDriver2 CreateKeyboardDriver()
{ {
return default_implementation.CreateKeyboardDriver(); return defaultImplementation.CreateKeyboardDriver();
} }
public IMouseDriver2 CreateMouseDriver() public IMouseDriver2 CreateMouseDriver()
{ {
return default_implementation.CreateMouseDriver(); return defaultImplementation.CreateMouseDriver();
} }
public IGamePadDriver CreateGamePadDriver() public IGamePadDriver CreateGamePadDriver()
{ {
return default_implementation.CreateGamePadDriver(); return defaultImplementation.CreateGamePadDriver();
} }
public IJoystickDriver2 CreateJoystickDriver() public IJoystickDriver2 CreateJoystickDriver()
{ {
return default_implementation.CreateJoystickDriver(); return defaultImplementation.CreateJoystickDriver();
} }
[Obsolete] [Obsolete]
public IJoystickDriver CreateLegacyJoystickDriver() public IJoystickDriver CreateLegacyJoystickDriver()
{ {
#pragma warning disable 612,618 #pragma warning disable 612,618
return default_implementation.CreateLegacyJoystickDriver(); return defaultImplementation.CreateLegacyJoystickDriver();
#pragma warning restore 612,618 #pragma warning restore 612,618
} }
public void RegisterResource(IDisposable resource) public void RegisterResource(IDisposable resource)
{ {
default_implementation.RegisterResource(resource); defaultImplementation.RegisterResource(resource);
} }
class UnsupportedPlatform : PlatformFactoryBase class UnsupportedPlatform : PlatformFactoryBase

View file

@ -393,6 +393,24 @@ namespace OpenTK.Platform
#endregion #endregion
#region
#if !__MOBILE__
/// <summary>
/// Creates an IWindowInfo instance for Angle rendering, based on
/// supplied platform window (e.g. a window created with
/// CreateWindowsWindowInfo, or CreateDummyWindowInfo).
/// </summary>
/// <param name="platformWindow"></param>
/// <returns></returns>
public static Egl.IAngleWindowInfo CreateAngleWindowInfo(IWindowInfo platformWindow)
{
return new Egl.AngleWindowInfo(platformWindow);
}
#endif
#endregion
#endregion #endregion
#region RelaxGraphicsMode #region RelaxGraphicsMode

View file

@ -371,8 +371,8 @@ namespace OpenTK.Platform.Windows
// Load the entry points we are interested in from that dll // Load the entry points we are interested in from that dll
GetCapabilities = (XInputGetCapabilities)Load("XInputGetCapabilities", typeof(XInputGetCapabilities)); GetCapabilities = (XInputGetCapabilities)Load("XInputGetCapabilities", typeof(XInputGetCapabilities));
GetState = GetState =
// undocumented XInputGetStateEx with support for the "Guide" button (requires XINPUT_1_3+) // undocumented XInputGetStateEx (Ordinal 100) with support for the "Guide" button (requires XINPUT_1_3+)
(XInputGetState)Load("XInputGetStateEx", typeof(XInputGetState)) ?? (XInputGetState)Load(100, typeof(XInputGetState)) ??
// documented XInputGetState (no support for the "Guide" button) // documented XInputGetState (no support for the "Guide" button)
(XInputGetState)Load("XInputGetState", typeof(XInputGetState)); (XInputGetState)Load("XInputGetState", typeof(XInputGetState));
SetState = (XInputSetState)Load("XInputSetState", typeof(XInputSetState)); SetState = (XInputSetState)Load("XInputSetState", typeof(XInputSetState));
@ -380,6 +380,14 @@ namespace OpenTK.Platform.Windows
#region Private Members #region Private Members
Delegate Load(ushort ordinal, Type type)
{
IntPtr pfunc = Functions.GetProcAddress(dll, (IntPtr)ordinal);
if (pfunc != IntPtr.Zero)
return Marshal.GetDelegateForFunctionPointer(pfunc, type);
return null;
}
Delegate Load(string name, Type type) Delegate Load(string name, Type type)
{ {
IntPtr pfunc = Functions.GetProcAddress(dll, name); IntPtr pfunc = Functions.GetProcAddress(dll, name);

View file

@ -861,20 +861,20 @@ namespace OpenTK.Platform.iPhoneOS
internal void RunIteration (NSTimer timer) internal void RunIteration (NSTimer timer)
{ {
var curUpdateTime = stopwatch.Elapsed; var curUpdateTime = stopwatch.Elapsed;
if (prevUpdateTime == TimeSpan.Zero) if (prevUpdateTime.Ticks != 0) {
prevUpdateTime = curUpdateTime;
var t = (curUpdateTime - prevUpdateTime).TotalSeconds; var t = (curUpdateTime - prevUpdateTime).TotalSeconds;
updateEventArgs.Time = t; updateEventArgs.Time = t;
}
OnUpdateFrame(updateEventArgs); OnUpdateFrame(updateEventArgs);
prevUpdateTime = curUpdateTime; prevUpdateTime = curUpdateTime;
gl.BindFramebuffer(All.FramebufferOes, framebuffer); gl.BindFramebuffer(All.FramebufferOes, framebuffer);
var curRenderTime = stopwatch.Elapsed; var curRenderTime = stopwatch.Elapsed;
if (prevRenderTime == TimeSpan.Zero) if (prevRenderTime.Ticks == 0) {
prevRenderTime = curRenderTime; var t = (curRenderTime - prevRenderTime).TotalSeconds;
t = (curRenderTime - prevRenderTime).TotalSeconds;
renderEventArgs.Time = t; renderEventArgs.Time = t;
}
OnRenderFrame(renderEventArgs); OnRenderFrame(renderEventArgs);
prevRenderTime = curRenderTime; prevRenderTime = curRenderTime;
} }