RetroArch/diff.diff
2017-01-17 17:13:42 +01:00

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,