Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 30 additions & 9 deletions src/windy/platforms/linux/x11.nim
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type
innerDecorated: bool
innerFocused: bool
mouseCaptured: bool
vsyncEnabled: bool

# XDnD state
xdndSource: XWindow
Expand Down Expand Up @@ -406,6 +407,34 @@ proc makeContextCurrent*(window: Window) =
proc swapBuffers*(window: Window) =
display.glXSwapBuffers(window.handle)

proc applyVsync(window: Window, enabled: bool) =
window.makeContextCurrent()
let interval = if enabled: 1.cint else: 0.cint
if glXSwapIntervalEXT != nil:
display.glXSwapIntervalEXT(window.handle, interval)
elif glXSwapIntervalMESA != nil:
if glXSwapIntervalMESA(interval) != 0:
raise WindyError.newException("Error setting the GLX swap interval")
elif glXSwapIntervalSGI != nil:
if not enabled:
raise WindyError.newException(
"Disabling VSync is not supported by GLX_SGI_swap_control"
)
if glXSwapIntervalSGI(interval) != 0:
raise WindyError.newException("Error setting the GLX swap interval")
else:
raise WindyError.newException("VSync control is not supported")
window.vsyncEnabled = enabled

proc vsync*(window: Window): bool =
## Returns true when vertical sync is enabled for this window.
window.vsyncEnabled

proc `vsync=`*(window: Window, enabled: bool) =
## Changes the GLX swap interval without recreating the window.
if window.vsyncEnabled != enabled:
window.applyVsync(enabled)

template blockUntil(expression: untyped) {.dirty.} =
## In X11 many properties are async, you change them and then it takes
## time for them to take effect. This is different from Win/Mac. This
Expand Down Expand Up @@ -819,15 +848,7 @@ proc newWindow*(

makeContextCurrent result

if vsync:
if glXSwapIntervalEXT != nil:
display.glXSwapIntervalEXT(result.handle, 1)
elif glXSwapIntervalMESA != nil:
glXSwapIntervalMESA(1)
elif glXSwapIntervalSGI != nil:
glXSwapIntervalSGI(1)
else:
raise WindyError.newException("VSync is not supported")
result.applyVsync(vsync)

if visible:
result.visible = true
Expand Down
4 changes: 2 additions & 2 deletions src/windy/platforms/linux/x11/glx.nim
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ proc glXSwapBuffers*(d: Display, drawable: Drawable) {.libglx.}

proc glXSwapIntervalEXT*(d: Display, drawable: Drawable,
interval: cint) {.libglx.}
proc glXSwapIntervalMESA*(interval: cint) {.libglx.}
proc glXSwapIntervalSGI*(interval: cint) {.libglx.}
proc glXSwapIntervalMESA*(interval: cint): cint {.libglx.}
proc glXSwapIntervalSGI*(interval: cint): cint {.libglx.}
19 changes: 19 additions & 0 deletions src/windy/platforms/macos/platform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type
minimizedState: bool
cpuImage: NSImage
activationSettlePolls: int
vsyncEnabled: bool

const
ActivationSettlePolls = 60
Expand Down Expand Up @@ -1090,6 +1091,23 @@ proc swapBuffers*(window: Window) =
else:
window.inner.contentView.NSOpenGLView.openGLContext.flushBuffer()

proc vsync*(window: Window): bool =
## Returns true when vertical sync is enabled for this window.
window.vsyncEnabled

proc `vsync=`*(window: Window, enabled: bool) =
## Changes the OpenGL swap interval without recreating the window.
if window.vsyncEnabled == enabled:
return
when not defined(useMetal4) and not defined(useCpu):
window.makeContextCurrent()
var swapInterval: GLint = if enabled: 1 else: 0
window.inner.contentView.NSOpenGLView.openGLContext.setValues(
swapInterval.addr,
NSOpenGLContextParameterSwapInterval
)
window.vsyncEnabled = enabled

proc presentPixels*(window: Window, image: Image) =
## Presents a CPU-rendered Pixie image into the macOS window content view.
when defined(useCpu):
Expand Down Expand Up @@ -1142,6 +1160,7 @@ proc newWindow*(
stencilBits = 8
): Window =
result = Window()
result.vsyncEnabled = vsync

init()

Expand Down
16 changes: 13 additions & 3 deletions src/windy/platforms/win32/platform.nim
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type
hdc: HDC
hglrc: HGLRC
cpuPresentBuffer: seq[uint8]
vsync*: bool
vsyncEnabled: bool
iconHandle: HICON
customCursor: HCURSOR

Expand Down Expand Up @@ -1339,7 +1339,7 @@ proc newWindow*(
result.title = title
result.hWnd = createWindow(windowClassName, title)
result.size = size
result.vsync = vsync
result.vsyncEnabled = vsync

discard SetPropW(result.hWnd, cast[ptr WCHAR](windowPropKey[0].addr), 1)

Expand All @@ -1366,7 +1366,17 @@ proc title*(window: Window): string =

proc vsync*(window: Window): bool =
## Returns true when vertical sync is enabled for this window.
window.vsync
window.vsyncEnabled

proc `vsync=`*(window: Window, enabled: bool) =
## Changes the OpenGL swap interval without recreating the window.
if window.vsyncEnabled == enabled:
return
when not defined(useDirectX) and not defined(useVulkan) and not defined(useCpu):
window.makeContextCurrent()
if wglSwapIntervalEXT(if enabled: 1 else: 0) == 0:
raise newException(WindyError, "Error setting swap interval")
window.vsyncEnabled = enabled

proc icon*(window: Window): Image =
window.state.icon
Expand Down
4 changes: 4 additions & 0 deletions tests/test.nim
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import windy

proc checkVsyncApi(window: Window) {.used.} =
window.vsync = false
discard window.vsync
Loading