Refactor all GL context handling code.

This commit is contained in:
Themaister 2012-09-25 01:26:22 +02:00
parent c1948b7c5d
commit d0e220bbf1
16 changed files with 547 additions and 314 deletions

View File

@ -129,27 +129,27 @@ ifeq ($(HAVE_COREAUDIO), 1)
LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit
endif
ifeq ($(SCALER_NO_SIMD), 1)
DEFINES += -DSCALER_NO_SIMD
endif
ifeq ($(SCALER_PERF), 1)
DEFINES += -DSCALER_PERF
endif
ifeq ($(HAVE_SDL), 1)
OBJ += gfx/sdl_gfx.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o
OBJ += gfx/scaler/scaler.o gfx/scaler/pixconv.o gfx/scaler/scaler_int.o gfx/scaler/filter.o
DEFINES += $(SDL_CFLAGS) $(BSD_LOCAL_INC)
LIBS += $(SDL_LIBS)
ifeq ($(SCALER_NO_SIMD), 1)
DEFINES += -DSCALER_NO_SIMD
endif
ifeq ($(SCALER_PERF), 1)
DEFINES += -DSCALER_PERF
endif
ifeq ($(HAVE_X11), 1)
LIBS += $(X11_LIBS)
DEFINES += $(X11_CFLAGS)
endif
ifeq ($(HAVE_OPENGL), 1)
OBJ += gfx/gl.o gfx/fonts/freetype.o gfx/math/matrix.o
OBJ += gfx/gl.o gfx/gfx_context.o gfx/fonts/freetype.o gfx/math/matrix.o
ifeq ($(OSX), 1)
LIBS += -framework OpenGL
@ -158,24 +158,29 @@ ifeq ($(HAVE_SDL), 1)
OBJ += gfx/context/drm_egl_ctx.o
DEFINES += $(GBM_CFLAGS) $(DRM_CFLAGS) $(EGL_CFLAGS)
LIBS += $(GBM_LIBS) $(DRM_LIBS) $(EGL_LIBS)
else ifeq ($(HAVE_VIDEOCORE), 1)
endif
ifeq ($(HAVE_VIDEOCORE), 1)
OBJ += gfx/context/vc_egl_ctx.o
# videocore's libs set later
else ifeq ($(HAVE_GLES), 1)
endif
ifeq ($(HAVE_X11), 1)
ifeq ($(HAVE_EGL), 1)
OBJ += gfx/context/xegl_ctx.o
DEFINES += $(EGL_CFLAGS)
LIBS += $(EGL_LIBS)
else
LIBS += -lGL
OBJ += gfx/context/sdl_ctx.o
endif
endif
endif
ifeq ($(HAVE_GLES), 1)
LIBS += -lGLESv2
DEFINES += -DHAVE_OPENGLES -DHAVE_OPENGLES2
else
LIBS += -lGL
endif
OBJ += gfx/context/sdl_ctx.o
ifeq ($(HAVE_GLES), 1)
LIBS += -lGLESv2
DEFINES += -DHAVE_OPENGLES -DHAVE_OPENGLES2
else
LIBS += -lGL
endif
endif

View File

@ -61,7 +61,7 @@ ifeq ($(TDM_GCC),)
endif
ifeq ($(HAVE_SDL), 1)
OBJ += gfx/sdl_gfx.o gfx/gl.o gfx/math/matrix.o gfx/fonts/freetype.o gfx/context/sdl_ctx.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o
OBJ += gfx/sdl_gfx.o gfx/gl.o gfx/math/matrix.o gfx/fonts/freetype.o gfx/context/sdl_ctx.o gfx/gfx_context.o input/sdl_input.o audio/sdl_audio.o fifo_buffer.o
OBJ += gfx/scaler/scaler.o gfx/scaler/pixconv.o gfx/scaler/scaler_int.o gfx/scaler/filter.o
LIBS += -lSDL
DEFINES += -ISDL -DHAVE_SDL

View File

