diff --git a/Source/GLControl/GLControl.cs b/Source/GLControl/GLControl.cs index 094dc28d..adc6dcf1 100644 --- a/Source/GLControl/GLControl.cs +++ b/Source/GLControl/GLControl.cs @@ -164,7 +164,7 @@ namespace OpenTK // Deferred setting of vsync mode. See VSync property for more information. if (initial_vsync_value.HasValue) { - Context.VSync = initial_vsync_value.Value; + Context.SwapInterval = initial_vsync_value.Value ? 1 : 0; initial_vsync_value = null; } @@ -331,7 +331,7 @@ namespace OpenTK /// /// Gets or sets a value indicating whether vsync is active for this GLControl. /// - [Description("Indicates whether GLControl updates are synced to the monitor's refresh.")] + [Description("Indicates whether GLControl updates are synced to the monitor's refresh rate.")] public bool VSync { get diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index b44191bc..1f02c314 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -518,9 +518,9 @@ namespace OpenTK { // Check if we have enough time for a vsync if (RenderTime > 2.0 * TargetRenderPeriod) - Context.VSync = false; + Context.SwapInterval = 0; else - Context.VSync = true; + Context.SwapInterval = 1; } render_period = render_args.Time = time; diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index 38817755..38ad336e 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -461,14 +461,36 @@ namespace OpenTK.Graphics } /// - /// Gets or sets a value indicating whether VSync is enabled. + /// [obsolete] Use SwapInterval property instead. + /// Gets or sets a value indicating whether VSync is enabled. When VSync is + /// enabled, calls will be synced to the refresh + /// rate of the that contains improving visual + /// quality and reducing CPU usage. However, systems that cannot maintain + /// the requested rendering rate will suffer from large jumps in performance. + /// This can be counteracted by increasing the + /// value. /// + [Obsolete("Use SwapInterval property instead.")] public bool VSync { get { return implementation.VSync; } set { implementation.VSync = value; } } + /// + /// Gets or sets a positive integer in the range [1, n), indicating the number of + /// refreshes between consecutive + /// calls. The maximum value for n is + /// implementation-dependent. The default value is 1. + /// This value will only affect instances where is enabled. + /// Invalid values will be clamped to the valid range. + /// + public int SwapInterval + { + get { return implementation.SwapInterval; } + set { implementation.SwapInterval = value; } + } + /// /// Updates the graphics context. This must be called when the render target /// is resized for proper behavior on Mac OS X. diff --git a/Source/OpenTK/Graphics/GraphicsContextBase.cs b/Source/OpenTK/Graphics/GraphicsContextBase.cs index 4e3fb939..d2335a17 100644 --- a/Source/OpenTK/Graphics/GraphicsContextBase.cs +++ b/Source/OpenTK/Graphics/GraphicsContextBase.cs @@ -57,8 +57,20 @@ namespace OpenTK.Graphics get { return disposed; } protected set { disposed = value; } } - - public abstract bool VSync { get; set; } + + public bool VSync + { + get { return SwapInterval > 0; } + set + { + if (value && SwapInterval <= 0) + SwapInterval = 1; + else if (!value && SwapInterval > 0) + SwapInterval = 0; + } + } + + public abstract int SwapInterval { get; set; } public virtual void Update(IWindowInfo window) { } diff --git a/Source/OpenTK/Graphics/IGraphicsContext.cs b/Source/OpenTK/Graphics/IGraphicsContext.cs index f21750d8..9b641d33 100644 --- a/Source/OpenTK/Graphics/IGraphicsContext.cs +++ b/Source/OpenTK/Graphics/IGraphicsContext.cs @@ -42,10 +42,27 @@ namespace OpenTK.Graphics bool IsDisposed { get; } /// - /// Gets or sets a value indicating whether VSyncing is enabled. + /// Gets or sets a value indicating whether VSync is enabled. When VSync is + /// enabled, calls will be synced to the refresh + /// rate of the that contains improving visual + /// quality and reducing CPU usage. However, systems that cannot maintain + /// the requested rendering rate will suffer from large jumps in performance. + /// This can be counteracted by increasing the + /// value. /// + [Obsolete("Use SwapInterval property instead.")] bool VSync { get; set; } + /// + /// Gets or sets a positive integer in the range [1, n), indicating the number of + /// refreshes between consecutive + /// calls. The maximum value for n is + /// implementation-dependent. The default value is 1. + /// This value will only affect instances where is enabled. + /// Invalid values will be clamped to the valid range. + /// + int SwapInterval { get; set; } + /// /// Updates the graphics context. This must be called when the region the graphics context /// is drawn to is resized. diff --git a/Source/OpenTK/Platform/Dummy/DummyGLContext.cs b/Source/OpenTK/Platform/Dummy/DummyGLContext.cs index 101572eb..4280d400 100644 --- a/Source/OpenTK/Platform/Dummy/DummyGLContext.cs +++ b/Source/OpenTK/Platform/Dummy/DummyGLContext.cs @@ -24,6 +24,7 @@ namespace OpenTK.Platform.Dummy { // This mode is not real. To receive a real mode we'd have to create a temporary context, which is not desirable! bool vsync; + int swap_interval; static int handle_count; Thread current_thread; @@ -82,7 +83,17 @@ namespace OpenTK.Platform.Dummy public override IntPtr GetAddress(string function) { return IntPtr.Zero; } - public override bool VSync { get { return vsync; } set { vsync = value; } } + public override int SwapInterval + { + get + { + return swap_interval; + } + set + { + swap_interval = value; + } + } public override void Update(IWindowInfo window) { } diff --git a/Source/OpenTK/Platform/Egl/EglContext.cs b/Source/OpenTK/Platform/Egl/EglContext.cs index 208bd208..7d93d1b5 100644 --- a/Source/OpenTK/Platform/Egl/EglContext.cs +++ b/Source/OpenTK/Platform/Egl/EglContext.cs @@ -39,7 +39,7 @@ namespace OpenTK.Platform.Egl EglWindowInfo WindowInfo; IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } } - bool vsync = true; // Default vsync value is defined as 1 (true) in EGL. + int swap_interval = 1; // Default interval is defined as 1 in EGL. #endregion @@ -117,18 +117,18 @@ namespace OpenTK.Platform.Egl get { return Egl.GetCurrentContext() == HandleAsEGLContext; } } - public override bool VSync + public override int SwapInterval { get { // Egl.GetSwapInterval does not exist, so store and return the current interval. // The default interval is defined as 1 (true). - return vsync; + return swap_interval; } set { - if (Egl.SwapInterval(WindowInfo.Display, value ? 1 : 0)) - vsync = value; + if (Egl.SwapInterval(WindowInfo.Display, value)) + swap_interval = value; else Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", WindowInfo.Display, value); } diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index 4d2ca42e..cb6548a3 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -44,7 +44,6 @@ namespace OpenTK.Platform.MacOS class AglContext : DesktopGraphicsContext { - bool mVSync = false; // Todo: keep track of which display adapter was specified when the context was created. // IntPtr displayID; @@ -427,16 +426,24 @@ namespace OpenTK.Platform.MacOS get { return (Handle.Handle == Agl.aglGetCurrentContext()); } } - public override bool VSync + public override int SwapInterval { - get { return mVSync; } + get { + int swap_interval = 0; + if (Agl.aglGetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, out swap_interval)) + { + return swap_interval; + } + else + { + MyAGLReportError("aglGetInteger"); + return 0; + } + } set { - int intVal = value ? 1 : 0; - - Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal); - - mVSync = value; + if (!Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref value)) + MyAGLReportError("aglSetInteger"); } } diff --git a/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs b/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs index 03f4cb4a..11197a7f 100644 --- a/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs +++ b/Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs @@ -425,15 +425,20 @@ namespace OpenTK.Platform.MacOS /* ** Per context options */ - [DllImport(agl)] internal static extern byte aglEnable(AGLContext ctx, ParameterNames pname); - [DllImport(agl)] internal static extern byte aglDisable(AGLContext ctx, ParameterNames pname); - [DllImport(agl)] static extern byte aglIsEnabled(AGLContext ctx, GLenum pname); [DllImport(agl)] - internal static extern byte aglSetInteger(AGLContext ctx, ParameterNames pname, ref int @params); + internal static extern bool aglEnable(AGLContext ctx, ParameterNames pname); [DllImport(agl)] - internal static extern byte aglSetInteger(AGLContext ctx, ParameterNames pname, int []@params); + internal static extern bool aglDisable(AGLContext ctx, ParameterNames pname); [DllImport(agl)] - static extern byte aglGetInteger(AGLContext ctx, GLenum pname, int* @params); + static extern bool aglIsEnabled(AGLContext ctx, GLenum pname); + [DllImport(agl)] + internal static extern bool aglSetInteger(AGLContext ctx, ParameterNames pname, ref int param); + [DllImport(agl)] + internal static extern bool aglSetInteger(AGLContext ctx, ParameterNames pname, int[] @params); + //[DllImport(agl)] + //static extern bool aglGetInteger(AGLContext ctx, ParameterNames pname, int* @params); + [DllImport(agl)] + internal static extern bool aglGetInteger(AGLContext ctx, ParameterNames pname, out int param); /* ** Font function diff --git a/Source/OpenTK/Platform/Windows/WinGLContext.cs b/Source/OpenTK/Platform/Windows/WinGLContext.cs index 6dcf9d06..e947aae3 100644 --- a/Source/OpenTK/Platform/Windows/WinGLContext.cs +++ b/Source/OpenTK/Platform/Windows/WinGLContext.cs @@ -203,18 +203,18 @@ namespace OpenTK.Platform.Windows #endregion - #region public bool VSync + #region SwapInterval - /// - /// Gets or sets a System.Boolean indicating whether SwapBuffer calls are synced to the screen refresh rate. - /// - public override bool VSync + public override int SwapInterval { get { lock (LoadLock) { - return vsync_supported && Wgl.Ext.GetSwapInterval() != 0; + if (vsync_supported) + return Wgl.Ext.GetSwapInterval(); + else + return 0; } } set @@ -222,7 +222,7 @@ namespace OpenTK.Platform.Windows lock (LoadLock) { if (vsync_supported) - Wgl.Ext.SwapInterval(value ? 1 : 0); + Wgl.Ext.SwapInterval(value); } } } diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index f76aa505..4f0a6f51 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -30,7 +30,7 @@ namespace OpenTK.Platform.X11 IntPtr display; X11WindowInfo currentWindow; bool vsync_supported; - int vsync_interval; + int swap_interval = 1; // As defined in GLX_SGI_swap_control bool glx_loaded; #endregion @@ -348,13 +348,16 @@ namespace OpenTK.Platform.X11 #endregion - #region VSync + #region SwapInterval - public override bool VSync + public override int SwapInterval { get { - return vsync_supported && vsync_interval != 0; + if (vsync_supported) + return swap_interval; + else + return 0; } set { @@ -362,12 +365,12 @@ namespace OpenTK.Platform.X11 { ErrorCode error_code = 0; using (new XLock(Display)) - { - error_code = Glx.Sgi.SwapInterval(value ? 1 : 0); - } - if (error_code != X11.ErrorCode.NO_ERROR) + error_code = Glx.Sgi.SwapInterval(value); + + if (error_code == X11.ErrorCode.NO_ERROR) + swap_interval = value; + else Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code); - vsync_interval = value ? 1 : 0; } } }