mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-23 10:55:32 +00:00
Merge pull request #458 from mzanin/angle-es3
Allow using OpenGL ES3 with Angle and extract a Direct3D shared handle
This commit is contained in:
commit
4e2d1ae520
|
@ -97,6 +97,23 @@ namespace OpenTK.Graphics
|
|||
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
|
||||
/// </remarks>
|
||||
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)
|
||||
{
|
||||
|
@ -112,6 +129,18 @@ namespace OpenTK.Graphics
|
|||
if (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.");
|
||||
try
|
||||
{
|
||||
|
@ -121,8 +150,6 @@ namespace OpenTK.Graphics
|
|||
Debug.Print("GraphicsContextFlags: {0}", flags);
|
||||
Debug.Print("Requested version: {0}.{1}", major, minor);
|
||||
|
||||
IGraphicsContext shareContext = FindSharedContext();
|
||||
|
||||
// Todo: Add a DummyFactory implementing IPlatformFactory.
|
||||
if (designMode)
|
||||
{
|
||||
|
@ -133,8 +160,12 @@ namespace OpenTK.Graphics
|
|||
IPlatformFactory factory = null;
|
||||
switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
|
||||
{
|
||||
case false: factory = Factory.Default; break;
|
||||
case true: factory = Factory.Embedded; break;
|
||||
case false:
|
||||
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.
|
||||
|
|
|
@ -56,6 +56,30 @@ namespace OpenTK.Graphics
|
|||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is targeting OpenGL|ES.
|
||||
/// </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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,9 +132,11 @@
|
|||
<Compile Include="Math\Matrix4x3d.cs" />
|
||||
<Compile Include="Platform\Common\Hid.cs" />
|
||||
<Compile Include="Platform\DisplayDeviceBase.cs" />
|
||||
<Compile Include="Platform\Egl\AngleWindowInfo.cs" />
|
||||
<Compile Include="Platform\Egl\EglException.cs" />
|
||||
<Compile Include="Platform\Egl\EglUnixContext.cs" />
|
||||
<Compile Include="Platform\Egl\EglWinContext.cs" />
|
||||
<Compile Include="Platform\Egl\EglAnglePlatformFactory.cs" />
|
||||
<Compile Include="Platform\MappedGamePadDriver.cs" />
|
||||
<Compile Include="Platform\Windows\Bindings\HidProtocol.cs" />
|
||||
<Compile Include="Platform\Windows\WinInputBase.cs" />
|
||||
|
|
183
src/OpenTK/Platform/Egl/AngleWindowInfo.cs
Normal file
183
src/OpenTK/Platform/Egl/AngleWindowInfo.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -78,6 +78,17 @@ namespace OpenTK.Platform.Egl
|
|||
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
|
||||
{
|
||||
public const int VERSION_1_0 = 1;
|
||||
|
@ -199,6 +210,10 @@ namespace OpenTK.Platform.Egl
|
|||
// EGL_ANGLE_query_surface_pointer
|
||||
[DllImport("libEGL.dll", EntryPoint = "eglQuerySurfacePointerANGLE")]
|
||||
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
|
||||
public static readonly EGLNativeDisplayType SOFTWARE_DISPLAY_ANGLE = new EGLNativeDisplayType(-1);
|
||||
// EGL_ANGLE_direct3d_display
|
||||
|
@ -224,6 +239,8 @@ namespace OpenTK.Platform.Egl
|
|||
// EGL_ANGLE_platform_angle_opengl
|
||||
public const int PLATFORM_ANGLE_TYPE_OPENGL_ANGLE = 0x320D;
|
||||
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")]
|
||||
public static extern ErrorCode GetError();
|
||||
|
|
172
src/OpenTK/Platform/Egl/EglAnglePlatformFactory.cs
Normal file
172
src/OpenTK/Platform/Egl/EglAnglePlatformFactory.cs
Normal 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
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Graphics.ES20;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
|
@ -36,9 +37,11 @@ namespace OpenTK.Platform.Egl
|
|||
#region Fields
|
||||
|
||||
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.
|
||||
|
||||
#endregion
|
||||
|
@ -53,6 +56,8 @@ namespace OpenTK.Platform.Egl
|
|||
if (window == null)
|
||||
throw new ArgumentNullException("window");
|
||||
|
||||
EglContext shared = GetSharedEglContext(sharedContext);
|
||||
|
||||
WindowInfo = window;
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
Mode = new EglGraphicsMode().SelectGraphicsMode(window,
|
||||
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples,
|
||||
mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
|
||||
Renderable);
|
||||
bool offscreen = (flags & GraphicsContextFlags.Offscreen) != 0;
|
||||
|
||||
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);
|
||||
|
||||
if (!Mode.Index.HasValue)
|
||||
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
|
||||
IntPtr config = Mode.Index.Value;
|
||||
|
||||
if (window.Surface == IntPtr.Zero)
|
||||
window.CreateWindowSurface(config);
|
||||
{
|
||||
if (!offscreen)
|
||||
{
|
||||
window.CreateWindowSurface(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.CreatePbufferSurface(config);
|
||||
}
|
||||
}
|
||||
|
||||
int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
|
||||
HandleAsEGLContext = Egl.CreateContext(window.Display, config, sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero, attrib_list);
|
||||
int[] attribList = { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
|
||||
var shareContext = shared?.HandleAsEGLContext ?? IntPtr.Zero;
|
||||
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shareContext, attribList);
|
||||
|
||||
GraphicsContextFlags = flags;
|
||||
}
|
||||
|
||||
public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
|
@ -131,6 +155,9 @@ namespace OpenTK.Platform.Egl
|
|||
{
|
||||
if (window is EglWindowInfo)
|
||||
WindowInfo = (EglWindowInfo) window;
|
||||
else if (window is IAngleWindowInfoInternal)
|
||||
WindowInfo = ((IAngleWindowInfoInternal) window).EglWindowInfo;
|
||||
|
||||
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()));
|
||||
|
@ -229,6 +256,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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
|
@ -46,13 +44,24 @@ namespace OpenTK.Platform.Egl
|
|||
public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
|
||||
ColorFormat color, int depth, int stencil,
|
||||
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];
|
||||
int[] attribList = new int[]
|
||||
{
|
||||
Egl.SURFACE_TYPE, Egl.WINDOW_BIT,
|
||||
Egl.RENDERABLE_TYPE, (int)renderable_flags,
|
||||
Egl.SURFACE_TYPE, (int) surfaceType,
|
||||
Egl.RENDERABLE_TYPE, (int)renderableFlags,
|
||||
|
||||
Egl.RED_SIZE, color.Red,
|
||||
Egl.GREEN_SIZE, color.Green,
|
||||
|
@ -68,29 +77,27 @@ namespace OpenTK.Platform.Egl
|
|||
Egl.NONE,
|
||||
};
|
||||
|
||||
IntPtr display = window.Display;
|
||||
|
||||
int num_configs;
|
||||
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out num_configs) || num_configs == 0)
|
||||
int numConfigs;
|
||||
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out numConfigs) || numConfigs == 0)
|
||||
{
|
||||
throw new GraphicsModeException(String.Format("Failed to retrieve GraphicsMode, error {0}", Egl.GetError()));
|
||||
}
|
||||
|
||||
// See what we really got
|
||||
IntPtr active_config = configs[0];
|
||||
IntPtr activeConfig = 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);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.RED_SIZE, out r);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.GREEN_SIZE, out g);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.BLUE_SIZE, out b);
|
||||
Egl.GetConfigAttrib(display, activeConfig, 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);
|
||||
int sample_buffers;
|
||||
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out sample_buffers);
|
||||
Egl.GetConfigAttrib(display, active_config, Egl.SAMPLES, out samples);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.DEPTH_SIZE, out d);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.STENCIL_SIZE, out s);
|
||||
int sampleBuffers;
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.SAMPLES, out sampleBuffers);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ namespace OpenTK.Platform.Egl
|
|||
|
||||
Display = display;
|
||||
|
||||
int dummy_major, dummy_minor;
|
||||
if (!Egl.Initialize(Display, out dummy_major, out dummy_minor))
|
||||
int dummyMajor, dummyMinor;
|
||||
if (!Egl.Initialize(Display, out dummyMajor, out dummyMinor))
|
||||
{
|
||||
throw new GraphicsContextException(String.Format("Failed to initialize EGL, error {0}.", Egl.GetError()));
|
||||
}
|
||||
|
@ -98,20 +98,66 @@ namespace OpenTK.Platform.Egl
|
|||
|
||||
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()
|
||||
{
|
||||
if (Surface != IntPtr.Zero)
|
||||
{
|
||||
if (Egl.GetCurrentSurface(Egl.DRAW) == Surface)
|
||||
Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
||||
DestroySurface(ref surface);
|
||||
}
|
||||
|
||||
if (!Egl.DestroySurface(Display, Surface))
|
||||
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
|
||||
Surface = 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;
|
||||
}
|
||||
|
||||
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
|
||||
Surface = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public void TerminateDisplay()
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
|
@ -39,8 +38,10 @@ namespace OpenTK.Platform
|
|||
{
|
||||
#region Fields
|
||||
|
||||
bool disposed;
|
||||
static IPlatformFactory default_implementation, embedded_implementation;
|
||||
private bool disposed;
|
||||
private static IPlatformFactory defaultImplementation;
|
||||
private static IPlatformFactory embeddedImplementation;
|
||||
private static IPlatformFactory angleImplementation;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -102,11 +103,13 @@ namespace OpenTK.Platform
|
|||
else if (Configuration.RunningOnAndroid) Embedded = new Android.AndroidFactory();
|
||||
#endif
|
||||
else Embedded = new UnsupportedPlatform();
|
||||
Angle = new EglAnglePlatformFactory(Embedded);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
Embedded = new UnsupportedPlatform();
|
||||
Angle = Embedded;
|
||||
}
|
||||
|
||||
if (Default is UnsupportedPlatform && !(Embedded is UnsupportedPlatform))
|
||||
|
@ -119,14 +122,20 @@ namespace OpenTK.Platform
|
|||
|
||||
public static IPlatformFactory Default
|
||||
{
|
||||
get { return default_implementation; }
|
||||
private set { default_implementation = value; }
|
||||
get { return defaultImplementation; }
|
||||
private set { defaultImplementation = value; }
|
||||
}
|
||||
|
||||
public static IPlatformFactory Embedded
|
||||
{
|
||||
get { return embedded_implementation; }
|
||||
private set { embedded_implementation = value; }
|
||||
get { return embeddedImplementation; }
|
||||
private set { embeddedImplementation = value; }
|
||||
}
|
||||
|
||||
public static IPlatformFactory Angle
|
||||
{
|
||||
get { return angleImplementation; }
|
||||
private set { angleImplementation = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -136,60 +145,60 @@ namespace OpenTK.Platform
|
|||
public INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title,
|
||||
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()
|
||||
{
|
||||
return default_implementation.CreateDisplayDeviceDriver();
|
||||
return defaultImplementation.CreateDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
return default_implementation.CreateGetCurrentGraphicsContext();
|
||||
return defaultImplementation.CreateGetCurrentGraphicsContext();
|
||||
}
|
||||
|
||||
public IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
return default_implementation.CreateKeyboardDriver();
|
||||
return defaultImplementation.CreateKeyboardDriver();
|
||||
}
|
||||
|
||||
public IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
return default_implementation.CreateMouseDriver();
|
||||
return defaultImplementation.CreateMouseDriver();
|
||||
}
|
||||
|
||||
public IGamePadDriver CreateGamePadDriver()
|
||||
{
|
||||
return default_implementation.CreateGamePadDriver();
|
||||
return defaultImplementation.CreateGamePadDriver();
|
||||
}
|
||||
|
||||
public IJoystickDriver2 CreateJoystickDriver()
|
||||
{
|
||||
return default_implementation.CreateJoystickDriver();
|
||||
return defaultImplementation.CreateJoystickDriver();
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public IJoystickDriver CreateLegacyJoystickDriver()
|
||||
{
|
||||
#pragma warning disable 612,618
|
||||
return default_implementation.CreateLegacyJoystickDriver();
|
||||
return defaultImplementation.CreateLegacyJoystickDriver();
|
||||
#pragma warning restore 612,618
|
||||
}
|
||||
|
||||
public void RegisterResource(IDisposable resource)
|
||||
{
|
||||
default_implementation.RegisterResource(resource);
|
||||
defaultImplementation.RegisterResource(resource);
|
||||
}
|
||||
|
||||
class UnsupportedPlatform : PlatformFactoryBase
|
||||
|
|
|
@ -13,6 +13,7 @@ using System.Runtime.InteropServices;
|
|||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -393,6 +394,22 @@ namespace OpenTK.Platform
|
|||
|
||||
#endregion
|
||||
|
||||
#region
|
||||
|
||||
/// <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 IAngleWindowInfo CreateAngleWindowInfo(IWindowInfo platformWindow)
|
||||
{
|
||||
return new AngleWindowInfo(platformWindow);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region RelaxGraphicsMode
|
||||
|
|
Loading…
Reference in a new issue