@ -54,6 +54,7 @@ static EGLConfig g_config;
static volatile sig_atomic_t g_quit;
static bool g_inited;
static unsigned g_interval;
static enum gfx_ctx_api g_api;
static struct gbm_device *g_gbm_dev;
static struct gbm_surface *g_gbm_surface;
@ -81,6 +82,7 @@ struct drm_fb
};
static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo);
static void gfx_ctx_destroy(void);
static void sighandler(int sig)
{
@ -88,12 +90,12 @@ static void sighandler(int sig)
g_quit = 1;
}
void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
static void gfx_ctx_swap_interval(unsigned interval)
{
g_interval = interval;
}
void gfx_ctx_check_window(bool *quit,
static void gfx_ctx_check_window(bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{
(void)frame_count;
@ -204,7 +206,7 @@ static void queue_flip(void)
waiting_for_flip = true;
}
void gfx_ctx_swap_buffers(void)
static void gfx_ctx_swap_buffers(void)
{
eglSwapBuffers(g_egl_dpy, g_egl_surf);
@ -226,65 +228,28 @@ void gfx_ctx_swap_buffers(void)
}
}
void gfx_ctx_set_resize(unsigned width, unsigned height)
static void gfx_ctx_set_resize(unsigned width, unsigned height)
{
(void)width;
(void)height;
}
void gfx_ctx_update_window_title(bool reset)
static void gfx_ctx_update_window_title(bool reset)
{
(void)reset;
}
void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
{
*width = g_fb_width;
*height = g_fb_height;
}
#if 0
static void reschedule_process(void)
{
struct sched_param param = {0};
// All-out real-time. Why not? :D
param.sched_priority = sched_get_priority_max(SCHED_FIFO);
if (sched_setscheduler(0, SCHED_FIFO, &param) < 0)
RARCH_ERR("[KMS/EGL]: Failed to set SCHED_FIFO priority.\n");
int sched = sched_getscheduler(getpid());
const char *scheduler;
switch (sched)
{
case SCHED_OTHER:
scheduler = "SCHED_OTHER";
break;
case SCHED_FIFO:
scheduler = "SCHED_FIFO";
break;
default:
scheduler = "Unrelated";
}
RARCH_LOG("[KMS/EGL]: Current scheduler: %s\n", scheduler);
if (sched == SCHED_FIFO)
RARCH_LOG("[KMS/EGL]: SCHED_FIFO prio: %d\n", param.sched_priority);
}
#endif
bool gfx_ctx_init(void)
static bool gfx_ctx_init(void)
{
if (g_inited)
return false;
#if 0
reschedule_process();
#endif
static const char *modules[] = {
"i915", "radeon", "nouveau", "vmwgfx", "omapdrm", "exynos", NULL
};
@ -367,8 +332,8 @@ bool gfx_ctx_init(void)
goto error;
}
g_crtc_id = g_encoder->crtc_id;
g_connector_id = g_connector->connector_id;
g_crtc_id = g_encoder->crtc_id;
g_connector_id = g_connector->connector_id;
g_fb_width = g_drm_mode->hdisplay;
g_fb_height = g_drm_mode->vdisplay;
@ -385,6 +350,64 @@ bool gfx_ctx_init(void)
goto error;
}
return true;
error:
gfx_ctx_destroy();
return false;
}
static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
{
struct drm_fb *fb = (struct drm_fb*)data;
if (fb->fb_id)
drmModeRmFB(g_drm_fd, fb->fb_id);
free(fb);
}
static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo)
{
struct drm_fb *fb = (struct drm_fb*)gbm_bo_get_user_data(bo);
if (fb)
return fb;
fb = (struct drm_fb*)calloc(1, sizeof(*fb));
fb->bo = bo;
unsigned width = gbm_bo_get_width(bo);
unsigned height = gbm_bo_get_height(bo);
unsigned stride = gbm_bo_get_stride(bo);
unsigned handle = gbm_bo_get_handle(bo).u32;
int ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id);
if (ret < 0)
{
RARCH_ERR("[KMS/EGL]: Failed to create FB: %s\n", strerror(errno));
free(fb);
return NULL;
}
gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
return fb;
}
static bool gfx_ctx_set_video_mode(
unsigned width, unsigned height,
unsigned bits, bool fullscreen)
{
(void)bits;
if (g_inited)
return false;
struct sigaction sa = {{0}};
sa.sa_handler = sighandler;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
static const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
@ -430,64 +453,6 @@ bool gfx_ctx_init(void)
if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
goto error;
return true;
error:
gfx_ctx_destroy();
return false;
}
static void drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
{
struct drm_fb *fb = (struct drm_fb*)data;
if (fb->fb_id)
drmModeRmFB(g_drm_fd, fb->fb_id);
free(fb);
}
static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo)
{
struct drm_fb *fb = (struct drm_fb*)gbm_bo_get_user_data(bo);
if (fb)
return fb;
fb = (struct drm_fb*)calloc(1, sizeof(*fb));
fb->bo = bo;
unsigned width = gbm_bo_get_width(bo);
unsigned height = gbm_bo_get_height(bo);
unsigned stride = gbm_bo_get_stride(bo);
unsigned handle = gbm_bo_get_handle(bo).u32;
int ret = drmModeAddFB(g_drm_fd, width, height, 24, 32, stride, handle, &fb->fb_id);
if (ret < 0)
{
RARCH_ERR("[KMS/EGL]: Failed to create FB: %s\n", strerror(errno));
free(fb);
return NULL;
}
gbm_bo_set_user_data(bo, fb, drm_fb_destroy_callback);
return fb;
}
bool gfx_ctx_set_video_mode(
unsigned width, unsigned height,
unsigned bits, bool fullscreen)
{
(void)bits;
if (g_inited)
return false;
struct sigaction sa = {{0}};
sa.sa_handler = sighandler;
sa.sa_flags = SA_RESTART;
sigemptyset(&sa.sa_mask);
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(g_egl_dpy, g_egl_surf);
@ -596,20 +561,53 @@ void gfx_ctx_destroy(void)
g_inited = false;
}
void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
{
void *linuxinput = input_linuxraw.init();
*input = linuxinput ? &input_linuxraw : NULL;
*input_data = linuxinput;
}
bool gfx_ctx_window_has_focus(void)
static bool gfx_ctx_has_focus(void)
{
return g_inited;
}
gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
{
return eglGetProcAddress(symbol);
}
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{
g_api = api;
switch (api)
{
case GFX_CTX_OPENGL_API:
return eglBindAPI(EGL_OPENGL_API);
case GFX_CTX_OPENGL_ES_API:
return eglBindAPI(EGL_OPENGL_ES_API);
case GFX_CTX_OPENVG_API:
return eglBindAPI(EGL_OPENVG_API);
default:
return false;
}
}
const gfx_ctx_driver_t gfx_ctx_drm_egl = {
gfx_ctx_init,
gfx_ctx_destroy,
gfx_ctx_bind_api,
gfx_ctx_swap_interval,
gfx_ctx_set_video_mode,
gfx_ctx_get_video_size,
gfx_ctx_update_window_title,
gfx_ctx_check_window,
gfx_ctx_set_resize,
gfx_ctx_has_focus,
gfx_ctx_swap_buffers,
gfx_ctx_input_driver,
gfx_ctx_get_proc_address,
"drm-egl",
};

View File

@ -139,10 +139,8 @@ void gfx_ctx_get_available_resolutions (void)
g_console.check_available_resolutions = true;
}
void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
void gfx_ctx_set_swap_interval(unsigned interval)
{
(void)inited;
#if defined(HAVE_PSGL)
if (gl_context)
{
@ -172,12 +170,10 @@ void gfx_ctx_check_window(bool *quit,
*resize = true;
}
#ifndef HAVE_GRIFFIN
bool gfx_ctx_window_has_focus(void)
bool gfx_ctx_has_focus(void)
{
return true;
}
#endif
void gfx_ctx_swap_buffers(void)
{
@ -413,3 +409,40 @@ void gfx_ctx_set_overscan(void)
gl->should_resize = true;
}
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{
return api == GFX_CTX_OPENGL_API || GFX_CTX_OPENGL_ES_API;
}
const gfx_ctx_driver_t gfx_ctx_ps3 = {
gfx_ctx_init,
gfx_ctx_destroy,
gfx_ctx_bind_api,
gfx_ctx_set_swap_interval,
gfx_ctx_set_video_mode,
gfx_ctx_get_video_size,
gfx_ctx_update_window_title,
gfx_ctx_check_window,
gfx_ctx_set_resize,
gfx_ctx_has_focus,
gfx_ctx_swap_buffers,
gfx_ctx_input_driver,
gfx_ctx_get_proc_address,
"ps3",
// RARCH_CONSOLE stuff.
gfx_set_filtering,
gfx_get_available_resolutions,
gfx_check_resolutions,
#ifdef HAVE_CG_MENU
gfx_menu_init,
#else
NULL,
#endif
gfx_set_fbo,
gfx_apply_fbo_state_changes,
};

View File

@ -41,13 +41,16 @@
static bool g_fullscreen;
static unsigned g_interval;
static bool g_inited;
void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol);
static void gfx_ctx_swap_interval(unsigned interval)
{
g_interval = interval;
bool success = true;
if (inited)
if (g_inited)
{
#if defined(_WIN32)
static BOOL (APIENTRY *wgl_swap_interval)(int) = NULL;
@ -81,7 +84,7 @@ static void gfx_ctx_wm_set_caption(const char *str)
SDL_WM_SetCaption(str, NULL);
}
void gfx_ctx_update_window_title(bool reset)
static void gfx_ctx_update_window_title(bool reset)
{
if (reset)
gfx_window_title_reset();
@ -91,15 +94,15 @@ void gfx_ctx_update_window_title(bool reset)
gfx_ctx_wm_set_caption(buf);
}
void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
{
const SDL_VideoInfo *video_info = SDL_GetVideoInfo();
rarch_assert(video_info);
*width = video_info->current_w;
*width = video_info->current_w;
*height = video_info->current_h;
}
bool gfx_ctx_init(void)
static bool gfx_ctx_init(void)
{
if (SDL_WasInit(SDL_INIT_VIDEO))
return true;
@ -111,12 +114,13 @@ bool gfx_ctx_init(void)
return ret;
}
void gfx_ctx_destroy(void)
static void gfx_ctx_destroy(void)
{
SDL_QuitSubSystem(SDL_INIT_VIDEO);
g_inited = false;
}
bool gfx_ctx_set_video_mode(
static bool gfx_ctx_set_video_mode(
unsigned width, unsigned height,
unsigned bits, bool fullscreen)
{
@ -136,12 +140,14 @@ bool gfx_ctx_set_video_mode(
return false;
}
g_inited = true;
int attr = 0;
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &attr);
if (attr <= 0 && g_interval)
{
RARCH_WARN("SDL failed to setup VSync, attempting to recover using native calls.\n");
gfx_ctx_set_swap_interval(g_interval, true);
gfx_ctx_swap_interval(g_interval);
}
g_fullscreen = fullscreen;
@ -158,8 +164,9 @@ bool gfx_ctx_set_video_mode(
#if defined(HAVE_X11) && !defined(__APPLE__)
RARCH_LOG("Suspending screensaver (X11).\n");
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (gfx_ctx_get_wm_info(&info))
if (SDL_GetWMInfo(&info) == 1)
gfx_suspend_screensaver(info.info.x11.window);
else
RARCH_ERR("Failed to get SDL WM info, cannot suspend screensaver.\n");
@ -169,8 +176,7 @@ bool gfx_ctx_set_video_mode(
}
// SDL 1.2 has an awkward model where you need to "confirm" window resizing.
// SDL 1.3 luckily removes this quirk.
void gfx_ctx_set_resize(unsigned width, unsigned height)
static void gfx_ctx_set_resize(unsigned width, unsigned height)
{
#ifndef __APPLE__ // Resizing on OSX is broken in 1.2 it seems :)
static const int resizable = SDL_RESIZABLE;
@ -180,14 +186,13 @@ void gfx_ctx_set_resize(unsigned width, unsigned height)
SDL_SetVideoMode(width, height, 0, SDL_OPENGL | (g_fullscreen ? SDL_FULLSCREEN : resizable));
}
void gfx_ctx_swap_buffers(void)
static void gfx_ctx_swap_buffers(void)
{
SDL_GL_SwapBuffers();
}
// 1.2 specific workaround for tiling WMs. In 1.3 we call GetSize directly, so we don't need to rely on
// proper event handling (I hope).
#if !defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_X11)
// 1.2 specific workaround for tiling WMs.
#if defined(HAVE_X11) && !defined(__APPLE__)
// This X11 is set on OSX for some reason.
static bool gfx_ctx_get_window_size(unsigned *width, unsigned *height)
{
@ -210,9 +215,12 @@ static bool gfx_ctx_get_window_size(unsigned *width, unsigned *height)
}
#endif
static void check_window(bool *quit,
static void gfx_ctx_check_window(bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{
*quit = false;
*resize = false;
SDL_Event event;
while (SDL_PollEvent(&event))
{
@ -230,7 +238,7 @@ static void check_window(bool *quit,
}
}
#if defined(SDL_VIDEO_DRIVER_X11) && !defined(__APPLE__)
#if defined(HAVE_X11) && !defined(__APPLE__)
if (!*resize && !g_fullscreen)
{
unsigned new_width, new_height;
@ -252,34 +260,12 @@ static void check_window(bool *quit,
#endif
}
void gfx_ctx_check_window(bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{
*quit = false;
*resize = false;
check_window(quit, resize, width, height, frame_count);
}
#ifndef __APPLE__
bool gfx_ctx_get_wm_info(SDL_SysWMinfo *info)
{
#ifdef XENON
(void)info;
return false;
#else
SDL_VERSION(&info->version);
return SDL_GetWMInfo(info) == 1;
#endif
}
#endif
bool gfx_ctx_window_has_focus(void)
static bool gfx_ctx_has_focus(void)
{
return (SDL_GetAppState() & (SDL_APPINPUTFOCUS | SDL_APPACTIVE)) == (SDL_APPINPUTFOCUS | SDL_APPACTIVE);
}
void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
{
void *sdl_input = input_sdl.init();
if (sdl_input)
@ -291,12 +277,13 @@ void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
*input = NULL;
}
#ifdef HAVE_OPENGL
// Enforce void (*)(void) as it's not really legal to cast void* to fn-pointer.
// POSIX allows this, but strict C99 doesn't.
gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
{
// This will not fail on any system RetroArch would run on, but let's just be defensive.
rarch_assert(sizeof(void*) == sizeof(void (*)(void)));
gfx_ctx_proc_t ret;
void *sym__ = SDL_GL_GetProcAddress(symbol);
@ -304,5 +291,26 @@ gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
return ret;
}
#endif
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{
return api == GFX_CTX_OPENGL_API;
}
const gfx_ctx_driver_t gfx_ctx_sdl_gl = {
gfx_ctx_init,
gfx_ctx_destroy,
gfx_ctx_bind_api,
gfx_ctx_swap_interval,
gfx_ctx_set_video_mode,
gfx_ctx_get_video_size,
gfx_ctx_update_window_title,
gfx_ctx_check_window,
gfx_ctx_set_resize,
gfx_ctx_has_focus,
gfx_ctx_swap_buffers,
gfx_ctx_input_driver,
gfx_ctx_get_proc_address,
"sdl-gl",
};

View File

@ -43,6 +43,7 @@ static EGLConfig g_config;
static volatile sig_atomic_t g_quit;
static bool g_inited;
static gfx_ctx_api g_api;
static unsigned g_fb_width; // Just use something for now.
static unsigned g_fb_height;
@ -59,12 +60,12 @@ static void sighandler(int sig)
g_quit = 1;
}
void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
static void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
{
eglSwapInterval(g_egl_dpy, interval);
}
void gfx_ctx_check_window(bool *quit,
static void gfx_ctx_check_window(bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{
(void)frame_count;
@ -75,29 +76,29 @@ void gfx_ctx_check_window(bool *quit,
*quit = g_quit;
}
void gfx_ctx_swap_buffers(void)
static void gfx_ctx_swap_buffers(void)
{
eglSwapBuffers(g_egl_dpy, g_egl_surf);
}
void gfx_ctx_set_resize(unsigned width, unsigned height)
static void gfx_ctx_set_resize(unsigned width, unsigned height)
{
(void)width;
(void)height;
}
void gfx_ctx_update_window_title(bool reset)
static void gfx_ctx_update_window_title(bool reset)
{
(void)reset;
}
void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
{
*width = g_fb_width;
*height = g_fb_height;
}
bool gfx_ctx_init(void)
static bool gfx_ctx_init(void)
{
if (g_inited)
{
@ -189,7 +190,7 @@ bool gfx_ctx_init(void)
return true;
}
bool gfx_ctx_set_video_mode(
static bool gfx_ctx_set_video_mode(
unsigned width, unsigned height,
unsigned bits, bool fullscreen)
{
@ -208,7 +209,7 @@ bool gfx_ctx_set_video_mode(
return true;
}
void gfx_ctx_destroy(void)
static void gfx_ctx_destroy(void)
{
if (g_egl_dpy)
{
@ -227,39 +228,56 @@ void gfx_ctx_destroy(void)
g_egl_surf = NULL;
g_egl_dpy = NULL;
g_config = 0;
g_inited = false;
g_inited = false;
}
void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
{
void *linuxinput = input_linuxraw.init();
*input = linuxinput ? &input_linuxraw : NULL;
*input_data = linuxinput;
}
void gfx_ctx_set_projection(gl_t *gl, const struct gl_ortho *ortho, bool allow_rotate)
{
// Calculate projection.
math_matrix proj;
matrix_ortho(&proj, ortho->left, ortho->right,
ortho->bottom, ortho->top, ortho->znear, ortho->zfar);
if (allow_rotate)
{
math_matrix rot;
matrix_rotate_z(&rot, M_PI * gl->rotation / 180.0f);
matrix_multiply(&proj, &rot, &proj);
}
gl->mvp = proj;
}
bool gfx_ctx_window_has_focus(void)
static bool gfx_ctx_window_has_focus(void)
{
return g_inited;
}
gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
{
return eglGetProcAddress(symbol);
}
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{
g_api = api;
switch (api)
{
case GFX_CTX_OPENGL_API:
return eglBindAPI(EGL_OPENGL_API);
case GFX_CTX_OPENGL_ES_API:
return eglBindAPI(EGL_OPENGL_ES_API);
case GFX_CTX_OPENVG_API:
return eglBindAPI(EGL_OPENVG_API);
default:
return false;
}
}
const gfx_ctx_driver_t gfx_ctx_videocore = {
gfx_ctx_init,
gfx_ctx_destroy,
gfx_ctx_bind_api,
gfx_ctx_swap_interval,
gfx_ctx_set_video_mode,
gfx_ctx_get_video_size,
gfx_ctx_update_window_title,
gfx_ctx_check_window,
gfx_ctx_set_resize,
gfx_ctx_has_focus,
gfx_ctx_swap_buffers,
gfx_ctx_input_driver,
gfx_ctx_get_proc_address,
"videocore",
};

View File

@ -44,6 +44,7 @@ static EGLConfig g_config;
static volatile sig_atomic_t g_quit;
static bool g_inited;
static unsigned g_interval;
static enum gfx_ctx_api g_api;
static void sighandler(int sig)
{
@ -51,6 +52,9 @@ static void sighandler(int sig)
g_quit = 1;
}
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height);
static void gfx_ctx_destroy(void);
static void hide_mouse(void)
{
Cursor no_ptr;
@ -110,10 +114,10 @@ static void set_windowed_fullscreen(void)
&xev);
}
void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
static void gfx_ctx_swap_interval(unsigned interval)
{
g_interval = interval;
if (inited)
if (g_egl_dpy)
{
RARCH_LOG("[X/EGL]: eglSwapInterval(%u)\n", g_interval);
if (!eglSwapInterval(g_egl_dpy, g_interval))
@ -121,7 +125,7 @@ void gfx_ctx_set_swap_interval(unsigned interval, bool inited)
}
}
void gfx_ctx_check_window(bool *quit,
static void gfx_ctx_check_window(bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{
(void)frame_count;
@ -164,18 +168,18 @@ void gfx_ctx_check_window(bool *quit,
*quit = g_quit;
}
void gfx_ctx_swap_buffers(void)
static void gfx_ctx_swap_buffers(void)
{
eglSwapBuffers(g_egl_dpy, g_egl_surf);
}
void gfx_ctx_set_resize(unsigned width, unsigned height)
static void gfx_ctx_set_resize(unsigned width, unsigned height)
{
(void)width;
(void)height;
}
void gfx_ctx_update_window_title(bool reset)
static void gfx_ctx_update_window_title(bool reset)
{
if (reset)
gfx_window_title_reset();
@ -185,7 +189,7 @@ void gfx_ctx_update_window_title(bool reset)
XStoreName(g_dpy, g_win, buf);
}
void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
{
if (!g_dpy || g_win == None)
{
@ -213,7 +217,7 @@ void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
}
}
bool gfx_ctx_init(void)
static bool gfx_ctx_init(void)
{
if (g_inited)
return false;
@ -260,7 +264,7 @@ error:
return false;
}
bool gfx_ctx_set_video_mode(
static bool gfx_ctx_set_video_mode(
unsigned width, unsigned height,
unsigned bits, bool fullscreen)
{
@ -326,6 +330,7 @@ bool gfx_ctx_set_video_mode(
XSetWMProtocols(g_dpy, g_win, &g_quit_atom, 1);
gfx_suspend_screensaver(g_win);
gfx_ctx_swap_interval(g_interval);
XFree(vi);
g_has_focus = true;
@ -341,7 +346,7 @@ error:
return false;
}
void gfx_ctx_destroy(void)
static void gfx_ctx_destroy(void)
{
if (g_egl_dpy)
{
@ -383,7 +388,7 @@ void gfx_ctx_destroy(void)
g_inited = false;
}
void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
{
void *xinput = input_x.init();
*input = xinput ? &input_x : NULL;
@ -393,7 +398,7 @@ void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
x_input_set_disp_win((x11_input_t*)xinput, g_dpy, g_win);
}
bool gfx_ctx_window_has_focus(void)
static bool gfx_ctx_has_focus(void)
{
if (!g_inited)
return false;
@ -405,8 +410,41 @@ bool gfx_ctx_window_has_focus(void)
return win == g_win && g_has_focus;
}
gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
{
return eglGetProcAddress(symbol);
}
static bool gfx_ctx_bind_api(enum gfx_ctx_api api)
{
g_api = api;
switch (api)
{
case GFX_CTX_OPENGL_API:
return eglBindAPI(EGL_OPENGL_API);
case GFX_CTX_OPENGL_ES_API:
return eglBindAPI(EGL_OPENGL_ES_API);
case GFX_CTX_OPENVG_API:
return eglBindAPI(EGL_OPENVG_API);
default:
return false;
}
}
const gfx_ctx_driver_t gfx_ctx_x_egl = {
gfx_ctx_init,
gfx_ctx_destroy,
gfx_ctx_bind_api,
gfx_ctx_swap_interval,
gfx_ctx_set_video_mode,
gfx_ctx_get_video_size,
gfx_ctx_update_window_title,
gfx_ctx_check_window,
gfx_ctx_set_resize,
gfx_ctx_has_focus,
gfx_ctx_swap_buffers,
gfx_ctx_input_driver,
gfx_ctx_get_proc_address,
"x-egl",
};

66
gfx/gfx_context.c Normal file
View File

@ -0,0 +1,66 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2012 - Hans-Kristian Arntzen
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "gfx_context.h"
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
static const gfx_ctx_driver_t *gfx_ctx_drivers[] = {
#if defined(__CELLOS_LV2__)
&gfx_ctx_ps3,
#endif
#if defined(HAVE_VIDEOCORE)
&gfx_ctx_videocore,
#endif
#if defined(HAVE_SDL) && defined(HAVE_OPENGL)
&gfx_ctx_sdl_gl,
#endif
#if defined(HAVE_X11) && defined(HAVE_EGL)
&gfx_ctx_x_egl,
#endif
#if defined(HAVE_KMS)
&gfx_ctx_drm_egl,
#endif
};
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
{
for (unsigned i = 0; i < sizeof(gfx_ctx_drivers) / sizeof(gfx_ctx_drivers[0]); i++)
{
if (strcmp(gfx_ctx_drivers[i]->ident, ident) == 0)
return gfx_ctx_drivers[i];
}
return NULL;
}
const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api)
{
for (unsigned i = 0; i < sizeof(gfx_ctx_drivers) / sizeof(gfx_ctx_drivers[0]); i++)
{
if (gfx_ctx_drivers[i]->init())
{
if (gfx_ctx_drivers[i]->bind_api(api))
return gfx_ctx_drivers[i];
else
gfx_ctx_drivers[i]->destroy();
}
}
return NULL;
}

View File

@ -19,20 +19,88 @@
#include "../boolean.h"
#include "../driver.h"
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#ifdef HAVE_OPENGL
#include "gl_common.h"
#define VID_HANDLE gl_t
#endif
#if defined(HAVE_SDL) && !defined(__APPLE__)
#include "SDL_syswm.h"
#endif
enum gfx_ctx_api
{
GFX_CTX_OPENGL_API,
GFX_CTX_OPENGL_ES_API,
GFX_CTX_OPENVG_API
};
typedef void (*gfx_ctx_proc_t)(void);
// Avoid breakage on XBox. TODO: Migrate to new context abstraction if it makes sense.
#if !defined(HAVE_D3D9) && !defined(HAVE_D3D8)
typedef struct gfx_ctx_driver
{
bool (*init)(void);
void (*destroy)(void);
bool (*bind_api)(enum gfx_ctx_api); // Which API to bind to.
// Sets the swap interval.
void (*swap_interval)(unsigned);
// Sets video mode. Creates a window, etc.
bool (*set_video_mode)(unsigned, unsigned, unsigned, bool);
// Gets current window size.
// If not initialized yet, it returns current screen size.
void (*get_video_size)(unsigned*, unsigned*);
// Asks driver to update window title (FPS, etc).
void (*update_window_title)(bool);
// Queries for resize and quit events.
// Also processes events.
void (*check_window)(bool*, bool*, unsigned*, unsigned*, unsigned);
// Acknowledge a resize event. This is needed for some APIs. Most backends will ignore this.
void (*set_resize)(unsigned, unsigned);
// Checks if window has input focus.
bool (*has_focus)(void);
// Swaps buffers. VBlank sync depends on earlier calls to swap_interval.
void (*swap_buffers)(void);
// Most video backends will want to use a certain input driver.
// Checks for it here.
void (*input_driver)(const input_driver_t**, void**);
// Wraps whatever gl_proc_address() there is.
gfx_ctx_proc_t (*get_proc_address)(const char*);
// Human readable string.
const char *ident;
#ifdef RARCH_CONSOLE
void (*set_filtering)(unsigned index, bool set_smooth);
void (*get_available_resolutions)(void);
int (*check_resolution)(unsigned resolution_id);
bool (*menu_init)(void);
void (*set_fbo)(bool);
void (*apply_fbo_state_changes)(unsigned);
#endif
} gfx_ctx_driver_t;
extern const gfx_ctx_driver_t gfx_ctx_sdl_gl;
extern const gfx_ctx_driver_t gfx_ctx_x_egl;
extern const gfx_ctx_driver_t gfx_ctx_drm_egl;
extern const gfx_ctx_driver_t gfx_ctx_ps3;
extern const gfx_ctx_driver_t gfx_ctx_videocore;
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api); // Finds first suitable driver and initializes.
#else
void gfx_ctx_set_swap_interval(unsigned interval, bool inited);
bool gfx_ctx_set_video_mode(
@ -50,10 +118,6 @@ void gfx_ctx_check_window(bool *quit,
void gfx_ctx_set_resize(unsigned width, unsigned height);
#if defined(HAVE_SDL) && !defined(__APPLE__)
bool gfx_ctx_get_wm_info(SDL_SysWMinfo *info);
#endif
#ifndef HAVE_GRIFFIN
bool gfx_ctx_window_has_focus(void);
#endif
@ -65,16 +129,10 @@ void gfx_ctx_input_driver(const input_driver_t **input, void **input_data);
bool gfx_ctx_menu_init(void);
#endif
#ifdef RARCH_CONSOLE
void gfx_ctx_set_filtering(unsigned index, bool set_smooth);
void gfx_ctx_get_available_resolutions(void);
int gfx_ctx_check_resolution(unsigned resolution_id);
#endif
typedef void (*gfx_ctx_proc_t)(void);
gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *sym);
#if defined(HAVE_D3D9) || defined(HAVE_D3D8)
void gfx_ctx_set_projection(xdk_d3d_video_t *vid, const struct gl_ortho *ortho, bool allow_rotate);
#endif

107
gfx/gl.c
View File

@ -26,10 +26,6 @@
#include "config.h"
#endif
#ifdef HAVE_EGL
#include <EGL/egl.h>
#endif
#include "gl_common.h"
#include "gl_font.h"
#include "gfx_common.h"
@ -94,7 +90,7 @@ const GLfloat *vertex_ptr = vertexes_flipped;
const GLfloat *default_vertex_ptr = vertexes_flipped;
#define LOAD_GL_SYM(SYM) if (!pgl##SYM) { \
gfx_ctx_proc_t sym = gfx_ctx_get_proc_address("gl" #SYM); \
gfx_ctx_proc_t sym = gl->driver->get_proc_address("gl" #SYM); \
memcpy(&(pgl##SYM), &sym, sizeof(sym)); \
}
@ -106,7 +102,7 @@ static PFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D = NULL;
static PFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus = NULL;
static PFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers = NULL;
static bool load_fbo_proc(void)
static bool load_fbo_proc(gl_t *gl)
{
LOAD_GL_SYM(GenFramebuffers);
LOAD_GL_SYM(BindFramebuffer);
@ -123,7 +119,7 @@ static bool load_fbo_proc(void)
#define pglFramebufferTexture2D glFramebufferTexture2D
#define pglCheckFramebufferStatus glCheckFramebufferStatus
#define pglDeleteFramebuffers glDeleteFramebuffers
static bool load_fbo_proc(void) { return true; }
#define load_fbo_proc(gl) (true)
#elif defined(HAVE_OPENGLES)
#define pglGenFramebuffers glGenFramebuffersOES
#define pglBindFramebuffer glBindFramebufferOES
@ -133,14 +129,14 @@ static bool load_fbo_proc(void) { return true; }
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_OES
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES
static bool load_fbo_proc(void) { return true; }
#define load_fbo_proc(gl) (true)
#else
#define pglGenFramebuffers glGenFramebuffers
#define pglBindFramebuffer glBindFramebuffer
#define pglFramebufferTexture2D glFramebufferTexture2D
#define pglCheckFramebufferStatus glCheckFramebufferStatus
#define pglDeleteFramebuffers glDeleteFramebuffers
static bool load_fbo_proc(void) { return true; }
#define load_fbo_proc(gl) (true)
#endif
#endif
@ -152,7 +148,7 @@ static PFNGLBUFFERSUBDATAPROC pglBufferSubData;
static PFNGLBUFFERDATAPROC pglBufferData;
static PFNGLMAPBUFFERPROC pglMapBuffer;
static PFNGLUNMAPBUFFERPROC pglUnmapBuffer;
static inline bool load_gl_proc_win32(void)
static inline bool load_gl_proc_win32(gl_t *gl)
{
LOAD_GL_SYM(ClientActiveTexture);
LOAD_GL_SYM(ActiveTexture);
@ -521,7 +517,7 @@ void gl_init_fbo(gl_t *gl, unsigned width, unsigned height)
if (gl_shader_num() == 1 && !scale.valid && !g_settings.video.render_to_texture)
return;
if (!load_fbo_proc())
if (!load_fbo_proc(gl))
{
RARCH_ERR("Failed to locate FBO functions. Won't be able to use render-to-texture.\n");
return;
@ -1102,7 +1098,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
if (gl->should_resize)
{
gl->should_resize = false;
gfx_ctx_set_resize(gl->win_width, gl->win_height);
gl->driver->set_resize(gl->win_width, gl->win_height);
// On resize, we might have to recreate our FBOs due to "Viewport" scale, and set a new viewport.
gl_update_resize(gl);
@ -1144,13 +1140,13 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
gl_render_msg(gl, msg);
#ifndef RARCH_CONSOLE
gfx_ctx_update_window_title(false);
gl->driver->update_window_title(false);
#endif
#ifdef RARCH_CONSOLE
if (!gl->block_swap)
#endif
gfx_ctx_swap_buffers();
gl->driver->swap_buffers();
#ifdef HAVE_CG_MENU
if (gl->menu_render)
@ -1199,7 +1195,7 @@ static void gl_free(void *data)
gl_deinit_fbo(gl);
#endif
gfx_ctx_destroy();
gl->driver->destroy();
free(gl->empty_buf);
free(gl->conv_buffer);
@ -1209,10 +1205,10 @@ static void gl_free(void *data)
static void gl_set_nonblock_state(void *data, bool state)
{
(void)data;
gl_t *gl = (gl_t*)data;
RARCH_LOG("GL VSync => %s\n", state ? "off" : "on");
gfx_ctx_set_swap_interval(state ? 0 : 1, true);
gl->driver->swap_interval(state ? 0 : 1);
}
static bool resolve_extensions(gl_t *gl)
@ -1220,7 +1216,7 @@ static bool resolve_extensions(gl_t *gl)
#ifdef _WIN32
// Win32 GL lib doesn't have some elementary functions needed.
// Need to load dynamically :(
if (!load_gl_proc_win32())
if (!load_gl_proc_win32(gl))
return false;
#endif
@ -1265,26 +1261,23 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
if (!gl)
return NULL;
#ifdef HAVE_EGL
#ifdef HAVE_OPENGLES
if (!eglBindAPI(EGL_OPENGL_ES_API))
return NULL;
gl->driver = gfx_ctx_init_first(GFX_CTX_OPENGL_ES_API);
#else
if (!eglBindAPI(EGL_OPENGL_API))
return NULL;
gl->driver = gfx_ctx_init_first(GFX_CTX_OPENGL_API);
#endif
#endif
if (!gfx_ctx_init())
if (!gl->driver)
{
free(gl);
return NULL;
}
gfx_ctx_get_video_size(&gl->full_x, &gl->full_y);
RARCH_LOG("Found GL context: %s\n", gl->driver->ident);
gl->driver->get_video_size(&gl->full_x, &gl->full_y);
RARCH_LOG("Detecting screen resolution %ux%u.\n", gl->full_x, gl->full_y);
gfx_ctx_set_swap_interval(video->vsync ? 1 : 0, false);
gl->driver->swap_interval(video->vsync ? 1 : 0);
unsigned win_width = video->width;
unsigned win_height = video->height;
@ -1294,7 +1287,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
win_height = gl->full_y;
}
if (!gfx_ctx_set_video_mode(win_width, win_height,
if (!gl->driver->set_video_mode(win_width, win_height,
g_settings.video.force_16bit ? 15 : 0, video->fullscreen))
{
free(gl);
@ -1302,13 +1295,13 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
}
#ifndef RARCH_CONSOLE
gfx_ctx_update_window_title(true);
gl->driver->update_window_title(true);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#endif
if (!resolve_extensions(gl))
{
gfx_ctx_destroy();
gl->driver->destroy();
free(gl);
return NULL;
}
@ -1317,7 +1310,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl->fullscreen = video->fullscreen;
// Get real known video size, which might have been altered by context.
gfx_ctx_get_video_size(&gl->win_width, &gl->win_height);
gl->driver->get_video_size(&gl->win_width, &gl->win_height);
RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);
if (gl->full_x || gl->full_y) // We got bogus from gfx_ctx_get_video_size. Replace.
@ -1331,10 +1324,14 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl_cg_set_menu_shader(default_paths.menu_shader_file);
#endif
#ifdef HAVE_XML
gl_glsl_set_get_proc_address(gl->driver->get_proc_address);
#endif
if (!gl_shader_init())
{
RARCH_ERR("Shader init failed.\n");
gfx_ctx_destroy();
gl->driver->destroy();
free(gl);
return NULL;
}
@ -1402,7 +1399,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
gl->conv_buffer = calloc(gl->tex_w * gl->tex_h, gl->base_size);
if (!gl->conv_buffer)
{
gfx_ctx_destroy();
gl->driver->destroy();
free(gl);
return NULL;
}
@ -1426,12 +1423,12 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
memcpy(gl->prev_info[i].coord, tex_coords, sizeof(tex_coords));
}
gfx_ctx_input_driver(input, input_data);
gl->driver->input_driver(input, input_data);
gl_init_font(gl, g_settings.video.font_path, g_settings.video.font_size);
if (!gl_check_error())
{
gfx_ctx_destroy();
gl->driver->destroy();
free(gl);
return NULL;
}
@ -1444,7 +1441,7 @@ static bool gl_alive(void *data)
gl_t *gl = (gl_t*)data;
bool quit, resize;
gfx_ctx_check_window(&quit,
gl->driver->check_window(&quit,
&resize, &gl->win_width, &gl->win_height,
gl->frame_count);
@ -1458,8 +1455,8 @@ static bool gl_alive(void *data)
static bool gl_focus(void *data)
{
(void)data;
return gfx_ctx_window_has_focus();
gl_t *gl = (gl_t*)data;
return gl->driver->has_focus();
}
#if defined(HAVE_XML) || defined(HAVE_CG)
@ -1553,29 +1550,25 @@ static void gl_start(void)
video_info.fullscreen = true;
if (g_console.aspect_ratio_index == ASPECT_RATIO_CUSTOM)
{
video_info.width = g_console.viewports.custom_vp.width;
video_info.width = g_console.viewports.custom_vp.width;
video_info.height = g_console.viewports.custom_vp.height;
}
driver.video_data = gl_init(&video_info, NULL, NULL);
#ifdef HAVE_FBO
gfx_ctx_set_fbo(g_console.fbo_enabled);
#endif
gfx_ctx_get_available_resolutions();
#ifdef HAVE_CG_MENU
gfx_ctx_menu_init();
#endif
if (gl->driver->set_fbo)
gl->driver->set_fbo(g_console.fbo_enabled);
gl->driver->get_available_resolutions();
if (gl->driver->menu_init)
gl->driver->menu_init();
#ifdef HAVE_FBO
// FBO mode has to be enabled once even if FBO mode has to be
// turned off
if (!g_console.fbo_enabled)
{
gfx_ctx_apply_fbo_state_changes(FBO_DEINIT);
gfx_ctx_apply_fbo_state_changes(FBO_INIT);
gfx_ctx_apply_fbo_state_changes(FBO_DEINIT);
gl->driver->apply_fbo_state_changes(FBO_DEINIT);
gl->driver->apply_fbo_state_changes(FBO_INIT);
gl->driver->apply_fbo_state_changes(FBO_DEINIT);
}
#endif
}
@ -1589,22 +1582,16 @@ static void gl_stop(void)
static void gl_restart(void)
{
#ifdef HAVE_CG_MENU
bool should_menu_render;
#endif
#ifdef RARCH_CONSOLE
bool should_block_swap;
#endif
gl_t *gl = driver.video_data;
if (!gl)
return;
#ifdef RARCH_CONSOLE
should_block_swap = gl->block_swap;
bool should_block_swap = gl->block_swap;
#endif
#ifdef HAVE_CG_MENU
should_menu_render = gl->menu_render;
bool should_menu_render = gl->menu_render;
#endif
gl_stop();

View File

@ -19,6 +19,7 @@
#include "../general.h"
#include "fonts/fonts.h"
#include "math/matrix.h"
#include "gfx_context.h"
#ifdef HAVE_CONFIG_H
#include "../config.h"
@ -161,13 +162,7 @@ struct gl_coords
typedef struct gl
{
#ifdef RARCH_CONSOLE
bool block_swap;
#endif
#ifdef HAVE_CG_MENU
bool menu_render;
GLuint menu_texture_id;
#endif
const gfx_ctx_driver_t *driver;
bool vsync;
GLuint texture[TEXTURES];
unsigned tex_index; // For use with PREV.
@ -226,6 +221,14 @@ typedef struct gl
GLfloat font_color[16];
GLfloat font_color_dark[16];
#endif
#ifdef RARCH_CONSOLE
bool block_swap;
#endif
#ifdef HAVE_CG_MENU
bool menu_render;
GLuint menu_texture_id;
#endif
} gl_t;
// Windows ... <_<

View File

@ -154,6 +154,8 @@ static char *gl_script_program = NULL;
static GLint gl_attribs[PREV_TEXTURES + 1 + 4 + MAX_PROGRAMS];
static unsigned gl_attrib_index = 0;
static gfx_ctx_proc_t (*glsl_get_proc_address)(const char*);
struct shader_program
{
char *vertex;
@ -928,13 +930,14 @@ static void gl_glsl_reset_attrib(void)
// Platforms with broken get_proc_address.
// Assume functions are available without proc_address.
#define LOAD_GL_SYM(SYM) if (!pgl##SYM) { \
gfx_ctx_proc_t sym = gfx_ctx_get_proc_address("gl" #SYM); \
gfx_ctx_proc_t sym = glsl_get_proc_address("gl" #SYM); \
memcpy(&(pgl##SYM), &sym, sizeof(sym)); \
}
bool gl_glsl_init(const char *path)
{
#if !defined(HAVE_OPENGLES2) && !defined(HAVE_OPENGL_MODERN)
// Load shader functions.
LOAD_GL_SYM(CreateProgram);
LOAD_GL_SYM(UseProgram);
@ -1427,3 +1430,9 @@ void gl_glsl_shader_scale(unsigned index, struct gl_fbo_scale *scale)
else
scale->valid = false;
}
void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*))
{
glsl_get_proc_address = proc;
}

View File

@ -19,6 +19,7 @@
#include "../boolean.h"
#include "gl_common.h"
#include "gfx_context.h"
#include "math/matrix.h"
bool gl_glsl_init(const char *path);
@ -43,4 +44,6 @@ void gl_glsl_shader_scale(unsigned index, struct gl_fbo_scale *scale);
bool gl_glsl_set_coords(const struct gl_coords *coords);
bool gl_glsl_set_mvp(const math_matrix *mat);
void gl_glsl_set_get_proc_address(gfx_ctx_proc_t (*proc)(const char*));
#endif

View File

@ -106,7 +106,8 @@ sdl_dinput_t* sdl_dinput_init(void)
CoInitialize(NULL);
SDL_SysWMinfo info;
if (!gfx_ctx_get_wm_info(&info))
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info) != 1)
{
RARCH_ERR("Failed to get SysWM info.\n");
goto error;

View File

@ -127,18 +127,23 @@ fi
check_lib DYNAMIC "$DYLIB" dlopen
if [ "$HAVE_KMS" = "yes" ]; then
check_pkgconf GBM gbm
check_pkgconf DRM libdrm
check_pkgconf GBM gbm 9.1.0
check_pkgconf DRM libdrm
if [ "$HAVE_KMS" != "no" ]; then
if [ "$HAVE_GBM" = "yes" ] && [ "$HAVE_DRM" = "yes" ]; then
HAVE_KMS=yes
HAVE_EGL=yes
HAVE_EGL=yes # Required
elif [ "$HAVE_KMS" = "yes" ]; then
echo "Cannot find libgbm and/or libdrm libraries required."
exit 1
else
HAVE_KMS=no
fi
fi
[ "$HAVE_GLES" = "yes" ] && HAVE_EGL=yes && HAVE_XML=yes
[ "$HAVE_VG" = "yes" ] && HAVE_EGL=yes
if [ "$HAVE_VIDEOCORE" != "yes" ]; then
check_pkgconf EGL egl
check_pkgconf GLES glesv2

View File

@ -6,8 +6,9 @@ HAVE_DYLIB=auto # Enable dynamic loading support
HAVE_NETPLAY=auto # Enable netplay support
HAVE_CONFIGFILE=yes # Disable support for config file
HAVE_OPENGL=yes # Disable OpenGL support
HAVE_GLES=no # Use X/EGL instead of desktop GL (experimental)
HAVE_KMS=no # Use KMS framebuffer EGL instead of desktop GL (experimental)
HAVE_GLES=no # Use GLESv2 instead of desktop GL
HAVE_KMS=auto # Enable KMS context support
HAVE_EGL=auto # Enable EGL context support
HAVE_VG=no # Enable OpenVG support
HAVE_CG=auto # Enable Cg shader support
HAVE_XML=auto # Enable bSNES-style XML shader support