+ 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
--- /dev/null
+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);
+
+ }
+}
\ No newline at end of file
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
{
/// <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,
}
}
<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" />
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;
using System;
using System.Diagnostics;
using OpenTK.Graphics;
+using OpenTK.Graphics.ES20;
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
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 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)
- 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);
+ 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,
{
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()));
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,
Egl.NONE,
};
- IntPtr display = window.Display;
-
int num_configs;
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out num_configs) || num_configs == 0)
{
return new GraphicsMode(active_config, new ColorFormat(r, g, b, a), d, s, sample_buffers > 0 ? samples : 0, 0, 2, false);
}
+
}
}
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)
{
- if (Egl.GetCurrentSurface(Egl.DRAW) == Surface)
- Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+ return;
+ }
- if (!Egl.DestroySurface(Display, Surface))
- Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
- Surface = IntPtr.Zero;
+ 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()