use OpenGL swap interval on Windows and X11
This commit is contained in:
parent
f9aa6acb7a
commit
815fa2f255
@ -102,3 +102,12 @@ resize_dst(SWindowData *window_data, uint32_t width, uint32_t height) {
|
||||
window_data->dst_width = (uint32_t) (width * window_data->factor_width);
|
||||
window_data->dst_height = (uint32_t) (height * window_data->factor_height);
|
||||
}
|
||||
|
||||
#if !defined(USE_OPENGL_API)
|
||||
|
||||
//-------------------------------------
|
||||
void
|
||||
set_target_fps_aux() {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,7 @@ extern "C" {
|
||||
|
||||
void calc_dst_factor(SWindowData *window_data, uint32_t width, uint32_t height);
|
||||
void resize_dst(SWindowData *window_data, uint32_t width, uint32_t height);
|
||||
void set_target_fps_aux();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
double g_timer_frequency;
|
||||
double g_timer_resolution;
|
||||
double g_time_for_frame = 1.0 / 60.0;
|
||||
bool g_use_hardware_sync = false;
|
||||
|
||||
//-------------------------------------
|
||||
extern uint64_t mfb_timer_tick(void);
|
||||
@ -20,6 +21,7 @@ mfb_set_target_fps(uint32_t fps) {
|
||||
else {
|
||||
g_time_for_frame = 1.0 / fps;
|
||||
}
|
||||
set_target_fps_aux();
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
|
@ -1,6 +1,7 @@
|
||||
#if defined(USE_OPENGL_API)
|
||||
|
||||
#include "MiniFB_GL.h"
|
||||
#include "MiniFB_internal.h"
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
#include <windows/WindowData_Win.h>
|
||||
#include <gl/gl.h>
|
||||
@ -19,6 +20,10 @@
|
||||
#define UseCleanUp(x)
|
||||
#endif
|
||||
|
||||
extern double g_time_for_frame;
|
||||
extern bool g_use_hardware_sync;
|
||||
|
||||
|
||||
//-------------------------------------
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
bool
|
||||
@ -59,6 +64,44 @@ setup_pixel_format(HDC hDC) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
|
||||
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC)(void);
|
||||
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT = 0x0;
|
||||
PFNWGLGETSWAPINTERVALEXTPROC GetSwapIntervalEXT = 0x0;
|
||||
|
||||
#elif defined(linux)
|
||||
|
||||
bool
|
||||
setup_pixel_format(SWindowData_X11 *window_data_x11) {
|
||||
GLint glxAttribs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
GLX_STENCIL_SIZE, 8,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
GLX_STENCIL_SIZE, 8,
|
||||
GLX_SAMPLE_BUFFERS, 0,
|
||||
GLX_SAMPLES, 0,
|
||||
None
|
||||
};
|
||||
|
||||
XVisualInfo* visualInfo = glXChooseVisual(window_data_x11->display, window_data_x11->screen, glxAttribs);
|
||||
if (visualInfo == 0) {
|
||||
fprintf(stderr, "Could not create correct visual window.\n");
|
||||
XCloseDisplay(window_data_x11->display);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*,GLXDrawable,int);
|
||||
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT = 0x0;
|
||||
|
||||
#endif
|
||||
|
||||
//-------------------------------------
|
||||
@ -67,12 +110,17 @@ create_GL_context(SWindowData *window_data) {
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
SWindowData_Win *window_data_win = (SWindowData_Win *) window_data->specific;
|
||||
|
||||
if(setup_pixel_format(window_data_win->hdc) == false)
|
||||
if (setup_pixel_format(window_data_win->hdc) == false)
|
||||
return false;
|
||||
|
||||
window_data_win->hGLRC = wglCreateContext(window_data_win->hdc);
|
||||
wglMakeCurrent(window_data_win->hdc, window_data_win->hGLRC);
|
||||
init_GL(window_data);
|
||||
|
||||
SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT");
|
||||
GetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) wglGetProcAddress("wglGetSwapIntervalEXT");
|
||||
set_target_fps_aux();
|
||||
|
||||
return true;
|
||||
|
||||
#elif defined(linux)
|
||||
@ -89,26 +137,8 @@ create_GL_context(SWindowData *window_data) {
|
||||
//fprintf(stdout, "GLX version: %d.%d\n", majorGLX, minorGLX);
|
||||
}
|
||||
|
||||
GLint glxAttribs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
GLX_STENCIL_SIZE, 8,
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
GLX_STENCIL_SIZE, 8,
|
||||
GLX_SAMPLE_BUFFERS, 0,
|
||||
GLX_SAMPLES, 0,
|
||||
None
|
||||
};
|
||||
XVisualInfo* visualInfo = glXChooseVisual(window_data_x11->display, window_data_x11->screen, glxAttribs);
|
||||
if (visualInfo == 0) {
|
||||
fprintf(stderr, "Could not create correct visual window.\n");
|
||||
XCloseDisplay(window_data_x11->display);
|
||||
if (setup_pixel_format(window_data_x11) == false)
|
||||
return false;
|
||||
}
|
||||
|
||||
window_data_x11->context = glXCreateContext(window_data_x11->display, visualInfo, NULL, GL_TRUE);
|
||||
glXMakeCurrent(window_data_x11->display, window_data_x11->window, window_data_x11->context);
|
||||
@ -120,6 +150,9 @@ create_GL_context(SWindowData *window_data) {
|
||||
|
||||
init_GL(window_data);
|
||||
|
||||
SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) getProcAddressGLX("glXSwapIntervalEXT");
|
||||
set_target_fps_aux();
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
@ -202,7 +235,7 @@ init_GL(SWindowData *window_data) {
|
||||
//-------------------------------------
|
||||
void
|
||||
resize_GL(SWindowData *window_data) {
|
||||
if(window_data->is_initialized) {
|
||||
if (window_data->is_initialized) {
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
|
||||
SWindowData_Win *window_data_ex = (SWindowData_Win *) window_data->specific;
|
||||
@ -289,4 +322,47 @@ redraw_GL(SWindowData *window_data, const void *pixels) {
|
||||
#endif
|
||||
}
|
||||
|
||||
//-------------------------------------
|
||||
void
|
||||
set_target_fps_aux() {
|
||||
// Assuming the monitor refresh rate is 60 hz
|
||||
int interval = (int) ((60.0 * g_time_for_frame) + 0.5);
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
|
||||
if (SwapIntervalEXT != 0x0) {
|
||||
bool success = SwapIntervalEXT(interval);
|
||||
if (GetSwapIntervalEXT != 0x0) {
|
||||
int currentInterval = GetSwapIntervalEXT();
|
||||
if (interval != currentInterval) {
|
||||
fprintf(stderr, "Cannot set target swap interval. Current swap interval is %d\n", currentInterval);
|
||||
}
|
||||
}
|
||||
else if (success == false) {
|
||||
fprintf(stderr, "Cannot set target swap interval.\n");
|
||||
}
|
||||
g_use_hardware_sync = true;
|
||||
}
|
||||
|
||||
#elif defined(linux)
|
||||
#define kGLX_SWAP_INTERVAL_EXT 0x20F1
|
||||
#define kGLX_MAX_SWAP_INTERVAL_EXT 0x20F2
|
||||
|
||||
if (SwapIntervalEXT != 0x0) {
|
||||
Display *dpy = glXGetCurrentDisplay();
|
||||
GLXDrawable drawable = glXGetCurrentDrawable();
|
||||
unsigned int currentInterval, maxInterval;
|
||||
|
||||
SwapIntervalEXT(dpy, drawable, interval);
|
||||
glXQueryDrawable(dpy, drawable, kGLX_SWAP_INTERVAL_EXT, ¤tInterval);
|
||||
if (interval != currentInterval) {
|
||||
glXQueryDrawable(dpy, drawable, kGLX_MAX_SWAP_INTERVAL_EXT, &maxInterval);
|
||||
fprintf(stderr, "Cannot set target swap interval. Current swap interval is %d (max: %d)\n", currentInterval, maxInterval);
|
||||
}
|
||||
g_use_hardware_sync = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -192,7 +192,7 @@ WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
|
||||
if(mfb_EnableNonClientDpiScaling)
|
||||
mfb_EnableNonClientDpiScaling(hWnd);
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);;
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
// TODO
|
||||
@ -647,11 +647,10 @@ mfb_update_events(struct mfb_window *window) {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern double g_time_for_frame;
|
||||
extern bool g_use_hardware_sync;
|
||||
|
||||
bool
|
||||
mfb_wait_sync(struct mfb_window *window) {
|
||||
MSG msg;
|
||||
|
||||
if (window == 0x0) {
|
||||
return false;
|
||||
}
|
||||
@ -662,9 +661,14 @@ mfb_wait_sync(struct mfb_window *window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(g_use_hardware_sync) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
SWindowData_Win *window_data_win = (SWindowData_Win *) window_data->specific;
|
||||
double current;
|
||||
uint32_t millis = 1;
|
||||
double current;
|
||||
uint32_t millis = 1;
|
||||
while (1) {
|
||||
current = mfb_timer_now(window_data_win->timer);
|
||||
if (current >= g_time_for_frame * 0.96) {
|
||||
|
@ -433,6 +433,7 @@ mfb_update_events(struct mfb_window *window) {
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern double g_time_for_frame;
|
||||
extern bool g_use_hardware_sync;
|
||||
|
||||
bool
|
||||
mfb_wait_sync(struct mfb_window *window) {
|
||||
@ -446,6 +447,10 @@ mfb_wait_sync(struct mfb_window *window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(g_use_hardware_sync) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SWindowData_X11 *window_data_x11 = (SWindowData_X11 *) window_data->specific;
|
||||
XFlush(window_data_x11->display);
|
||||
XEvent event;
|
||||
|
Loading…
Reference in New Issue
Block a user