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)
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.");
try
{

View file

@ -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,
}
}

View file

@ -134,6 +134,7 @@
<Compile Include="Platform\Common\Hid.cs" />
<Compile Include="Platform\DisplayDeviceBase.cs" />
<Compile Include="Platform\Egl\EglException.cs" />
<Compile Include="Platform\Egl\EglAngle.cs" />
<Compile Include="Platform\Egl\EglUnixContext.cs" />
<Compile Include="Platform\Egl\EglWinContext.cs" />
<Compile Include="Platform\MappedGamePadDriver.cs" />

View file

@ -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;

View file

@ -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
@ -85,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,
bool offscreen = (flags & GraphicsContextFlags.Offscreen) != 0;
SurfaceType surface_type = offscreen
? 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)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
IntPtr config = Mode.Index.Value;
if (window.Surface == IntPtr.Zero)
{
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);
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,
@ -133,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()));

View file

@ -47,11 +47,23 @@ namespace OpenTK.Platform.Egl
ColorFormat color, int depth, int stencil,
int samples, ColorFormat accum, int buffers, bool stereo,
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];
int[] attribList = new int[]
{
Egl.SURFACE_TYPE, Egl.WINDOW_BIT,
Egl.SURFACE_TYPE, (int) surface_type,
Egl.RENDERABLE_TYPE, (int)renderable_flags,
Egl.RED_SIZE, color.Red,
@ -68,8 +80,6 @@ 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)
{
@ -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);
}
}
}

View file

@ -98,21 +98,67 @@ 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 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()
{
if (Surface != IntPtr.Zero)
DestroySurface(ref surface);
}
public void DestroySurface(ref IntPtr surface_)
{
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))
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()
{