forked from libretro/RetroArch
-
Notifications
You must be signed in to change notification settings - Fork 2
/
diff.diff
166 lines (157 loc) · 5.7 KB
/
diff.diff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
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,