Browse Source

Added the option to include the OpenGL error code description when constructing OpenGlException

pull/2205/head
mstr2 7 years ago
parent
commit
02faa2e3ac
  1. 6
      src/Avalonia.OpenGL/EglContext.cs
  2. 17
      src/Avalonia.OpenGL/EglDisplay.cs
  3. 7
      src/Avalonia.OpenGL/EglInterface.cs
  4. 5
      src/Avalonia.OpenGL/GlInterface.cs
  5. 38
      src/Avalonia.OpenGL/OpenGlException.cs

6
src/Avalonia.OpenGL/EglContext.cs

@ -31,14 +31,14 @@ namespace Avalonia.OpenGL
public void MakeCurrent()
{
if (!_egl.MakeCurrent(_disp.Handle, IntPtr.Zero, IntPtr.Zero, Context))
throw new OpenGlException("eglMakeCurrent failed");
throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl);
}
public void MakeCurrent(EglSurface surface)
{
var surf = ((EglSurface)surface)?.DangerousGetHandle() ?? OffscreenSurface;
var surf = surface?.DangerousGetHandle() ?? OffscreenSurface;
if (!_egl.MakeCurrent(_disp.Handle, surf, surf, Context))
throw new OpenGlException("eglMakeCurrent failed");
throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl);
}
}
}

17
src/Avalonia.OpenGL/EglDisplay.cs

@ -1,5 +1,4 @@
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Avalonia.Platform.Interop;
using static Avalonia.OpenGL.EglConsts;
@ -34,11 +33,11 @@ namespace Avalonia.OpenGL
if (_display == IntPtr.Zero)
_display = _egl.GetDisplay(IntPtr.Zero);
if(_display == IntPtr.Zero)
throw new OpenGlException("eglGetDisplay failed");
if (_display == IntPtr.Zero)
throw OpenGlException.GetFormattedException("eglGetDisplay", _egl);
if (!_egl.Initialize(_display, out var major, out var minor))
throw new OpenGlException("eglInitialize failed");
throw OpenGlException.GetFormattedException("eglInitialize", _egl);
foreach (var cfg in new[]
{
@ -113,7 +112,7 @@ namespace Avalonia.OpenGL
var shareCtx = (EglContext)share;
var ctx = _egl.CreateContext(_display, _config, shareCtx?.Context ?? IntPtr.Zero, _contextAttributes);
if (ctx == IntPtr.Zero)
throw new OpenGlException("eglCreateContext failed");
throw OpenGlException.GetFormattedException("eglCreateContext", _egl);
var surf = _egl.CreatePBufferSurface(_display, _config, new[]
{
EGL_WIDTH, 1,
@ -121,7 +120,7 @@ namespace Avalonia.OpenGL
EGL_NONE
});
if (surf == IntPtr.Zero)
throw new OpenGlException("eglCreatePbufferSurface failed");
throw OpenGlException.GetFormattedException("eglCreatePBufferSurface", _egl);
var rv = new EglContext(this, _egl, ctx, surf);
rv.MakeCurrent(null);
return rv;
@ -130,14 +129,14 @@ namespace Avalonia.OpenGL
public void ClearContext()
{
if (!_egl.MakeCurrent(_display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero))
throw new OpenGlException("eglMakeCurrent failed");
throw OpenGlException.GetFormattedException("eglMakeCurrent", _egl);
}
public EglSurface CreateWindowSurface(IntPtr window)
{
var s = _egl.CreateWindowSurface(_display, _config, window, new[] {EGL_NONE, EGL_NONE});
if (s == IntPtr.Zero)
throw new OpenGlException("eglCreateWindowSurface failed");
throw OpenGlException.GetFormattedException("eglCreateWindowSurface", _egl);
return new EglSurface(this, _egl, s);
}

7
src/Avalonia.OpenGL/EglInterface.cs

@ -1,7 +1,6 @@
using System;
using Avalonia.Platform;
using Avalonia.Platform.Interop;
using static Avalonia.OpenGL.EglConsts;
namespace Avalonia.OpenGL
{
@ -32,8 +31,12 @@ namespace Avalonia.OpenGL
var lib = dyn.LoadLibrary(library);
return (s, o) => dyn.GetProcAddress(lib, s, o);
}
// ReSharper disable UnassignedGetOnlyAutoProperty
public delegate int EglGetError();
[EntryPoint("eglGetError")]
public EglGetError GetError { get; }
public delegate IntPtr EglGetDisplay(IntPtr nativeDisplay);
[EntryPoint("eglGetDisplay")]
public EglGetDisplay GetDisplay { get; }

5
src/Avalonia.OpenGL/GlInterface.cs

@ -19,7 +19,10 @@ namespace Avalonia.OpenGL
public T GetProcAddress<T>(string proc) => Marshal.GetDelegateForFunctionPointer<T>(GetProcAddress(proc));
// ReSharper disable UnassignedGetOnlyAutoProperty
public delegate int GlGetError();
[EntryPoint("glGetError")]
public GlGetError GetError { get; }
public delegate void GlClearStencil(int s);
[EntryPoint("glClearStencil")]
public GlClearStencil ClearStencil { get; }

38
src/Avalonia.OpenGL/OpenGlException.cs

@ -1,12 +1,50 @@
using System;
using System.Reflection;
namespace Avalonia.OpenGL
{
public class OpenGlException : Exception
{
public int? ErrorCode { get; private set; }
public OpenGlException(string message) : base(message)
{
}
private OpenGlException(string message, int errorCode) : base(message)
{
ErrorCode = errorCode;
}
public static OpenGlException GetFormattedException(string funcName, EglInterface egl)
{
return GetFormattedException(typeof(EglConsts).GetFields(), funcName, 0x3000, 0x301F, egl.GetError());
}
public static OpenGlException GetFormattedException(string funcName, GlInterface gl)
{
return GetFormattedException(typeof(GlConsts).GetFields(), funcName, 0x0500, 0x0505, gl.GetError());
}
private static OpenGlException GetFormattedException(
FieldInfo[] fields, string funcName, int minValue, int maxValue, int errorCode)
{
foreach (var field in fields)
{
int value = (int)field.GetValue(null);
if (value < minValue || value > maxValue)
{
continue;
}
if (value == errorCode)
{
return new OpenGlException(
$"{funcName} failed with error {field.Name} (0x{errorCode.ToString("X")})", errorCode);
}
}
return new OpenGlException($"{funcName} failed with error 0x{errorCode.ToString("X")}", errorCode);
}
}
}

Loading…
Cancel
Save