Skip to content

Commit

Permalink
Implemented IGraphicsContext.SwapInterval property that supersedes IG…
Browse files Browse the repository at this point in the history
…raphicsContext.VSync. Fixes issue [#2671]: "Expose SwapInterval to GameWindow".

git-svn-id: https://opentk.svn.sourceforge.net/svnroot/opentk/trunk@3081 ebc5dd9b-fb1d-0410-b6f8-d24c324e9604
  • Loading branch information
the_fiddler committed Sep 6, 2011
1 parent fb4f71f commit a63c056
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 44 deletions.
4 changes: 2 additions & 2 deletions Source/GLControl/GLControl.cs
Expand Up @@ -164,7 +164,7 @@ protected override void OnHandleCreated(EventArgs e)
// Deferred setting of vsync mode. See VSync property for more information. // Deferred setting of vsync mode. See VSync property for more information.
if (initial_vsync_value.HasValue) if (initial_vsync_value.HasValue)
{ {
Context.VSync = initial_vsync_value.Value; Context.SwapInterval = initial_vsync_value.Value ? 1 : 0;
initial_vsync_value = null; initial_vsync_value = null;
} }


Expand Down Expand Up @@ -331,7 +331,7 @@ public float AspectRatio
/// <summary> /// <summary>
/// Gets or sets a value indicating whether vsync is active for this GLControl. /// Gets or sets a value indicating whether vsync is active for this GLControl.
/// </summary> /// </summary>
[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 public bool VSync
{ {
get get
Expand Down
4 changes: 2 additions & 2 deletions Source/OpenTK/GameWindow.cs
Expand Up @@ -518,9 +518,9 @@ void RaiseRenderFrame(Stopwatch render_watch, ref double next_render, FrameEvent
{ {
// Check if we have enough time for a vsync // Check if we have enough time for a vsync
if (RenderTime > 2.0 * TargetRenderPeriod) if (RenderTime > 2.0 * TargetRenderPeriod)
Context.VSync = false; Context.SwapInterval = 0;
else else
Context.VSync = true; Context.SwapInterval = 1;
} }


render_period = render_args.Time = time; render_period = render_args.Time = time;
Expand Down
24 changes: 23 additions & 1 deletion Source/OpenTK/Graphics/GraphicsContext.cs
Expand Up @@ -461,14 +461,36 @@ public bool IsDisposed
} }


/// <summary> /// <summary>
/// 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, <see cref="SwapBuffers()"/> calls will be synced to the refresh
/// rate of the <see cref="DisplayDevice"/> 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 <see cref="SwapInterval"/>
/// value.
/// </summary> /// </summary>
[Obsolete("Use SwapInterval property instead.")]
public bool VSync public bool VSync
{ {
get { return implementation.VSync; } get { return implementation.VSync; }
set { implementation.VSync = value; } set { implementation.VSync = value; }
} }


/// <summary>
/// Gets or sets a positive integer in the range [1, n), indicating the number of
/// <see cref="DisplayDevice"/> refreshes between consecutive
/// <see cref="SwapBuffers()"/> calls. The maximum value for n is
/// implementation-dependent. The default value is 1.
/// This value will only affect instances where <see cref="VSync"/> is enabled.
/// Invalid values will be clamped to the valid range.
/// </summary>
public int SwapInterval
{
get { return implementation.SwapInterval; }
set { implementation.SwapInterval = value; }
}

/// <summary> /// <summary>
/// Updates the graphics context. This must be called when the render target /// Updates the graphics context. This must be called when the render target
/// is resized for proper behavior on Mac OS X. /// is resized for proper behavior on Mac OS X.
Expand Down
16 changes: 14 additions & 2 deletions Source/OpenTK/Graphics/GraphicsContextBase.cs
Expand Up @@ -57,8 +57,20 @@ public bool IsDisposed
get { return disposed; } get { return disposed; }
protected set { disposed = value; } 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) { } public virtual void Update(IWindowInfo window) { }


Expand Down
19 changes: 18 additions & 1 deletion Source/OpenTK/Graphics/IGraphicsContext.cs
Expand Up @@ -42,10 +42,27 @@ public interface IGraphicsContext : IDisposable
bool IsDisposed { get; } bool IsDisposed { get; }


/// <summary> /// <summary>
/// Gets or sets a value indicating whether VSyncing is enabled. /// Gets or sets a value indicating whether VSync is enabled. When VSync is
/// enabled, <see cref="SwapBuffers()"/> calls will be synced to the refresh
/// rate of the <see cref="DisplayDevice"/> 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 <see cref="SwapInterval"/>
/// value.
/// </summary> /// </summary>
[Obsolete("Use SwapInterval property instead.")]
bool VSync { get; set; } bool VSync { get; set; }


/// <summary>
/// Gets or sets a positive integer in the range [1, n), indicating the number of
/// <see cref="DisplayDevice"/> refreshes between consecutive
/// <see cref="SwapBuffers()"/> calls. The maximum value for n is
/// implementation-dependent. The default value is 1.
/// This value will only affect instances where <see cref="VSync"/> is enabled.
/// Invalid values will be clamped to the valid range.
/// </summary>
int SwapInterval { get; set; }

/// <summary> /// <summary>
/// Updates the graphics context. This must be called when the region the graphics context /// Updates the graphics context. This must be called when the region the graphics context
/// is drawn to is resized. /// is drawn to is resized.
Expand Down
13 changes: 12 additions & 1 deletion Source/OpenTK/Platform/Dummy/DummyGLContext.cs
Expand Up @@ -24,6 +24,7 @@ internal sealed class DummyGLContext : DesktopGraphicsContext
{ {
// This mode is not real. To receive a real mode we'd have to create a temporary context, which is not desirable! // This mode is not real. To receive a real mode we'd have to create a temporary context, which is not desirable!
bool vsync; bool vsync;
int swap_interval;
static int handle_count; static int handle_count;
Thread current_thread; Thread current_thread;


Expand Down Expand Up @@ -82,7 +83,17 @@ public override bool IsCurrent


public override IntPtr GetAddress(string function) { return IntPtr.Zero; } 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) public override void Update(IWindowInfo window)
{ } { }
Expand Down
10 changes: 5 additions & 5 deletions Source/OpenTK/Platform/Egl/EglContext.cs
Expand Up @@ -39,7 +39,7 @@ class EglContext : EmbeddedGraphicsContext


EglWindowInfo WindowInfo; EglWindowInfo WindowInfo;
IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } } 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 #endregion


Expand Down Expand Up @@ -117,18 +117,18 @@ public override bool IsCurrent
get { return Egl.GetCurrentContext() == HandleAsEGLContext; } get { return Egl.GetCurrentContext() == HandleAsEGLContext; }
} }


public override bool VSync public override int SwapInterval
{ {
get get
{ {
// Egl.GetSwapInterval does not exist, so store and return the current interval. // Egl.GetSwapInterval does not exist, so store and return the current interval.
// The default interval is defined as 1 (true). // The default interval is defined as 1 (true).
return vsync; return swap_interval;
} }
set set
{ {
if (Egl.SwapInterval(WindowInfo.Display, value ? 1 : 0)) if (Egl.SwapInterval(WindowInfo.Display, value))
vsync = value; swap_interval = value;
else else
Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", WindowInfo.Display, value); Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed.", WindowInfo.Display, value);
} }
Expand Down
23 changes: 15 additions & 8 deletions Source/OpenTK/Platform/MacOS/AglContext.cs
Expand Up @@ -44,7 +44,6 @@ namespace OpenTK.Platform.MacOS


class AglContext : DesktopGraphicsContext class AglContext : DesktopGraphicsContext
{ {
bool mVSync = false;
// Todo: keep track of which display adapter was specified when the context was created. // Todo: keep track of which display adapter was specified when the context was created.
// IntPtr displayID; // IntPtr displayID;


Expand Down Expand Up @@ -427,16 +426,24 @@ public override bool IsCurrent
get { return (Handle.Handle == Agl.aglGetCurrentContext()); } 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 set
{ {
int intVal = value ? 1 : 0; if (!Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref value))

MyAGLReportError("aglSetInteger");
Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal);

mVSync = value;
} }
} }


Expand Down
17 changes: 11 additions & 6 deletions Source/OpenTK/Platform/MacOS/CarbonBindings/Agl.cs
Expand Up @@ -425,15 +425,20 @@ internal static void aglSetFullScreen(AGLContext ctx, int width, int height, int
/* /*
** Per context options ** 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)] [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)] [DllImport(agl)]
internal static extern byte aglSetInteger(AGLContext ctx, ParameterNames pname, int []@params); internal static extern bool aglDisable(AGLContext ctx, ParameterNames pname);
[DllImport(agl)] [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 ** Font function
Expand Down
14 changes: 7 additions & 7 deletions Source/OpenTK/Platform/Windows/WinGLContext.cs
Expand Up @@ -203,26 +203,26 @@ public override bool IsCurrent


#endregion #endregion


#region public bool VSync #region SwapInterval


/// <summary> public override int SwapInterval
/// Gets or sets a System.Boolean indicating whether SwapBuffer calls are synced to the screen refresh rate.
/// </summary>
public override bool VSync
{ {
get get
{ {
lock (LoadLock) lock (LoadLock)
{ {
return vsync_supported && Wgl.Ext.GetSwapInterval() != 0; if (vsync_supported)
return Wgl.Ext.GetSwapInterval();
else
return 0;
} }
} }
set set
{ {
lock (LoadLock) lock (LoadLock)
{ {
if (vsync_supported) if (vsync_supported)
Wgl.Ext.SwapInterval(value ? 1 : 0); Wgl.Ext.SwapInterval(value);
} }
} }
} }
Expand Down
21 changes: 12 additions & 9 deletions Source/OpenTK/Platform/X11/X11GLContext.cs
Expand Up @@ -30,7 +30,7 @@ internal sealed class X11GLContext : DesktopGraphicsContext
IntPtr display; IntPtr display;
X11WindowInfo currentWindow; X11WindowInfo currentWindow;
bool vsync_supported; bool vsync_supported;
int vsync_interval; int swap_interval = 1; // As defined in GLX_SGI_swap_control
bool glx_loaded; bool glx_loaded;


#endregion #endregion
Expand Down Expand Up @@ -348,26 +348,29 @@ public override bool IsCurrent


#endregion #endregion


#region VSync #region SwapInterval


public override bool VSync public override int SwapInterval
{ {
get get
{ {
return vsync_supported && vsync_interval != 0; if (vsync_supported)
return swap_interval;
else
return 0;
} }
set set
{ {
if (vsync_supported) if (vsync_supported)
{ {
ErrorCode error_code = 0; ErrorCode error_code = 0;
using (new XLock(Display)) using (new XLock(Display))
{ error_code = Glx.Sgi.SwapInterval(value);
error_code = Glx.Sgi.SwapInterval(value ? 1 : 0);
} if (error_code == X11.ErrorCode.NO_ERROR)
if (error_code != X11.ErrorCode.NO_ERROR) swap_interval = value;
else
Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code); Debug.Print("VSync = {0} failed, error code: {1}.", value, error_code);
vsync_interval = value ? 1 : 0;
} }
} }
} }
Expand Down

0 comments on commit a63c056

Please sign in to comment.