diff --git a/src/wgl_context.c b/src/wgl_context.c index 3f0260f0..a87c50b2 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -533,6 +533,13 @@ void _glfwPlatformSwapInterval(int interval) { _GLFWwindow* window = _glfwCurrentWindow; + if (_glfwIsCompositionEnabled()) + { + // Don't enabled vsync when desktop compositing is enabled, as it leads + // to frame jitter + return; + } + if (window->wgl.EXT_swap_control) window->wgl.SwapIntervalEXT(interval); } diff --git a/src/win32_init.c b/src/win32_init.c index 4377bdfb..e2725a1d 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -86,6 +86,13 @@ static GLboolean initLibraries(void) GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware"); } + _glfw.win32.dwmapi.instance = LoadLibrary(L"dwmapi.dll"); + if (_glfw.win32.dwmapi.instance) + { + _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) + GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); + } + return GL_TRUE; } @@ -107,6 +114,21 @@ static void freeLibraries(void) ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// +// Returns whether desktop compositing is enabled +// +BOOL _glfwIsCompositionEnabled(void) +{ + BOOL enabled; + + if (!_glfw_DwmIsCompositionEnabled) + return FALSE; + + if (_glfw_DwmIsCompositionEnabled(&enabled) != S_OK) + return FALSE; + + return enabled; +} + // Returns a wide string version of the specified UTF-8 string // WCHAR* _glfwCreateWideStringFromUTF8(const char* source) diff --git a/src/win32_platform.h b/src/win32_platform.h index 23ef27ce..92ca2213 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -72,6 +72,9 @@ #ifndef WM_MOUSEHWHEEL #define WM_MOUSEHWHEEL 0x020E #endif +#ifndef WM_DWMCOMPOSITIONCHANGED + #define WM_DWMCOMPOSITIONCHANGED 0x031E +#endif //======================================================================== @@ -104,6 +107,10 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void); typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void); #define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware +// dwmapi.dll function pointer typedefs +typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*); +#define _glfw_DwmIsCompositionEnabled _glfw.win32.dwmapi.DwmIsCompositionEnabled + // We use versioned window class names in order not to cause conflicts // between applications using different versions of GLFW @@ -186,10 +193,16 @@ typedef struct _GLFWlibraryWin32 // user32.dll struct { - HINSTANCE instance; + HINSTANCE instance; SETPROCESSDPIAWARE_T SetProcessDPIAware; } user32; + // dwmapi.dll + struct { + HINSTANCE instance; + DWMISCOMPOSITIONENABLED_T DwmIsCompositionEnabled; + } dwmapi; + struct { char* name; } joystick[GLFW_JOYSTICK_LAST + 1]; @@ -212,6 +225,9 @@ typedef struct _GLFWmonitorWin32 // Prototypes for platform specific internal functions //======================================================================== +// Desktop compositing +BOOL _glfwIsCompositionEnabled(void); + // Wide strings WCHAR* _glfwCreateWideStringFromUTF8(const char* source); char* _glfwCreateUTF8FromWideString(const WCHAR* source); diff --git a/src/win32_window.c b/src/win32_window.c index 2d51b689..ad98bde2 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -606,6 +606,20 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, } break; } + + case WM_DWMCOMPOSITIONCHANGED: + { + if (_glfwIsCompositionEnabled()) + { + _GLFWwindow* previous = _glfwPlatformGetCurrentContext(); + _glfwPlatformMakeContextCurrent(window); + _glfwPlatformSwapInterval(0); + _glfwPlatformMakeContextCurrent(previous); + } + + // TODO: Restore vsync if compositing was disabled + break; + } } return DefWindowProc(hWnd, uMsg, wParam, lParam);