mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-25 23:11:05 +00:00
Added automatic error checking for all OpenGL function calls (debug mode only). Begin()-End() regions are handled correctly.
This commit is contained in:
parent
c0f573f996
commit
7a57fbd8a7
|
@ -2,7 +2,7 @@
|
||||||
//
|
//
|
||||||
// The Open Toolkit Library License
|
// The Open Toolkit Library License
|
||||||
//
|
//
|
||||||
// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
|
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||||
//
|
//
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
// of this software and associated documentation files (the "Software"), to deal
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -350,11 +350,7 @@ namespace Bind.Structures
|
||||||
{
|
{
|
||||||
// No special wrapper needed - just call this delegate:
|
// No special wrapper needed - just call this delegate:
|
||||||
Function f = new Function(this);
|
Function f = new Function(this);
|
||||||
|
f.CreateBody(false);
|
||||||
if (f.ReturnType.CurrentType.ToLower().Contains("void"))
|
|
||||||
f.Body.Add(String.Format("{0};", f.CallString()));
|
|
||||||
else
|
|
||||||
f.Body.Add(String.Format("return {0};", f.CallString()));
|
|
||||||
|
|
||||||
wrappers.Add(f);
|
wrappers.Add(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,11 @@ namespace Bind.Structures
|
||||||
static Regex endings = new Regex(@"((([df]|u?[isb])v?)|v)", RegexOptions.Compiled | RegexOptions.RightToLeft);
|
static Regex endings = new Regex(@"((([df]|u?[isb])v?)|v)", RegexOptions.Compiled | RegexOptions.RightToLeft);
|
||||||
static Regex endingsNotToTrim = new Regex("(ib|[tdrey]s|[eE]n[vd]|bled|Flagv|Tess|Status|Pixels)", RegexOptions.Compiled | RegexOptions.RightToLeft);
|
static Regex endingsNotToTrim = new Regex("(ib|[tdrey]s|[eE]n[vd]|bled|Flagv|Tess|Status|Pixels)", RegexOptions.Compiled | RegexOptions.RightToLeft);
|
||||||
|
|
||||||
|
// Add a trailing v to functions matching this regex. Used to differntiate between overloads taking both
|
||||||
|
// a 'type' and a 'ref type' (such overloads are not CLS Compliant).
|
||||||
|
// The default Regex matches no functions. Create a new Regex in Bind.Generator classes to override the default behavior.
|
||||||
|
internal static Regex endingsAddV = new Regex("^0", RegexOptions.Compiled);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Fields
|
#region Fields
|
||||||
|
@ -44,15 +49,6 @@ namespace Bind.Structures
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a trailing v to functions matching this regex. Used to differntiate between overloads taking both
|
|
||||||
/// a 'type' and a 'ref type' (such overloads are not CLS Compliant).
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// The default Regex matches no functions. Create a new Regex in Bind.Generator classes to override the default behavior.
|
|
||||||
/// </remarks>
|
|
||||||
internal static Regex endingsAddV = new Regex("^0", RegexOptions.Compiled);
|
|
||||||
|
|
||||||
#region --- Constructors ---
|
#region --- Constructors ---
|
||||||
|
|
||||||
|
@ -72,12 +68,16 @@ namespace Bind.Structures
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region public Delegate WrappedDelegate
|
||||||
|
|
||||||
public Delegate WrappedDelegate
|
public Delegate WrappedDelegate
|
||||||
{
|
{
|
||||||
get { return wrapped_delegate; }
|
get { return wrapped_delegate; }
|
||||||
set { wrapped_delegate = value; }
|
set { wrapped_delegate = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region public void TurnVoidPointersToIntPtr()
|
#region public void TurnVoidPointersToIntPtr()
|
||||||
|
|
||||||
public void TurnVoidPointersToIntPtr()
|
public void TurnVoidPointersToIntPtr()
|
||||||
|
@ -394,10 +394,10 @@ namespace Bind.Structures
|
||||||
|
|
||||||
#region public void CreateBody(bool wantCLSCompliance)
|
#region public void CreateBody(bool wantCLSCompliance)
|
||||||
|
|
||||||
static List<string> handle_statements = new List<string>();
|
readonly List<string> handle_statements = new List<string>();
|
||||||
static List<string> handle_release_statements = new List<string>();
|
readonly List<string> handle_release_statements = new List<string>();
|
||||||
static List<string> fixed_statements = new List<string>();
|
readonly List<string> fixed_statements = new List<string>();
|
||||||
static List<string> assign_statements = new List<string>();
|
readonly List<string> assign_statements = new List<string>();
|
||||||
|
|
||||||
public void CreateBody(bool wantCLSCompliance)
|
public void CreateBody(bool wantCLSCompliance)
|
||||||
{
|
{
|
||||||
|
@ -459,7 +459,21 @@ namespace Bind.Structures
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f.Unsafe || fixed_statements.Count > 0)
|
// Automatic OpenGL error checking.
|
||||||
|
// See OpenTK.Graphics.ErrorHelper for more information.
|
||||||
|
// Make sure that no error checking is added to the GetError function,
|
||||||
|
// as that would cause infinite recursion!
|
||||||
|
if (f.TrimmedName != "GetError")
|
||||||
|
{
|
||||||
|
f.Body.Add("#if DEBUG");
|
||||||
|
f.Body.Add("using (new ErrorHelper(GraphicsContext.CurrentContext))");
|
||||||
|
f.Body.Add("{");
|
||||||
|
if (f.TrimmedName == "Begin")
|
||||||
|
f.Body.Add("GraphicsContext.CurrentContext.EnterBeginRegion();");
|
||||||
|
f.Body.Add("#endif");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!f.Unsafe && fixed_statements.Count > 0)
|
||||||
{
|
{
|
||||||
f.Body.Add("unsafe");
|
f.Body.Add("unsafe");
|
||||||
f.Body.Add("{");
|
f.Body.Add("{");
|
||||||
|
@ -529,7 +543,7 @@ namespace Bind.Structures
|
||||||
f.Body.Add("}");
|
f.Body.Add("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!f.Unsafe || fixed_statements.Count > 0)
|
if (!f.Unsafe && fixed_statements.Count > 0)
|
||||||
{
|
{
|
||||||
f.Body.Unindent();
|
f.Body.Unindent();
|
||||||
f.Body.Add("}");
|
f.Body.Add("}");
|
||||||
|
@ -541,6 +555,15 @@ namespace Bind.Structures
|
||||||
f.Body.Add("}");
|
f.Body.Add("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f.TrimmedName != "GetError")
|
||||||
|
{
|
||||||
|
f.Body.Add("#if DEBUG");
|
||||||
|
if (f.TrimmedName == "End")
|
||||||
|
f.Body.Add("GraphicsContext.CurrentContext.ExitBeginRegion();");
|
||||||
|
f.Body.Add("}");
|
||||||
|
f.Body.Add("#endif");
|
||||||
|
}
|
||||||
|
|
||||||
this.Body = f.Body;
|
this.Body = f.Body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
74
Source/OpenTK/Graphics/GL/ErrorHelper.cs
Normal file
74
Source/OpenTK/Graphics/GL/ErrorHelper.cs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#region License
|
||||||
|
//
|
||||||
|
// The Open Toolkit Library License
|
||||||
|
//
|
||||||
|
// Copyright (c) 2006 - 2009 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 System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenTK.Graphics
|
||||||
|
{
|
||||||
|
// Used in debug-mode only, for automatic OpenGL error-checking.
|
||||||
|
//
|
||||||
|
// Works like this: an instance is created before each OpenGL function is called.
|
||||||
|
// The constructor resets the OpenGL error state. Once the native function returns,
|
||||||
|
// the error state is checked again, raising the relevant exceptions.
|
||||||
|
//
|
||||||
|
// A using-region is used to ensure Dispose() is called.
|
||||||
|
//
|
||||||
|
// Make sure that no error checking is added to the GetError function,
|
||||||
|
// as that would cause infinite recursion!
|
||||||
|
struct ErrorHelper : IDisposable
|
||||||
|
{
|
||||||
|
#region Fields
|
||||||
|
|
||||||
|
readonly GraphicsContext Context;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ErrorHelper(GraphicsContext context)
|
||||||
|
{
|
||||||
|
if (context == null)
|
||||||
|
throw new GraphicsContextMissingException();
|
||||||
|
|
||||||
|
Context = context;
|
||||||
|
Context.ResetErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Context.CheckErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -266,7 +266,6 @@ namespace OpenTK.Graphics
|
||||||
MethodInfo m;
|
MethodInfo m;
|
||||||
return
|
return
|
||||||
GetExtensionDelegate(name, signature) ??
|
GetExtensionDelegate(name, signature) ??
|
||||||
/*((m = importsClass.GetMethod(name.Substring(2), BindingFlags.Static | BindingFlags.NonPublic)) != null ?*/
|
|
||||||
(Imports.FunctionMap.TryGetValue((name.Substring(2)), out m) ?
|
(Imports.FunctionMap.TryGetValue((name.Substring(2)), out m) ?
|
||||||
Delegate.CreateDelegate(signature, m) : null);
|
Delegate.CreateDelegate(signature, m) : null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,8 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
#region --- Static Members ---
|
#region --- Static Members ---
|
||||||
|
|
||||||
|
#region public static GraphicsContext CreateDummyContext()
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries.
|
/// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -143,34 +145,27 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region --- Private Members ---
|
#region public static void Assert()
|
||||||
|
|
||||||
#region void ContextDestroyed(IGraphicsContext context, EventArgs e)
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the Destroy event.
|
/// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">The OpenTK.Platform.IGraphicsContext that was destroyed.</param>
|
/// <exception cref="GraphicsContextMissingException">Generated when no GraphicsContext is current in the calling thread.</exception>
|
||||||
/// <param name="e">Not used.</param>
|
public static void Assert()
|
||||||
void ContextDestroyed(IGraphicsContext context, EventArgs e)
|
|
||||||
{
|
{
|
||||||
this.Destroy -= ContextDestroyed;
|
if (GraphicsContext.CurrentContext == null)
|
||||||
//available_contexts.Remove(((IGraphicsContextInternal)this).Context);
|
throw new GraphicsContextMissingException();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region --- Public Members ---
|
|
||||||
|
|
||||||
#region public static IGraphicsContext CurrentContext
|
#region public static IGraphicsContext CurrentContext
|
||||||
|
|
||||||
internal delegate ContextHandle GetCurrentContextDelegate();
|
internal delegate ContextHandle GetCurrentContextDelegate();
|
||||||
internal static GetCurrentContextDelegate GetCurrentContext;
|
internal static GetCurrentContextDelegate GetCurrentContext;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the current GraphicsContext in the calling thread.
|
/// Gets the GraphicsContext that is current in the calling thread.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static GraphicsContext CurrentContext
|
public static GraphicsContext CurrentContext
|
||||||
{
|
{
|
||||||
|
@ -187,13 +182,6 @@ namespace OpenTK.Graphics
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//set
|
|
||||||
//{
|
|
||||||
// if (value != null)
|
|
||||||
// value.MakeCurrent();
|
|
||||||
// else if (CurrentContext != null)
|
|
||||||
// CurrentContext.IsCurrent = false;
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -231,20 +219,84 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public static AvailableDisplayFormats
|
#endregion
|
||||||
|
|
||||||
|
#region --- Internal Members ---
|
||||||
|
|
||||||
|
bool inside_begin_region;
|
||||||
|
List<ErrorCode> error_list = new List<ErrorCode>();
|
||||||
|
|
||||||
|
// Indicates that we entered a GL.Begin() - GL.End() region.
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
internal void EnterBeginRegion()
|
||||||
|
{
|
||||||
|
inside_begin_region = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Indicates that we left a GL.Begin() - GL.End() region.
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
internal void ExitBeginRegion()
|
||||||
|
{
|
||||||
|
inside_begin_region = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve all OpenGL errors to clear the error list.
|
||||||
|
// See http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/geterror.html
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
internal void ResetErrors()
|
||||||
|
{
|
||||||
|
if (!inside_begin_region)
|
||||||
|
{
|
||||||
|
while (GL.GetError() != ErrorCode.NoError)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve all OpenGL errors and throw an exception if anything other than NoError is returned.
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
internal void CheckErrors()
|
||||||
|
{
|
||||||
|
if (!inside_begin_region)
|
||||||
|
{
|
||||||
|
error_list.Clear();
|
||||||
|
ErrorCode error;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
error = GL.GetError();
|
||||||
|
error_list.Add(error);
|
||||||
|
} while (error != ErrorCode.NoError);
|
||||||
|
|
||||||
|
if (error_list.Count != 1)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
foreach (ErrorCode e in error_list)
|
||||||
|
{
|
||||||
|
sb.Append(e.ToString());
|
||||||
|
sb.Append(", ");
|
||||||
|
}
|
||||||
|
sb.Remove(sb.Length - 2, 2);
|
||||||
|
|
||||||
|
Debug.Assert(error_list.Count == 1, "OpenTK detected an OpenGL error.",
|
||||||
|
String.Format("The following errors where reported: \"{0}\"", sb.ToString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region public static void Assert()
|
#region --- Private Members ---
|
||||||
|
|
||||||
|
#region void ContextDestroyed(IGraphicsContext context, EventArgs e)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't.
|
/// Handles the Destroy event.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Assert()
|
/// <param name="context">The OpenTK.Platform.IGraphicsContext that was destroyed.</param>
|
||||||
|
/// <param name="e">Not used.</param>
|
||||||
|
void ContextDestroyed(IGraphicsContext context, EventArgs e)
|
||||||
{
|
{
|
||||||
if (GraphicsContext.CurrentContext == null)
|
this.Destroy -= ContextDestroyed;
|
||||||
throw new GraphicsContextMissingException();
|
//available_contexts.Remove(((IGraphicsContextInternal)this).Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -344,60 +396,38 @@ namespace OpenTK.Graphics
|
||||||
|
|
||||||
#region --- IGraphicsContextInternal Members ---
|
#region --- IGraphicsContextInternal Members ---
|
||||||
|
|
||||||
#region Implementation
|
/// <summary>
|
||||||
|
/// Gets the platform-specific implementation of this IGraphicsContext.
|
||||||
|
/// </summary>
|
||||||
IGraphicsContext IGraphicsContextInternal.Implementation
|
IGraphicsContext IGraphicsContextInternal.Implementation
|
||||||
{
|
{
|
||||||
get { return implementation; }
|
get { return implementation; }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
/// <summary>
|
||||||
|
/// Loads all OpenGL extensions.
|
||||||
#region void LoadAll()
|
/// </summary>
|
||||||
|
|
||||||
void IGraphicsContextInternal.LoadAll()
|
void IGraphicsContextInternal.LoadAll()
|
||||||
{
|
{
|
||||||
(implementation as IGraphicsContextInternal).LoadAll();
|
(implementation as IGraphicsContextInternal).LoadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
/// <summary>
|
||||||
|
/// Gets a handle to the OpenGL rendering context.
|
||||||
/// <internal />
|
/// </summary>
|
||||||
/// <summary>Gets a handle to the OpenGL rendering context.</summary>
|
|
||||||
ContextHandle IGraphicsContextInternal.Context
|
ContextHandle IGraphicsContextInternal.Context
|
||||||
{
|
{
|
||||||
get { return ((IGraphicsContextInternal)implementation).Context; }
|
get { return ((IGraphicsContextInternal)implementation).Context; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the IWindowInfo describing the window associated with this context.
|
|
||||||
/// </summary>
|
|
||||||
IWindowInfo IGraphicsContextInternal.Info
|
|
||||||
{
|
|
||||||
get { return (implementation as IGraphicsContextInternal).Info; }
|
|
||||||
//internal set { (implementation as IGLContextInternal).Info = value; }
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the GraphicsMode of the context.
|
/// Gets the GraphicsMode of the context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GraphicsMode GraphicsMode
|
public GraphicsMode GraphicsMode
|
||||||
{
|
{
|
||||||
get { return implementation.GraphicsMode; }
|
get { return (implementation as IGraphicsContextInternal).GraphicsMode; }
|
||||||
}
|
}
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// Gets a System.IntPtr containing the handle to the OpenGL context which is current in the
|
|
||||||
///// calling thread, or IntPtr.Zero if no OpenGL context is current.
|
|
||||||
///// </summary>
|
|
||||||
///// <returns>A System.IntPtr that holds the handle to the current OpenGL context.</returns>
|
|
||||||
//ContextHandle IGLContextInternal.GetCurrentContext()
|
|
||||||
//{
|
|
||||||
// return (implementation as IGLContextInternal).GetCurrentContext();
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers an OpenGL resource for disposal.
|
/// Registers an OpenGL resource for disposal.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in a new issue