mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 16:39:43 +00:00
167 lines
5.7 KiB
Diff
167 lines
5.7 KiB
Diff
diff --git a/gfx/drivers_context/wgl_ctx.cpp b/gfx/drivers_context/wgl_ctx.cpp
|
|
index fc6132d..6c81bcb 100644
|
|
--- a/gfx/drivers_context/wgl_ctx.cpp
|
|
+++ b/gfx/drivers_context/wgl_ctx.cpp
|
|
@@ -81,6 +81,20 @@
|
|
#endif
|
|
|
|
#if defined(HAVE_OPENGL)
|
|
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC)(HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
|
|
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC)(HDC hdc, INT32 *numerator, INT32 *denominator);
|
|
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC)(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
|
|
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC)(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
|
|
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC)(HDC hdc, INT64 traget_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
|
|
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC hdc);
|
|
+
|
|
+static PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
|
|
+static PFNWGLGETSYNCVALUESOMLPROC wglGetSyncValuesOML;
|
|
+static PFNWGLGETMSCRATEOMLPROC wglGetMscRateOML;
|
|
+static PFNWGLSWAPBUFFERSMSCOMLPROC wglSwapBuffersMscOML;
|
|
+static PFNWGLWAITFORMSCOMLPROC wglWaitForMscOML;
|
|
+static PFNWGLWAITFORSBCOMLPROC wglWaitForSbcOML;
|
|
+
|
|
typedef HGLRC (APIENTRY *wglCreateContextAttribsProc)(HDC, HGLRC, const int*);
|
|
static wglCreateContextAttribsProc pcreate_context;
|
|
#endif
|
|
@@ -91,6 +105,13 @@ static HGLRC win32_hw_hrc;
|
|
static HDC win32_hdc;
|
|
static bool win32_use_hw_ctx = false;
|
|
static bool win32_core_hw_context_enable = false;
|
|
+static unsigned g_wgl_swap_mode = 0;
|
|
+
|
|
+static int g_wgl_divisor = 0;
|
|
+static int g_wgl_remainder = 0;
|
|
+static int64_t g_wgl_ust = 0;
|
|
+static int64_t g_wgl_msc = 0;
|
|
+static int64_t g_wgl_sbc = 0;
|
|
|
|
#ifdef HAVE_VULKAN
|
|
static gfx_ctx_vulkan_data_t win32_vk;
|
|
@@ -103,6 +124,44 @@ static enum gfx_ctx_api win32_api = GFX_CTX_NONE;
|
|
|
|
static dylib_t dll_handle = NULL; /* Handle to OpenGL32.dll */
|
|
|
|
+static unsigned strclen(const unsigned char *s, unsigned char c)
|
|
+{
|
|
+ unsigned i = 0;
|
|
+ while (s + i != NULL && s[i] != '\0' && s[i] != c)
|
|
+ i++;
|
|
+ return i;
|
|
+}
|
|
+
|
|
+static bool strsame(const unsigned char *a, const unsigned char *b, unsigned n)
|
|
+{
|
|
+ unsigned i = 0;
|
|
+ while (i < n && a + i != NULL && b + i != NULL && a[i] == b[i])
|
|
+ i++;
|
|
+ return i == n;
|
|
+}
|
|
+
|
|
+static bool wgl_has_extension(HDC hdc, const char *ext)
|
|
+{
|
|
+ char *end;
|
|
+ int len = strlen(ext);
|
|
+ char *p = (char*)wglGetExtensionsStringARB(hdc);
|
|
+
|
|
+ if (p == 0)
|
|
+ return false;
|
|
+
|
|
+ end = p + strlen(p);
|
|
+
|
|
+ while (p < end)
|
|
+ {
|
|
+ int n = strclen((const unsigned char*)p, ' ');
|
|
+ if (len == n && strsame((const unsigned char*)ext, (const unsigned char*)p, n))
|
|
+ return true;
|
|
+ p += n+1;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
static void setup_pixel_format(HDC hdc)
|
|
{
|
|
PIXELFORMATDESCRIPTOR pfd = {0};
|
|
@@ -282,9 +341,7 @@ static void gfx_ctx_wgl_swap_interval(void *data, unsigned interval)
|
|
case GFX_CTX_OPENGL_API:
|
|
#ifdef HAVE_OPENGL
|
|
win32_interval = interval;
|
|
- if (!win32_hrc)
|
|
- return;
|
|
- if (!p_swap_interval)
|
|
+ if (!win32_hrc || !p_swap_interval)
|
|
return;
|
|
|
|
RARCH_LOG("[WGL]: wglSwapInterval(%u)\n", win32_interval);
|
|
@@ -339,7 +396,19 @@ static void gfx_ctx_wgl_swap_buffers(void *data, video_frame_info_t video_info)
|
|
{
|
|
case GFX_CTX_OPENGL_API:
|
|
#ifdef HAVE_OPENGL
|
|
- SwapBuffers(win32_hdc);
|
|
+ if (g_wgl_swap_mode)
|
|
+ {
|
|
+ if (win32_interval)
|
|
+ {
|
|
+ wglWaitForMscOML(win32_hdc, g_wgl_msc + win32_interval,
|
|
+ 0, 0, &g_wgl_ust, &g_wgl_msc, &g_wgl_sbc);
|
|
+ wglSwapBuffersMscOML(win32_hdc, 0, 0, 0);
|
|
+ }
|
|
+ else
|
|
+ wglSwapBuffersMscOML(win32_hdc, 0, g_wgl_divisor, g_wgl_remainder);
|
|
+ }
|
|
+ else
|
|
+ SwapBuffers(win32_hdc);
|
|
#endif
|
|
break;
|
|
|
|
@@ -439,11 +508,35 @@ static void *gfx_ctx_wgl_init(video_frame_info_t video_info, void *video_driver)
|
|
win32_monitor_init();
|
|
|
|
wndclass.lpfnWndProc = WndProcGL;
|
|
+ g_wgl_swap_mode = 0;
|
|
if (!win32_window_init(&wndclass, true, NULL))
|
|
return NULL;
|
|
|
|
switch (win32_api)
|
|
{
|
|
+ case GFX_CTX_OPENGL_API:
|
|
+ RARCH_LOG("Testing if extension WGL_OML_sync_control is available...\n");
|
|
+ wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
|
+
|
|
+ if (wgl_has_extension(win32_hdc, "WGL_OML_sync_control"))
|
|
+ {
|
|
+ RARCH_LOG("WGL_OML_sync_control supported, using better swap control method...\n");
|
|
+
|
|
+ g_wgl_swap_mode = 1;
|
|
+ wglGetSyncValuesOML = (PFNWGLGETSYNCVALUESOMLPROC)
|
|
+ wglGetProcAddress("wglGetSyncValuesOML");
|
|
+ wglGetMscRateOML = (PFNWGLGETMSCRATEOMLPROC)
|
|
+ wglGetProcAddress("wglGetMscRateOML");
|
|
+ wglSwapBuffersMscOML = (PFNWGLSWAPBUFFERSMSCOMLPROC)
|
|
+ wglGetProcAddress("wglSwapBuffersMscOML");
|
|
+ wglWaitForMscOML = (PFNWGLWAITFORMSCOMLPROC)
|
|
+ wglGetProcAddress("wglWaitForMscOML");
|
|
+ wglWaitForSbcOML = (PFNWGLWAITFORSBCOMLPROC)
|
|
+ wglGetProcAddress("wglWaitForSbcOML");
|
|
+
|
|
+ wglGetSyncValuesOML(win32_hdc, &g_wgl_ust, &g_wgl_msc, &g_wgl_sbc);
|
|
+ }
|
|
+ break;
|
|
case GFX_CTX_VULKAN_API:
|
|
#ifdef HAVE_VULKAN
|
|
if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32))
|
|
@@ -522,6 +615,13 @@ static void gfx_ctx_wgl_destroy(void *data)
|
|
win32_major = 0;
|
|
win32_minor = 0;
|
|
p_swap_interval = NULL;
|
|
+
|
|
+ g_wgl_swap_mode = 0;
|
|
+ g_wgl_divisor = 0;
|
|
+ g_wgl_remainder = 0;
|
|
+ g_wgl_ust = 0;
|
|
+ g_wgl_msc = 0;
|
|
+ g_wgl_sbc = 0;
|
|
}
|
|
|
|
static bool gfx_ctx_wgl_set_video_mode(void *data,
|