From 4cdfcf30d52fd5c99a594639fd5911ec85b1fca5 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 7 Apr 2013 14:05:39 +0200 Subject: [PATCH] Refactor set_rgui_texture. More generic and avoids poking directly into RGUI state. --- driver.h | 9 +++-- frontend/menu/rgui.c | 12 ++++-- gfx/gl.c | 96 +++++++++++++++++++++++++++----------------- gfx/gl_common.h | 3 +- gfx/thread_wrapper.c | 58 +++++++++++++++++++++++--- gx/gx_video.c | 19 +++++++-- gx/gx_video.h | 1 + 7 files changed, 144 insertions(+), 54 deletions(-) diff --git a/driver.h b/driver.h index 9f11384835..e6d731d7af 100644 --- a/driver.h +++ b/driver.h @@ -298,7 +298,8 @@ typedef struct input_driver { void *(*init)(void); void (*poll)(void *data); - int16_t (*input_state)(void *data, const struct retro_keybind **retro_keybinds, unsigned port, unsigned device, unsigned index, unsigned id); + int16_t (*input_state)(void *data, const struct retro_keybind **retro_keybinds, + unsigned port, unsigned device, unsigned index, unsigned id); bool (*key_pressed)(void *data, int key); void (*free)(void *data); void (*set_keybinds)(void *data, unsigned device, unsigned port, unsigned id, unsigned keybind_action); @@ -334,9 +335,9 @@ typedef struct video_poke_interface void (*set_aspect_ratio)(void *data, unsigned aspectratio_index); void (*apply_state_changes)(void *data); - // Set to NULL if RGUI texture is not supposed to be rendered. -#ifdef HAVE_RGUI - void (*set_rgui_texture)(void *data, const void *frame); +#if defined(HAVE_RGUI) + void (*set_texture_frame)(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha); // Update texture. + void (*set_texture_enable)(void *data, bool enable); // Enable/disable rendering. #endif void (*set_osd_msg)(void *data, const char *msg, void *userdata); diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index 356b54efe0..2d69044f71 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -1801,13 +1801,17 @@ bool menu_iterate(void) input_entry_ret = rgui_iterate(rgui, action); // draw last frame for loading messages - if (driver.video_poke && driver.video_poke->set_rgui_texture) - driver.video_poke->set_rgui_texture(driver.video_data, menu_framebuf); + if (driver.video_poke && driver.video_poke->set_texture_enable) + { + driver.video_poke->set_texture_frame(driver.video_data, menu_framebuf, + false, RGUI_WIDTH, RGUI_HEIGHT, 1.0f); + driver.video_poke->set_texture_enable(driver.video_data, true); + } rarch_render_cached_frame(); - if (driver.video_poke && driver.video_poke->set_rgui_texture) - driver.video_poke->set_rgui_texture(driver.video_data, NULL); + if (driver.video_poke && driver.video_poke->set_texture_enable) + driver.video_poke->set_texture_enable(driver.video_data, false); input_process_ret = menu_input_process(NULL, NULL); diff --git a/gfx/gl.c b/gfx/gl.c index b507e8bf63..983024114a 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -58,10 +58,6 @@ #include "../frontend/frontend_android.h" #endif -#ifdef HAVE_RGUI -#include "../frontend/menu/rgui.h" -#endif - // Used for the last pass when rendering to the back buffer. const GLfloat vertexes_flipped[] = { 0, 1, @@ -1131,20 +1127,6 @@ static void gl_init_textures_data(void *data) } } -#ifdef HAVE_RGUI -static void gl_init_rgui_texture(void *data) -{ - gl_t *gl = (gl_t*)data; - - glGenTextures(1, &gl->rgui_texture); - glBindTexture(GL_TEXTURE_2D, gl->rgui_texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->border_type); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); -} -#endif - static void gl_init_textures(void *data, const video_info_t *video) { gl_t *gl = (gl_t*)data; @@ -1165,10 +1147,6 @@ static void gl_init_textures(void *data, const video_info_t *video) glGenTextures(TEXTURES, gl->texture); -#ifdef HAVE_RGUI - gl_init_rgui_texture(gl); -#endif - for (unsigned i = 0; i < TEXTURES; i++) { glBindTexture(GL_TEXTURE_2D, gl->texture[i]); @@ -1327,19 +1305,21 @@ static void gl_pbo_async_readback(void *data) #endif #ifdef HAVE_RGUI -static inline void gl_draw_rgui(void *data) +static inline void gl_draw_texture(void *data) { gl_t *gl = (gl_t*)data; + + const GLfloat color[] = { + 1.0f, 1.0f, 1.0f, gl->rgui_texture_alpha, + 1.0f, 1.0f, 1.0f, gl->rgui_texture_alpha, + 1.0f, 1.0f, 1.0f, gl->rgui_texture_alpha, + 1.0f, 1.0f, 1.0f, gl->rgui_texture_alpha, + }; + gl->coords.tex_coord = tex_coords; - + gl->coords.color = color; glBindTexture(GL_TEXTURE_2D, gl->rgui_texture); - glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(RGUI_WIDTH * 2)); - // RGUI is always packed so pitch = width * bpp - glTexImage2D(GL_TEXTURE_2D, - 0, GL_RGBA, RGUI_WIDTH, RGUI_HEIGHT, 0, GL_RGBA, - GL_UNSIGNED_SHORT_4_4_4_4, gl->rgui_data); - gl_shader_use_func(gl, 0); gl_shader_set_coords_func(gl, &gl->coords, &gl->mvp_no_rot); @@ -1348,6 +1328,7 @@ static inline void gl_draw_rgui(void *data) glDisable(GL_BLEND); gl->coords.tex_coord = gl->tex_coords; + gl->coords.color = white_color; } #endif @@ -1458,8 +1439,8 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei gl_set_prev_texture(gl, &tex_info); #ifdef HAVE_RGUI - if (gl->rgui_data) - gl_draw_rgui(gl); + if (gl->rgui_texture_enable) + gl_draw_texture(gl); #endif #ifdef FPS_COUNTER @@ -1540,7 +1521,8 @@ static void gl_free(void *data) glDeleteTextures(TEXTURES, gl->texture); #ifdef HAVE_RGUI - glDeleteTextures(1, &gl->rgui_texture); + if (gl->rgui_texture) + glDeleteTextures(1, &gl->rgui_texture); #endif #ifdef HAVE_OVERLAY @@ -2359,10 +2341,51 @@ static void gl_set_blend(void *data, bool enable) } #ifdef HAVE_RGUI -static void gl_set_rgui_texture(void *data, const void *frame) +static void gl_set_texture_frame(void *data, + const void *frame, bool rgb32, unsigned width, unsigned height, + float alpha) { gl_t *gl = (gl_t*)data; - gl->rgui_data = frame; + + if (!gl->rgui_texture) + { + glGenTextures(1, &gl->rgui_texture); + glBindTexture(GL_TEXTURE_2D, gl->rgui_texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gl->border_type); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gl->border_type); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } + else + glBindTexture(GL_TEXTURE_2D, gl->rgui_texture); + + gl->rgui_texture_alpha = alpha; + + unsigned base_size = rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); + glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(width * base_size)); + + if (rgb32) + { + glTexImage2D(GL_TEXTURE_2D, + 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_INTERNAL_FORMAT32, + width, height, + 0, driver.gfx_use_rgba ? GL_RGBA : RARCH_GL_TEXTURE_TYPE32, + RARCH_GL_FORMAT32, frame); + } + else + { + glTexImage2D(GL_TEXTURE_2D, + 0, GL_RGBA, width, height, 0, GL_RGBA, + GL_UNSIGNED_SHORT_4_4_4_4, frame); + } + + glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); +} + +static void gl_set_texture_enable(void *data, bool state) +{ + gl_t *gl = (gl_t*)data; + gl->rgui_texture_enable = state; } #endif @@ -2398,7 +2421,8 @@ static const video_poke_interface_t gl_poke_interface = { gl_set_aspect_ratio, gl_apply_state_changes, #ifdef HAVE_RGUI - gl_set_rgui_texture, + gl_set_texture_frame, + gl_set_texture_enable, #endif gl_set_osd_msg, diff --git a/gfx/gl_common.h b/gfx/gl_common.h index ab14e5a2c6..b866b95592 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -287,7 +287,8 @@ typedef struct gl #ifdef HAVE_RGUI GLuint rgui_texture; - const void *rgui_data; + bool rgui_texture_enable; + GLfloat rgui_texture_alpha; #endif } gl_t; diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 6962a8bb96..6e2df4eac3 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -72,7 +72,17 @@ typedef struct thread_video void **input_data; #ifdef HAVE_RGUI - const void *rgui_texture; + struct + { + void *frame; + size_t frame_cap; + bool frame_updated; + bool rgb32; + unsigned width; + unsigned height; + float alpha; + bool enable; + } texture; #endif bool apply_state_changes; @@ -294,8 +304,17 @@ static void thread_loop(void *data) slock_lock(thr->frame.lock); #ifdef HAVE_RGUI - thr->poke->set_rgui_texture(thr->driver_data, thr->rgui_texture); + if (thr->texture.frame_updated) + { + thr->poke->set_texture_frame(thr->driver_data, + thr->texture.frame, thr->texture.rgb32, + thr->texture.width, thr->texture.height, + thr->texture.alpha); + thr->texture.frame_updated = false; + } + thr->poke->set_texture_enable(thr->driver_data, thr->texture.enable); #endif + if (thr->apply_state_changes) { thr->poke->apply_state_changes(thr->driver_data); @@ -407,7 +426,7 @@ static bool thread_frame(void *data, const void *frame_, // we'll want to block to avoid stepping menu // at crazy speeds. #ifdef HAVE_RGUI - if (thr->rgui_texture) + if (thr->texture.enable) { while (thr->frame.updated) scond_wait(thr->cond_cmd, thr->lock); @@ -510,6 +529,7 @@ static void thread_free(void *data) thread_wait_reply(thr, CMD_FREE); sthread_join(thr->thread); + free(thr->texture.frame); free(thr->frame.buffer); slock_free(thr->frame.lock); slock_free(thr->lock); @@ -620,12 +640,37 @@ static void thread_set_aspect_ratio(void *data, unsigned aspectratio_index) } #ifdef HAVE_RGUI -static void thread_set_rgui_texture(void *data, const void *frame) +static void thread_set_texture_frame(void *data, const void *frame, + bool rgb32, unsigned width, unsigned height, float alpha) { thread_video_t *thr = (thread_video_t*)data; slock_lock(thr->frame.lock); - thr->rgui_texture = frame; + size_t required = width * height * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); + if (required > thr->texture.frame_cap) + { + thr->texture.frame = realloc(thr->texture.frame, required); + thr->texture.frame_cap = required; + } + + if (thr->texture.frame) + { + memcpy(thr->texture.frame, frame, required); + thr->texture.frame_updated = true; + thr->texture.rgb32 = rgb32; + thr->texture.width = width; + thr->texture.height = height; + thr->texture.alpha = alpha; + } + slock_unlock(thr->frame.lock); +} + +static void thread_set_texture_enable(void *data, bool state) +{ + thread_video_t *thr = (thread_video_t*)data; + + slock_lock(thr->frame.lock); + thr->texture.enable = state; slock_unlock(thr->frame.lock); } #endif @@ -648,7 +693,8 @@ static const video_poke_interface_t thread_poke = { thread_set_aspect_ratio, thread_apply_state_changes, #ifdef HAVE_RGUI - thread_set_rgui_texture, + thread_set_texture_frame, + thread_set_texture_enable, #endif }; diff --git a/gx/gx_video.c b/gx/gx_video.c index e93c87d394..9e4f58aaf9 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -918,7 +918,7 @@ static bool gx_frame(void *data, const void *frame, DCFlushRange(g_tex.data, height * (width << (gx->rgb32 ? 2 : 1))); } - if (gx->menu_data) + if (gx->menu_enable && gx->menu_data) { convert_texture16(gx->menu_data, menu_tex.data, RGUI_WIDTH, RGUI_HEIGHT, RGUI_WIDTH * 2); DCFlushRange(menu_tex.data, RGUI_WIDTH * RGUI_HEIGHT * 2); @@ -1019,12 +1019,24 @@ static bool gx_set_shader(void *data, enum rarch_shader_type type, const char *p return false; } -static void gx_set_rgui_texture(void *data, const void *frame) +static void gx_set_texture_frame(void *data, const void *frame, + bool rgb32, unsigned width, unsigned height, float alpha) { + (void)rgb32; + (void)width; + (void)height; + (void)alpha; + gx_video_t *gx = (gx_video_t*)data; gx->menu_data = (uint32_t*)frame; } +static void gx_set_texture_enable(void *data, bool enable) +{ + gx_video_t *gx = (gx_video_t*)data; + gx->menu_enable = enable; +} + static void gx_apply_state_changes(void *data) { gx_video_t *gx = (gx_video_t*)data; @@ -1042,7 +1054,8 @@ static const video_poke_interface_t gx_poke_interface = { NULL, gx_set_aspect_ratio, gx_apply_state_changes, - gx_set_rgui_texture, + gx_set_texture_frame, + gx_set_texture_enable, }; static void gx_get_poke_interface(void *data, const video_poke_interface_t **iface) diff --git a/gx/gx_video.h b/gx/gx_video.h index b541148119..12b6e950c3 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -25,6 +25,7 @@ typedef struct gx_video bool double_strike; bool rgb32; uint32_t *menu_data; // FIXME: Should be const uint16_t*. + bool menu_enable; rarch_viewport_t vp; unsigned scale; } gx_video_t;