mirror of
https://github.com/libretro/RetroArch
synced 2024-07-05 17:58:41 +00:00
mali_fbdev fix for fps drop after egl_destroy (#13494)
Currently each time a screen resolution or setting change occurs, fbdev_destroy, fbdev_init and fbdev_set_mode are called in sequence, trying to destroy context and surface (though context pointer seems to remain unchanged) and create again both of them. However it seems something is wrong with egl_destroy, as after the call fps drops from 60 to 33fps in GUI with huge performance impact, at least with libmali. Philosophy is changed with this commit to avoid destroying and creating context and surface each time (creation only occurs in fbdev_init and egl_destroy is called only if retroarch is shutting down). As a minor modification, framebuffer is resetted to 0 on retroarch shutdown to avoid any chance of freezed screen effect.
This commit is contained in:
parent
aca2b9675f
commit
f93548ab56
|
@ -53,35 +53,102 @@ typedef struct
|
|||
float refresh_rate;
|
||||
} mali_ctx_data_t;
|
||||
|
||||
mali_ctx_data_t *mali=NULL;
|
||||
|
||||
static int gfx_ctx_mali_fbdev_get_vinfo(void *data)
|
||||
{
|
||||
struct fb_var_screeninfo vinfo;
|
||||
int fd = open("/dev/fb0", O_RDWR);
|
||||
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
if (!mali || ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
|
||||
goto error;
|
||||
|
||||
/*Workaround to reset yoffset when returned >0 from driver */
|
||||
if (vinfo.yoffset != 0)
|
||||
{
|
||||
vinfo.yoffset = 0;
|
||||
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo))
|
||||
{
|
||||
RARCH_ERR("Error resetting yoffset to 0.\n");
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
||||
mali->width = vinfo.xres;
|
||||
mali->height = vinfo.yres;
|
||||
|
||||
mali->native_window.width = vinfo.xres;
|
||||
mali->native_window.height = vinfo.yres;
|
||||
|
||||
if (vinfo.pixclock)
|
||||
{
|
||||
mali->refresh_rate = 1000000.0f / vinfo.pixclock * 1000000.0f /
|
||||
(vinfo.yres + vinfo.upper_margin + vinfo.lower_margin + vinfo.vsync_len) /
|
||||
(vinfo.xres + vinfo.left_margin + vinfo.right_margin + vinfo.hsync_len);
|
||||
}else{
|
||||
mali->refresh_rate = 60;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void gfx_ctx_mali_fbdev_clear_screen(void)
|
||||
{
|
||||
struct fb_var_screeninfo vinfo;
|
||||
void *buffer = NULL;
|
||||
int fd = open("/dev/fb0", O_RDWR);
|
||||
|
||||
ioctl (fd, FBIOGET_VSCREENINFO, &vinfo);
|
||||
long buffer_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
|
||||
buffer = calloc(1, buffer_size);
|
||||
write(fd,buffer,buffer_size);
|
||||
free(buffer);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void gfx_ctx_mali_fbdev_destroy(void *data)
|
||||
{
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
if (mali)
|
||||
{
|
||||
mali->resize = false;
|
||||
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
|
||||
if (runloop_st->shutdown_initiated) {
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
egl_destroy(&mali->egl);
|
||||
if (mali)
|
||||
egl_destroy(&mali->egl);
|
||||
#endif
|
||||
|
||||
mali->resize = false;
|
||||
free(mali);
|
||||
}
|
||||
gfx_ctx_mali_fbdev_clear_screen();
|
||||
|
||||
/* Clear framebuffer and set cursor on again */
|
||||
if (!system(NULL) && !system("which setterm > /dev/null 2>&1"))
|
||||
{
|
||||
int fd = open("/dev/tty", O_RDWR);
|
||||
ioctl(fd, VT_ACTIVATE, 5);
|
||||
ioctl(fd, VT_ACTIVATE, 1);
|
||||
close(fd);
|
||||
system("setterm -cursor on");
|
||||
{
|
||||
int fd = open("/dev/tty", O_RDWR);
|
||||
ioctl(fd, VT_ACTIVATE, 5);
|
||||
ioctl(fd, VT_ACTIVATE, 1);
|
||||
close(fd);
|
||||
system("setterm -cursor on");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_mali_fbdev_get_video_size(void *data,
|
||||
unsigned *width, unsigned *height)
|
||||
{
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
*width = mali->width;
|
||||
*height = mali->height;
|
||||
|
@ -89,11 +156,14 @@ static void gfx_ctx_mali_fbdev_get_video_size(void *data,
|
|||
|
||||
static void *gfx_ctx_mali_fbdev_init(void *video_driver)
|
||||
{
|
||||
if (mali)
|
||||
return mali;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
EGLint n;
|
||||
EGLint major, minor;
|
||||
EGLint format;
|
||||
static const EGLint attribs[] = {
|
||||
static const EGLint attribs_init[] = {
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
|
@ -102,20 +172,28 @@ static void *gfx_ctx_mali_fbdev_init(void *video_driver)
|
|||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
static const EGLint attribs_create[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)calloc(1, sizeof(*mali));
|
||||
mali = (mali_ctx_data_t*)calloc(1, sizeof(*mali));
|
||||
|
||||
if (!mali)
|
||||
return NULL;
|
||||
if (gfx_ctx_mali_fbdev_get_vinfo(mali))
|
||||
goto error;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
frontend_driver_install_signal_handler();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_init_context(&mali->egl, EGL_NONE, EGL_DEFAULT_DISPLAY,
|
||||
&major, &minor, &n, attribs, NULL))
|
||||
&major, &minor, &n, attribs_init, NULL) ||
|
||||
!egl_create_context(&mali->egl, attribs_create) ||
|
||||
!egl_create_surface(&mali->egl, &mali->native_window))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
|
@ -148,66 +226,17 @@ static bool gfx_ctx_mali_fbdev_set_video_mode(void *data,
|
|||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
struct fb_var_screeninfo vinfo;
|
||||
static const EGLint attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2, /* Use version 2, even for GLES3. */
|
||||
EGL_NONE
|
||||
};
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
int fd = open("/dev/fb0", O_RDWR);
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
|
||||
{
|
||||
RARCH_ERR("Error obtaining framebuffer info.\n");
|
||||
goto error;
|
||||
}
|
||||
/*Workaround to reset yoffset when returned >0 from driver */
|
||||
if (vinfo.yoffset != 0)
|
||||
{
|
||||
vinfo.yoffset = 0;
|
||||
if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo))
|
||||
{
|
||||
RARCH_ERR("Error resetting yoffset to 0.\n");
|
||||
}
|
||||
}
|
||||
if (gfx_ctx_mali_fbdev_get_vinfo(mali))
|
||||
goto error;
|
||||
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
||||
width = vinfo.xres;
|
||||
height = vinfo.yres;
|
||||
|
||||
mali->width = width;
|
||||
mali->height = height;
|
||||
|
||||
mali->native_window.width = vinfo.xres;
|
||||
mali->native_window.height = vinfo.yres;
|
||||
|
||||
if (vinfo.pixclock)
|
||||
{
|
||||
mali->refresh_rate = 1000000.0f / vinfo.pixclock * 1000000.0f /
|
||||
(vinfo.yres + vinfo.upper_margin + vinfo.lower_margin + vinfo.vsync_len) /
|
||||
(vinfo.xres + vinfo.left_margin + vinfo.right_margin + vinfo.hsync_len);
|
||||
}else{
|
||||
mali->refresh_rate = 60;
|
||||
}
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_create_context(&mali->egl, attribs))
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
if (!egl_create_surface(&mali->egl, &mali->native_window))
|
||||
goto error;
|
||||
#endif
|
||||
width = mali->width;
|
||||
height = mali->height;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
egl_report_error();
|
||||
gfx_ctx_mali_fbdev_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
@ -240,7 +269,7 @@ static bool gfx_ctx_mali_fbdev_suppress_screensaver(void *data, bool enable) { r
|
|||
static void gfx_ctx_mali_fbdev_set_swap_interval(void *data,
|
||||
int swap_interval)
|
||||
{
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
egl_set_swap_interval(&mali->egl, swap_interval);
|
||||
|
@ -249,7 +278,7 @@ static void gfx_ctx_mali_fbdev_set_swap_interval(void *data,
|
|||
|
||||
static void gfx_ctx_mali_fbdev_swap_buffers(void *data)
|
||||
{
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
egl_swap_buffers(&mali->egl);
|
||||
|
@ -258,7 +287,7 @@ static void gfx_ctx_mali_fbdev_swap_buffers(void *data)
|
|||
|
||||
static void gfx_ctx_mali_fbdev_bind_hw_render(void *data, bool enable)
|
||||
{
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
egl_bind_hw_render(&mali->egl, enable);
|
||||
|
@ -278,7 +307,7 @@ static void gfx_ctx_mali_fbdev_set_flags(void *data, uint32_t flags) { }
|
|||
|
||||
static float gfx_ctx_mali_fbdev_get_refresh_rate(void *data)
|
||||
{
|
||||
mali_ctx_data_t *mali = (mali_ctx_data_t*)data;
|
||||
mali = (mali_ctx_data_t*)data;
|
||||
|
||||
return mali->refresh_rate;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user