diff --git a/gfx/drivers_context/mali_fbdev_ctx.c b/gfx/drivers_context/mali_fbdev_ctx.c index f5c98d2bae..37418cee64 100644 --- a/gfx/drivers_context/mali_fbdev_ctx.c +++ b/gfx/drivers_context/mali_fbdev_ctx.c @@ -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; }