Skip to content

[BUG] VSync on Windows: discarded GetWindowLong() return causes double-sync (DwmFlush + wglSwapInterval) in fullscreen #44

@brunu97

Description

@brunu97

In platform/windows/Source/WindowsCore.cpp, two functions read the window style but never assign the result to lStyle:

PlatformSync() (~line 3091):

LONG lStyle = 0;
if ( g_hWnd ) GetWindowLong( g_hWnd, GWL_STYLE );   // return value discarded
BOOL DwmActive = FALSE;
if ( g_bDwmExists && !(lStyle & WS_POPUP) ) DwmIsCompositionEnabled( &DwmActive );

CompositionChanged() (~line 3072): same pattern.

Because lStyle stays 0, the test !(lStyle & WS_POPUP) is always true, so the WS_POPUP (fullscreen) check never excludes anything.

Impact

The intent is: use DwmFlush() for VSync in windowed mode, and the OpenGL swap interval (wglSwapIntervalEXT(1)) in fullscreen, never both.

With the bug, in fullscreen on Windows 10/11 (DWM always composited), PlatformSync() calls DwmFlush() on top of wglSwapIntervalEXT(1). Both wait for the same VBlank at slightly different offsets; when one misses the other's cycle it waits the next one, so SetVSync(1) drops to half the refresh rate or stutters between values (e.g. 60/72/90 fps on a 144 Hz monitor).

Tested with the OpenGL2 (Basic) renderer, fullscreen, Windows 11. Confirmed fixed by the patch below.

Fix

Assign the return value in both places:

// Before
if ( g_hWnd ) GetWindowLong( g_hWnd, GWL_STYLE );

// After
if ( g_hWnd ) lStyle = GetWindowLong( g_hWnd, GWL_STYLE );
Function Change
CompositionChanged() (~line 3073) GetWindowLong(...)lStyle = GetWindowLong(...)
PlatformSync() (~line 3092) GetWindowLong(...)lStyle = GetWindowLong(...)
PlatformInitGraphics() (~line 2586) move int oldMode = m_iErrorMode; outside the #ifndef DISABLE_VULKAN block (optional — only for the compile bug)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions