mirror of
https://github.com/Ryujinx/Opentk.git
synced 2024-12-22 20:35:35 +00:00
Fix to able to recover from GraphicsModeException in the override OnH… (#658)
* Fix to able to recover from GraphicsModeException in the override OnHandleCreated. * Changes according to comments: - m_implementation and m_context is now always set. To DummyGLControl if CreateContext fails - Changed FailedCreateContext -> HasValidContext - Changed all if{} to short style with braces. - Added null propagation when applicable - Renamed member variables to have 'm_' infront. - and more ... * Changed 'm_' prefix into '_' Added braces to be using Allman Style * Fixed: 2) SA1003: GLControl.cs(226,47): Operator '(IGraphicsContextInternal)' must not be followed by whitespace. 3) SA1003: GLControl.cs(412,49): Operator '(float)' must not be followed by whitespace. * Removed Paket.Restore.targets from sourcecontrol Added *.Restore.targets to .gitignore * Fixed comments Added *.DotSettings to .gitignore * Removed *.DotSettings from GitIgnore Moved *.Restore.targets to Paket section
This commit is contained in:
parent
0b3f17507c
commit
0a5c346c52
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -317,6 +317,7 @@ _Pvt_Extensions
|
||||||
# Paket dependency manager
|
# Paket dependency manager
|
||||||
.paket/paket.exe
|
.paket/paket.exe
|
||||||
paket-files/
|
paket-files/
|
||||||
|
*.Restore.targets
|
||||||
|
|
||||||
# FAKE - F# Make
|
# FAKE - F# Make
|
||||||
.fake/
|
.fake/
|
||||||
|
|
|
@ -41,22 +41,24 @@ namespace OpenTK
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class GLControl : UserControl
|
public partial class GLControl : UserControl
|
||||||
{
|
{
|
||||||
private IGraphicsContext context;
|
private IGraphicsContext _context;
|
||||||
private IGLControl implementation;
|
private IGLControl _implementation;
|
||||||
private GraphicsMode format;
|
private readonly GraphicsMode _format;
|
||||||
private int major, minor;
|
private readonly int _major;
|
||||||
private GraphicsContextFlags flags;
|
private readonly int _minor;
|
||||||
|
private readonly GraphicsContextFlags _flags;
|
||||||
|
private bool? _initialVsyncValue;
|
||||||
|
|
||||||
private bool? initial_vsync_value;
|
|
||||||
// Indicates that OnResize was called before OnHandleCreated.
|
// Indicates that OnResize was called before OnHandleCreated.
|
||||||
// To avoid issues with missing OpenGL contexts, we suppress
|
// To avoid issues with missing OpenGL contexts, we suppress
|
||||||
// the premature Resize event and raise it as soon as the handle
|
// the premature Resize event and raise it as soon as the handle
|
||||||
// is ready.
|
// is ready.
|
||||||
private bool resize_event_suppressed;
|
private bool _resizeEventSuppressed;
|
||||||
|
|
||||||
// Indicates whether the control is in design mode. Due to issues
|
// Indicates whether the control is in design mode. Due to issues
|
||||||
// wiith the DesignMode property and nested controls,we need to
|
// with the DesignMode property and nested controls,we need to
|
||||||
// evaluate this in the constructor.
|
// evaluate this in the constructor.
|
||||||
private readonly bool design_mode;
|
private readonly bool _designMode;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs a new instance.
|
/// Constructs a new instance.
|
||||||
|
@ -84,7 +86,7 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
if (mode == null)
|
if (mode == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("mode");
|
throw new ArgumentNullException(nameof(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDL does not currently support embedding
|
// SDL does not currently support embedding
|
||||||
|
@ -104,28 +106,37 @@ namespace OpenTK
|
||||||
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
||||||
DoubleBuffered = false;
|
DoubleBuffered = false;
|
||||||
|
|
||||||
this.format = mode;
|
_format = mode;
|
||||||
this.major = major;
|
_major = major;
|
||||||
this.minor = minor;
|
_minor = minor;
|
||||||
this.flags = flags;
|
_flags = flags;
|
||||||
|
|
||||||
// Note: the DesignMode property may be incorrect when nesting controls.
|
// Note: the DesignMode property may be incorrect when nesting controls.
|
||||||
// We use LicenseManager.UsageMode as a workaround (this only works in
|
// We use LicenseManager.UsageMode as a workaround (this only works in
|
||||||
// the constructor).
|
// the constructor).
|
||||||
design_mode =
|
_designMode =
|
||||||
DesignMode ||
|
DesignMode ||
|
||||||
LicenseManager.UsageMode == LicenseUsageMode.Designtime;
|
LicenseManager.UsageMode == LicenseUsageMode.Designtime;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether [failed to create OpenGL context].
|
||||||
|
/// So that the application stays running and is able to recover.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// <c>true</c> if [failed create context]; otherwise, <c>false</c>.
|
||||||
|
/// </value>
|
||||||
|
public bool HasValidContext { get; private set; }
|
||||||
|
|
||||||
private IGLControl Implementation
|
private IGLControl Implementation
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ValidateState();
|
ValidateState();
|
||||||
|
|
||||||
return implementation;
|
return _implementation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +161,7 @@ namespace OpenTK
|
||||||
CreateControl();
|
CreateControl();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (implementation == null || context == null || context.IsDisposed)
|
if (_implementation == null || _context == null || _context.IsDisposed)
|
||||||
{
|
{
|
||||||
RecreateHandle();
|
RecreateHandle();
|
||||||
}
|
}
|
||||||
|
@ -167,7 +178,7 @@ namespace OpenTK
|
||||||
const int CS_HREDRAW = 0x2;
|
const int CS_HREDRAW = 0x2;
|
||||||
const int CS_OWNDC = 0x20;
|
const int CS_OWNDC = 0x20;
|
||||||
|
|
||||||
CreateParams cp = base.CreateParams;
|
var cp = base.CreateParams;
|
||||||
if (Configuration.RunningOnWindows)
|
if (Configuration.RunningOnWindows)
|
||||||
{
|
{
|
||||||
// Setup necessary class style for OpenGL on windows
|
// Setup necessary class style for OpenGL on windows
|
||||||
|
@ -181,46 +192,54 @@ namespace OpenTK
|
||||||
/// <param name="e">Not used.</param>
|
/// <param name="e">Not used.</param>
|
||||||
protected override void OnHandleCreated(EventArgs e)
|
protected override void OnHandleCreated(EventArgs e)
|
||||||
{
|
{
|
||||||
if (context != null)
|
if (!(_implementation is DummyGLControl))
|
||||||
{
|
{ // No need to recreate our DummyGLControl
|
||||||
context.Dispose();
|
_context?.Dispose();
|
||||||
}
|
_implementation?.WindowInfo.Dispose();
|
||||||
|
|
||||||
if (implementation != null)
|
if (_designMode)
|
||||||
{
|
{
|
||||||
implementation.WindowInfo.Dispose();
|
_implementation = new DummyGLControl();
|
||||||
}
|
_context = _implementation.CreateContext(_major, _minor, _flags);
|
||||||
|
HasValidContext = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_implementation = new GLControlFactory().CreateGLControl(_format, this);
|
||||||
|
_context = _implementation.CreateContext(_major, _minor, _flags);
|
||||||
|
HasValidContext = true;
|
||||||
|
}
|
||||||
|
catch (GraphicsModeException)
|
||||||
|
{
|
||||||
|
_implementation = new DummyGLControl();
|
||||||
|
_context = _implementation.CreateContext(_major, _minor, _flags);
|
||||||
|
HasValidContext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (design_mode)
|
MakeCurrent();
|
||||||
{
|
|
||||||
implementation = new DummyGLControl();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
implementation = new GLControlFactory().CreateGLControl(format, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
context = implementation.CreateContext(major, minor, flags);
|
if (HasValidContext)
|
||||||
MakeCurrent();
|
{
|
||||||
|
((IGraphicsContextInternal)_context).LoadAll();
|
||||||
|
}
|
||||||
|
|
||||||
if (!design_mode)
|
// Deferred setting of vsync mode. See VSync property for more information.
|
||||||
{
|
if (_initialVsyncValue.HasValue)
|
||||||
((IGraphicsContextInternal)Context).LoadAll();
|
{
|
||||||
}
|
_context.SwapInterval = _initialVsyncValue.Value ? 1 : 0;
|
||||||
|
_initialVsyncValue = null;
|
||||||
// Deferred setting of vsync mode. See VSync property for more information.
|
}
|
||||||
if (initial_vsync_value.HasValue)
|
|
||||||
{
|
|
||||||
Context.SwapInterval = initial_vsync_value.Value ? 1 : 0;
|
|
||||||
initial_vsync_value = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnHandleCreated(e);
|
base.OnHandleCreated(e);
|
||||||
|
|
||||||
if (resize_event_suppressed)
|
if (_resizeEventSuppressed)
|
||||||
{
|
{
|
||||||
OnResize(EventArgs.Empty);
|
OnResize(EventArgs.Empty);
|
||||||
resize_event_suppressed = false;
|
_resizeEventSuppressed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,18 +251,23 @@ namespace OpenTK
|
||||||
// => This allows to perform cleanup operations in OnHandleDestroyed handlers
|
// => This allows to perform cleanup operations in OnHandleDestroyed handlers
|
||||||
base.OnHandleDestroyed(e);
|
base.OnHandleDestroyed(e);
|
||||||
|
|
||||||
if (context != null)
|
if (_implementation is DummyGLControl)
|
||||||
{
|
{
|
||||||
context.Dispose();
|
// No need to destroy our DummyGLControl
|
||||||
context = null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (implementation != null)
|
if (_context != null)
|
||||||
{
|
{
|
||||||
implementation.WindowInfo.Dispose();
|
_context.Dispose();
|
||||||
implementation = null;
|
_context = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_implementation != null)
|
||||||
|
{
|
||||||
|
_implementation.WindowInfo.Dispose();
|
||||||
|
_implementation = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -254,7 +278,7 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
ValidateState();
|
ValidateState();
|
||||||
|
|
||||||
if (design_mode)
|
if (_designMode)
|
||||||
{
|
{
|
||||||
e.Graphics.Clear(BackColor);
|
e.Graphics.Clear(BackColor);
|
||||||
}
|
}
|
||||||
|
@ -273,7 +297,7 @@ namespace OpenTK
|
||||||
// Do not raise OnResize event before the handle and context are created.
|
// Do not raise OnResize event before the handle and context are created.
|
||||||
if (!IsHandleCreated)
|
if (!IsHandleCreated)
|
||||||
{
|
{
|
||||||
resize_event_suppressed = true;
|
_resizeEventSuppressed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,9 +306,9 @@ namespace OpenTK
|
||||||
DelayUpdate delay = PerformContextUpdate;
|
DelayUpdate delay = PerformContextUpdate;
|
||||||
BeginInvoke(delay); //Need the native window to resize first otherwise our control will be in the wrong place.
|
BeginInvoke(delay); //Need the native window to resize first otherwise our control will be in the wrong place.
|
||||||
}
|
}
|
||||||
else if (context != null)
|
else
|
||||||
{
|
{
|
||||||
context.Update (Implementation.WindowInfo);
|
_context?.Update(Implementation.WindowInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnResize(e);
|
base.OnResize(e);
|
||||||
|
@ -294,15 +318,13 @@ namespace OpenTK
|
||||||
/// Needed to delay the invoke on OS X. Also needed because OpenTK is .NET 2, otherwise I'd use an inline Action.
|
/// Needed to delay the invoke on OS X. Also needed because OpenTK is .NET 2, otherwise I'd use an inline Action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public delegate void DelayUpdate();
|
public delegate void DelayUpdate();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Execute the delayed context update
|
/// Execute the delayed context update
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void PerformContextUpdate()
|
public void PerformContextUpdate()
|
||||||
{
|
{
|
||||||
if (context != null)
|
_context?.Update(Implementation.WindowInfo);
|
||||||
{
|
|
||||||
context.Update (Implementation.WindowInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -311,10 +333,7 @@ namespace OpenTK
|
||||||
/// <param name="e">A System.EventArgs that contains the event data.</param>
|
/// <param name="e">A System.EventArgs that contains the event data.</param>
|
||||||
protected override void OnParentChanged(EventArgs e)
|
protected override void OnParentChanged(EventArgs e)
|
||||||
{
|
{
|
||||||
if (context != null)
|
_context?.Update(Implementation.WindowInfo);
|
||||||
{
|
|
||||||
context.Update(Implementation.WindowInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnParentChanged(e);
|
base.OnParentChanged(e);
|
||||||
}
|
}
|
||||||
|
@ -377,9 +396,8 @@ namespace OpenTK
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
ValidateState();
|
ValidateState();
|
||||||
return context;
|
return _context;
|
||||||
}
|
}
|
||||||
private set { context = value; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -409,12 +427,12 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
if (!IsHandleCreated)
|
if (!IsHandleCreated)
|
||||||
{
|
{
|
||||||
return initial_vsync_value.HasValue ?
|
return !_initialVsyncValue.HasValue || _initialVsyncValue.Value;
|
||||||
initial_vsync_value.Value : true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateState();
|
ValidateState();
|
||||||
ValidateContext("VSync");
|
ValidateContext(@"VSync");
|
||||||
|
|
||||||
return Context.SwapInterval != 0;
|
return Context.SwapInterval != 0;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
|
@ -425,12 +443,12 @@ namespace OpenTK
|
||||||
// Work around this issue by deferring VSync mode setting to the HandleCreated event.
|
// Work around this issue by deferring VSync mode setting to the HandleCreated event.
|
||||||
if (!IsHandleCreated)
|
if (!IsHandleCreated)
|
||||||
{
|
{
|
||||||
initial_vsync_value = value;
|
_initialVsyncValue = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateState();
|
ValidateState();
|
||||||
ValidateContext("VSync");
|
ValidateContext(@"VSync");
|
||||||
Context.SwapInterval = value ? 1 : 0;
|
Context.SwapInterval = value ? 1 : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -452,9 +470,6 @@ namespace OpenTK
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="OpenTK.Platform.IWindowInfo"/> for this instance.
|
/// Gets the <see cref="OpenTK.Platform.IWindowInfo"/> for this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IWindowInfo WindowInfo
|
public IWindowInfo WindowInfo => _implementation.WindowInfo;
|
||||||
{
|
|
||||||
get { return implementation.WindowInfo; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue