Ensured IWindowInfo.Dispose() is called when the GLControl handle is destroyed.

WinGLContext.SwapBuffers now throws an exception on failure.
This commit is contained in:
the_fiddler 2009-05-19 09:48:47 +00:00
parent 9bdc21cabd
commit d686adb42a
3 changed files with 31 additions and 32 deletions

View file

@ -124,6 +124,7 @@ namespace OpenTK
this.Context.Dispose();
this.Context = null;
}
this.window_info.Dispose();
this.window_info = null;
}
@ -135,6 +136,7 @@ namespace OpenTK
{
if (DesignMode)
e.Graphics.Clear(BackColor);
base.OnPaint(e);
}

View file

@ -147,7 +147,8 @@ namespace OpenTK.Platform.Windows
public void SwapBuffers()
{
if (!Functions.SwapBuffers(currentWindow.DeviceContext))
Debug.Print("SwapBuffers failed, error: {0}", Marshal.GetLastWin32Error());
throw new GraphicsContextException(String.Format(
"Failed to swap buffers for context {0} current. Error: {1}", this, Marshal.GetLastWin32Error()));
}
#endregion
@ -395,11 +396,13 @@ namespace OpenTK.Platform.Windows
{
if (!disposed)
{
DestroyContext();
if (calledManually)
{
// Safe to clean managed resources
DestroyContext();
}
else
{
Debug.Print("[Warning] OpenGL context {0} leaked. Did you forget to call IGraphicsContext.Dispose()?", renderContext.Handle);
}
disposed = true;
}
@ -421,10 +424,7 @@ namespace OpenTK.Platform.Windows
{
try
{
if (!Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero))
Debug.Print("Failed to make OpenGL context {0} non current. Error: {1}",
renderContext.ToString(), Marshal.GetLastWin32Error());
// This will fail if the user calls Dispose() on thread X when the context is current on thread Y.
if (!Wgl.Imports.DeleteContext(renderContext.Handle))
Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}",
renderContext.ToString(), Marshal.GetLastWin32Error());
@ -439,27 +439,6 @@ namespace OpenTK.Platform.Windows
}
renderContext = ContextHandle.Zero;
}
//if (deviceContext != IntPtr.Zero)
//{
// if (!Functions.ReleaseDC(this.windowInfo.Handle, deviceContext))
// {
// //throw new ApplicationException("Could not release device context. Error: " + Marshal.GetLastWin32Error());
// //Debug.Print("Could not destroy the device context. Error: {0}", Marshal.GetLastWin32Error());
// }
//}
/*
if (opengl32Handle != IntPtr.Zero)
{
if (!Functions.FreeLibrary(opengl32Handle))
{
//throw new ApplicationException("FreeLibray call failed ('opengl32.dll'), Error: " + Marshal.GetLastWin32Error());
//Debug.Print("Could not release {0}. Error: {1}", opengl32Name, Marshal.GetLastWin32Error());
}
opengl32Handle = IntPtr.Zero;
}
*/
}
#endregion

View file

@ -20,19 +20,37 @@ namespace OpenTK.Platform.Windows
MSG msg = new MSG();
GraphicsMode mode;
Control control;
WinWindowInfo window_info;
internal WinGLControl(GraphicsMode mode, Control control)
{
this.mode = mode;
this.control = control;
this.control.HandleCreated += delegate(object sender, EventArgs e)
{
if (window_info != null)
window_info.Dispose();
window_info = new WinWindowInfo(this.control.Handle, null);
};
this.control.HandleDestroyed += delegate(object sender, EventArgs e)
{
if (window_info != null)
{
window_info.Dispose();
window_info = null;
}
};
}
#region --- IGLControl Members ---
public GraphicsContext CreateContext(int major, int minor, GraphicsContextFlags flags)
{
WinWindowInfo window = new WinWindowInfo(control.Handle, null);
return new GraphicsContext(mode, window, major, minor, flags);
// Make sure the Control exists before creating the context.
if (window_info == null)
window_info = new WinWindowInfo(control.Handle, null);
return new GraphicsContext(mode, window_info, major, minor, flags);
}
public bool IsIdle
@ -45,7 +63,7 @@ namespace OpenTK.Platform.Windows
get
{
// This method forces the creation of the control. Beware of this side-effect!
return new WinWindowInfo(control.Handle, null);
return window_info;
}
}