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

View file

@ -147,7 +147,8 @@ namespace OpenTK.Platform.Windows
public void SwapBuffers() public void SwapBuffers()
{ {
if (!Functions.SwapBuffers(currentWindow.DeviceContext)) 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 #endregion
@ -395,11 +396,13 @@ namespace OpenTK.Platform.Windows
{ {
if (!disposed) if (!disposed)
{ {
DestroyContext();
if (calledManually) 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; disposed = true;
} }
@ -421,10 +424,7 @@ namespace OpenTK.Platform.Windows
{ {
try try
{ {
if (!Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero)) // This will fail if the user calls Dispose() on thread X when the context is current on thread Y.
Debug.Print("Failed to make OpenGL context {0} non current. Error: {1}",
renderContext.ToString(), Marshal.GetLastWin32Error());
if (!Wgl.Imports.DeleteContext(renderContext.Handle)) if (!Wgl.Imports.DeleteContext(renderContext.Handle))
Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}", Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}",
renderContext.ToString(), Marshal.GetLastWin32Error()); renderContext.ToString(), Marshal.GetLastWin32Error());
@ -439,27 +439,6 @@ namespace OpenTK.Platform.Windows
} }
renderContext = ContextHandle.Zero; 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 #endregion

View file

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