Added Angle-related enums and definitions

+ GraphicsContextFlags now has Angle and Offscreen flags.
+ Egl now has PLATFORM_ANGLE related const ints.
+ Added eglGetPlatformDisplayEXT p/invoke definition
+ Added eglQuerySurfacePointerANGLE p/invoke definition
+ EglWindowInfo.CreatePbufferSurface was commented out. Enabled and fixed it.
+ GraphicsContextFlags.Offscreen will make the context create a PbufferSurface instead of a WindowSurface in EglContext
+ SurfaceType enum to select surface type for SelectGraphicsMode
This commit is contained in:
Jonas Boesch 2015-04-21 16:08:50 +02:00 committed by Manuel Zanin
parent 7b795a02e1
commit df66598182
8 changed files with 192 additions and 20 deletions

View file

@ -0,0 +1,42 @@
using System;
using System.Runtime.InteropServices;
namespace OpenTK.Platform.Egl
{
using EGLDisplay = IntPtr;
using EGLNativeDisplayType = IntPtr;
using EGLSurface = IntPtr;
using ShareHandle = IntPtr;
static partial class Egl
{
// See
// - ANGLE_platform_angle
// - ANGLE_platform_angle_d3d
// - ANGLE_platform_angle_opengl
public const int PLATFORM_ANGLE = 0x3202;
public const int PLATFORM_ANGLE_TYPE = 0x3203;
public const int PLATFORM_ANGLE_MAX_VERSION_MAJOR = 0x3204;
public const int PLATFORM_ANGLE_MAX_VERSION_MINOR = 0x3205;
public const int PLATFORM_ANGLE_TYPE_DEFAULT = 0x3206;
public const int PLATFORM_ANGLE_TYPE_D3D9 = 0x3207;
public const int PLATFORM_ANGLE_TYPE_D3D11 = 0x3208;
public const int PLATFORM_ANGLE_DEVICE_TYPE = 0x3209;
public const int PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE = 0x320A;
public const int PLATFORM_ANGLE_DEVICE_TYPE_WARP = 0x320B;
public const int PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE = 0x320C;
public const int PLATFORM_ANGLE_TYPE_OPENGL = 0x320D;
public const int PLATFORM_ANGLE_TYPE_OPENGLES = 0x320E;
// See EGL_ANGLE_surface_d3d_texture_2d_share_handle
public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200;
[DllImport("libEGL.dll", EntryPoint = "eglGetPlatformDisplayEXT")]
public static extern EGLDisplay GetPlatformDisplay(int platform, EGLNativeDisplayType display_id,
int[] attrib_list);
[DllImport("libEGL.dll", EntryPoint = "eglQuerySurfacePointerANGLE")]
public static extern bool QuerySurfacePointerANGLE(EGLDisplay display, EGLSurface surface,
int attribute, out IntPtr value);
}
}

View file

@ -112,6 +112,18 @@ namespace OpenTK.Graphics
if (minor < 0) if (minor < 0)
minor = 0; minor = 0;
// Angle needs an embedded context
var use_angle_flag = GraphicsContextFlags.Angle
| GraphicsContextFlags.AngleD3D9
| GraphicsContextFlags.AngleD3D11
| GraphicsContextFlags.AngleOpenGL;
var use_angle = false;
if ((flags & use_angle_flag) != 0)
{
flags |= GraphicsContextFlags.Embedded;
use_angle = true;
}
Debug.Print("Creating GraphicsContext."); Debug.Print("Creating GraphicsContext.");
try try
{ {

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

@ -134,6 +134,7 @@
<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\EglException.cs" /> <Compile Include="Platform\Egl\EglException.cs" />
<Compile Include="Platform\Egl\EglAngle.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\MappedGamePadDriver.cs" /> <Compile Include="Platform\MappedGamePadDriver.cs" />

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;

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
@ -85,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 surface_type = offscreen
Renderable); ? SurfaceType.PBUFFER_BIT
: SurfaceType.WINDOW_BIT;
Mode = new EglGraphicsMode().SelectGraphicsMode(surface_type,
window.Display, mode.ColorFormat, mode.Depth, mode.Stencil,
mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
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)
window.CreateWindowSurface(config); {
if (!offscreen)
{
window.CreateWindowSurface(config);
}
else
{
window.CreatePbufferSurface(config);
}
}
int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE }; 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); var share_context = shared != null ? shared.HandleAsEGLContext : IntPtr.Zero;
HandleAsEGLContext = Egl.CreateContext(window.Display, config, share_context, attrib_list);
GraphicsContextFlags = flags;
} }
public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext, public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
@ -133,6 +155,9 @@ namespace OpenTK.Platform.Egl
{ {
if (window is EglWindowInfo) if (window is EglWindowInfo)
WindowInfo = (EglWindowInfo) window; WindowInfo = (EglWindowInfo) window;
else if (window is IAngleWindowInfoInternal)
WindowInfo = ((IAngleWindowInfoInternal) window).EglWindowInfo;
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()));

View file

@ -47,11 +47,23 @@ namespace OpenTK.Platform.Egl
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 renderable_flags)
{
return SelectGraphicsMode(
SurfaceType.WINDOW_BIT,
window.Display,
color, depth, stencil, samples, accum, buffers, stereo, renderable_flags
);
}
public GraphicsMode SelectGraphicsMode(SurfaceType surface_type,
IntPtr display, ColorFormat color, int depth, int stencil,
int samples, ColorFormat accum, int buffers, bool stereo,
RenderableFlags renderable_flags)
{ {
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) surface_type,
Egl.RENDERABLE_TYPE, (int)renderable_flags, Egl.RENDERABLE_TYPE, (int)renderable_flags,
Egl.RED_SIZE, color.Red, Egl.RED_SIZE, color.Red,
@ -68,8 +80,6 @@ namespace OpenTK.Platform.Egl
Egl.NONE, Egl.NONE,
}; };
IntPtr display = window.Display;
int num_configs; int num_configs;
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out num_configs) || num_configs == 0) if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out num_configs) || num_configs == 0)
{ {
@ -92,5 +102,6 @@ namespace OpenTK.Platform.Egl
return new GraphicsMode(active_config, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false); return new GraphicsMode(active_config, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false);
} }
} }
} }

View file

@ -98,20 +98,66 @@ 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 surface_)
{
int[] attribs = new int[]
{
Egl.WIDTH, width,
Egl.HEIGHT, height,
Egl.TEXTURE_TARGET, Egl.TEXTURE_2D,
Egl.TEXTURE_FORMAT, Egl.TEXTURE_RGBA,
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 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);
if (!Egl.DestroySurface(Display, Surface)) public void DestroySurface(ref IntPtr surface_)
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface); {
Surface = IntPtr.Zero; if (surface_ == IntPtr.Zero)
{
return;
} }
if (Egl.GetCurrentSurface(Egl.DRAW) == Surface)
Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
if (Egl.DestroySurface(Display, surface_))
{
surface_ = IntPtr.Zero;
return;
}
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
Surface = IntPtr.Zero;
} }
public void TerminateDisplay() public void TerminateDisplay()