From 843d07900221d4883e199f377de3d53d3f8d4a0f Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 16 Feb 2013 02:21:43 +0100 Subject: [PATCH 1/8] Begin adding threaded video driver wrapper. --- Makefile | 3 +- Makefile.win | 2 +- config.def.h | 3 + driver.c | 24 +++- driver.h | 2 + general.h | 1 + gfx/d3d9/d3d9.cpp | 9 +- gfx/gl.c | 3 +- gfx/sdl_gfx.c | 21 +-- gfx/thread_wrapper.c | 316 +++++++++++++++++++++++++++++++++++++++++++ gfx/thread_wrapper.h | 24 ++++ gfx/xvideo.c | 15 +- retroarch.cfg | 3 + settings.c | 2 + 14 files changed, 405 insertions(+), 23 deletions(-) create mode 100644 gfx/thread_wrapper.c create mode 100644 gfx/thread_wrapper.h diff --git a/Makefile b/Makefile index 7baff23a57..58212f2bec 100644 --- a/Makefile +++ b/Makefile @@ -77,9 +77,8 @@ ifneq ($(findstring Linux,$(OS)),) JOYCONFIG_OBJ += input/linuxraw_joypad.o endif -OBJ += autosave.o thread.o - ifeq ($(HAVE_THREADS), 1) + OBJ += autosave.o thread.o gfx/thread_wrapper.o ifeq ($(findstring Haiku,$(OS)),) LIBS += -lpthread endif diff --git a/Makefile.win b/Makefile.win index 79396f99bc..a038dece6a 100644 --- a/Makefile.win +++ b/Makefile.win @@ -99,7 +99,7 @@ ifeq ($(HAVE_SDL), 1) endif ifeq ($(HAVE_THREADS), 1) - OBJ += autosave.o thread.o + OBJ += autosave.o thread.o gfx/thread_wrapper.o DEFINES += -DHAVE_THREADS endif diff --git a/config.def.h b/config.def.h index 7a0cf21cac..779117199b 100644 --- a/config.def.h +++ b/config.def.h @@ -218,6 +218,9 @@ static const bool disable_composition = false; // Video VSYNC (recommended) static const bool vsync = true; +// Threaded video. Will possibly increase performance significantly at cost of worse synchronization and latency. +static const bool video_threaded = false; + // Smooths picture static const bool video_smooth = true; diff --git a/driver.c b/driver.c index 364ecba733..5db2e09af8 100644 --- a/driver.c +++ b/driver.c @@ -23,6 +23,7 @@ #include "compat/posix_string.h" #include "audio/utils.h" #include "audio/resampler.h" +#include "gfx/thread_wrapper.h" #ifdef HAVE_X11 #include "gfx/context/x11_common.h" @@ -492,6 +493,12 @@ static void compute_audio_buffer_statistics(void) static void compute_monitor_fps_statistics(void) { + if (g_settings.video.threaded) + { + RARCH_LOG("Monitor FPS estimation is disabled for threaded video.\n"); + return; + } + if (g_extern.measure_data.frame_time_samples_count < 2 * MEASURE_FRAME_TIME_SAMPLES_COUNT) { RARCH_LOG("Does not have enough samples for monitor refresh rate estimation. Requires to run for at least %u frames.\n", @@ -800,7 +807,22 @@ void init_video_input(void) video.rgb32 = g_extern.filter.active || (g_extern.system.pix_fmt == RETRO_PIXEL_FORMAT_XRGB8888); const input_driver_t *tmp = driver.input; - driver.video_data = video_init_func(&video, &driver.input, &driver.input_data); +#ifdef HAVE_THREADS + if (g_settings.video.threaded) + { + find_video_driver(); // Need to grab the "real" video driver interface on a reinit. + RARCH_LOG("Starting threaded video driver ...\n"); + if (!rarch_threaded_video_init(&driver.video, &driver.video_data, + &driver.input, &driver.input_data, + driver.video, &video)) + { + RARCH_ERR("Cannot open threaded video driver ... Exiting ...\n"); + rarch_fail(1, "init_video_input()"); + } + } + else +#endif + driver.video_data = video_init_func(&video, &driver.input, &driver.input_data); if (driver.video_data == NULL) { diff --git a/driver.h b/driver.h index 580999e379..59c06b63ee 100644 --- a/driver.h +++ b/driver.h @@ -280,6 +280,8 @@ typedef struct driver void *video_data; void *input_data; + bool threaded_video; + // Set if the respective handles are owned by RetroArch driver core. // Consoles upper logic will generally intialize the drivers before // the driver core initializes. It will then be up to upper logic diff --git a/general.h b/general.h index e6bfa575fe..4398447637 100644 --- a/general.h +++ b/general.h @@ -173,6 +173,7 @@ struct settings char filter_path[PATH_MAX]; enum rarch_shader_type shader_type; float refresh_rate; + bool threaded; bool render_to_texture; diff --git a/gfx/d3d9/d3d9.cpp b/gfx/d3d9/d3d9.cpp index 70efc7a69e..856838f6d3 100644 --- a/gfx/d3d9/d3d9.cpp +++ b/gfx/d3d9/d3d9.cpp @@ -1160,9 +1160,12 @@ static void *d3d9_init(const video_info_t *info, const input_driver_t **input, if (!vid) return nullptr; - void *dinput = input_dinput.init(); - *input = dinput ? &input_dinput : nullptr; - *input_data = dinput; + if (input && input_data) + { + void *dinput = input_dinput.init(); + *input = dinput ? &input_dinput : nullptr; + *input_data = dinput; + } return vid; } diff --git a/gfx/gl.c b/gfx/gl.c index 0ebd219329..ac3a6739b8 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1691,7 +1691,8 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl_init_textures(gl, video); gl_init_textures_data(gl); - context_input_driver_func(input, input_data); + if (input && input_data) + context_input_driver_func(input, input_data); #ifndef HAVE_RMENU // Comes too early for console - moved to gl_start diff --git a/gfx/sdl_gfx.c b/gfx/sdl_gfx.c index 0f30ad2778..2b2319af86 100644 --- a/gfx/sdl_gfx.c +++ b/gfx/sdl_gfx.c @@ -231,16 +231,19 @@ static void *sdl_gfx_init(const video_info_t *video, const input_driver_t **inpu sdl_gfx_set_handles(); - sdl_input = input_sdl.init(); - if (sdl_input) + if (input && input_data) { - *input = &input_sdl; - *input_data = sdl_input; - } - else - { - *input = NULL; - *input_data = NULL; + sdl_input = input_sdl.init(); + if (sdl_input) + { + *input = &input_sdl; + *input_data = sdl_input; + } + else + { + *input = NULL; + *input_data = NULL; + } } sdl_init_font(vid, g_settings.video.font_path, g_settings.video.font_size); diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c new file mode 100644 index 0000000000..6f5337b478 --- /dev/null +++ b/gfx/thread_wrapper.c @@ -0,0 +1,316 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - 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 . + */ + +#include "thread_wrapper.h" +#include "../thread.h" +#include "../general.h" +#include +#include +#include + +enum thread_cmd +{ + CMD_NONE = 0, + CMD_INIT, + CMD_SET_SHADER, + CMD_FREE, + CMD_SET_ROTATION, + CMD_VIEWPORT_INFO, + CMD_READ_VIEWPORT, + CMD_SET_NONBLOCK, + + CMD_DUMMY = INT_MAX +}; + +typedef struct thread_video +{ + slock_t *lock; + scond_t *cond_cmd; + scond_t *cond_thread; + sthread_t *thread; + + video_info_t info; + const video_driver_t *driver; + void *driver_data; + const input_driver_t **input; + void **input_data; + + bool alive; + bool focus; + + enum thread_cmd send_cmd; + enum thread_cmd reply_cmd; + union + { + bool b; + int i; + const char *str; + void *v; + } cmd_data; + + struct + { + slock_t *lock; + uint8_t *buffer; + unsigned width; + unsigned height; + unsigned pitch; + bool updated; + char msg[1024]; + } frame; + +} thread_video_t; + +static void *thread_init_never_call(const video_info_t *video, const input_driver_t **input, void **input_data) +{ + (void)video; + (void)input; + (void)input_data; + RARCH_ERR("Sanity check fail! Threaded mustn't be reinit.\n"); + abort(); + return NULL; +} + +static void thread_reply(thread_video_t *thr, enum thread_cmd cmd) +{ + slock_lock(thr->lock); + thr->reply_cmd = cmd; + thr->send_cmd = CMD_NONE; + scond_signal(thr->cond_cmd); + slock_unlock(thr->lock); +} + +static void thread_loop(void *data) +{ + thread_video_t *thr = (thread_video_t*)data; + + for (;;) + { + bool updated = false; + slock_lock(thr->lock); + while (thr->send_cmd == CMD_NONE && !thr->frame.updated) + scond_wait(thr->cond_thread, thr->lock); + if (thr->frame.updated) + updated = true; + slock_unlock(thr->lock); + + switch (thr->send_cmd) + { + case CMD_INIT: + //fprintf(stderr, "CMD_INIT\n"); + thr->driver_data = thr->driver->init(&thr->info, thr->input, thr->input_data); + thr->cmd_data.b = thr->driver_data; + thread_reply(thr, CMD_INIT); + break; + + case CMD_FREE: + //fprintf(stderr, "CMD_FREE\n"); + if (thr->driver_data) + thr->driver->free(thr->driver_data); + thr->driver_data = NULL; + thread_reply(thr, CMD_FREE); + return; + + case CMD_SET_NONBLOCK: + //fprintf(stderr, "CMD_SET_NONBLOCK\n"); + thr->driver->set_nonblock_state(thr->driver_data, thr->cmd_data.b); + thread_reply(thr, CMD_SET_NONBLOCK); + break; + + default: + //fprintf(stderr, "CMD unknown ...\n"); + thread_reply(thr, thr->send_cmd); + break; + } + + if (updated) + { + //fprintf(stderr, "RUN FRAME\n"); + slock_lock(thr->frame.lock); + bool ret = thr->driver->frame(thr->driver_data, + thr->frame.buffer, thr->frame.width, thr->frame.height, + thr->frame.pitch, *thr->frame.msg ? thr->frame.msg : NULL); + slock_unlock(thr->frame.lock); + + bool alive = ret && thr->driver->alive(thr->driver_data); + bool focus = ret && thr->driver->focus(thr->driver_data); + //fprintf(stderr, "Alive: %d, Focus: %d.\n", alive, focus); + + slock_lock(thr->lock); + thr->alive = alive; + thr->focus = focus; + thr->frame.updated = false; + slock_unlock(thr->lock); + } + } +} + +static void thread_send_cmd(thread_video_t *thr, enum thread_cmd cmd) +{ + slock_lock(thr->lock); + thr->send_cmd = cmd; + thr->reply_cmd = CMD_NONE; + scond_signal(thr->cond_thread); + slock_unlock(thr->lock); +} + +static void thread_wait_reply(thread_video_t *thr, enum thread_cmd cmd) +{ + slock_lock(thr->lock); + while (cmd != thr->reply_cmd) + scond_wait(thr->cond_cmd, thr->lock); + slock_unlock(thr->lock); +} + +static bool thread_alive(void *data) +{ + thread_video_t *thr = (thread_video_t*)data; + slock_lock(thr->lock); + bool ret = thr->alive; + slock_unlock(thr->lock); + return ret; +} + +static bool thread_focus(void *data) +{ + thread_video_t *thr = (thread_video_t*)data; + slock_lock(thr->lock); + bool ret = thr->focus; + slock_unlock(thr->lock); + return ret; +} + +static bool thread_frame(void *data, const void *frame_, + unsigned width, unsigned height, unsigned pitch, const char *msg) +{ + if (!frame_) + return true; + + thread_video_t *thr = (thread_video_t*)data; + unsigned copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); + + const uint8_t *src = (const uint8_t*)frame_; + uint8_t *dst = thr->frame.buffer; + + slock_lock(thr->lock); + // Drop frame if updated flag is still set, as thread is still working on last frame. + if (!thr->frame.updated) + { + slock_lock(thr->frame.lock); + for (unsigned h = 0; h < height; h++, src += pitch, dst += copy_stride) + memcpy(dst, src, copy_stride); + thr->frame.updated = true; + scond_signal(thr->cond_thread); + thr->frame.width = width; + thr->frame.height = height; + thr->frame.pitch = copy_stride; + + if (msg) + strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg)); + else + *thr->frame.msg = '\0'; + + slock_unlock(thr->frame.lock); + } + slock_unlock(thr->lock); + + return true; +} + +static void thread_set_nonblock_state(void *data, bool state) +{ + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.b = state; + thread_send_cmd(thr, CMD_SET_NONBLOCK); + thread_wait_reply(thr, CMD_SET_NONBLOCK); +} + +static bool thread_init(thread_video_t *thr, const video_info_t *info, const input_driver_t **input, + void **input_data) +{ + thr->lock = slock_new(); + thr->frame.lock = slock_new(); + thr->cond_cmd = scond_new(); + thr->cond_thread = scond_new(); + thr->input = input; + thr->input_data = input_data; + thr->info = *info; + thr->alive = true; + thr->focus = true; + + thr->frame.buffer = (uint8_t*)malloc((info->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)) * + info->input_scale * info->input_scale * RARCH_SCALE_BASE * RARCH_SCALE_BASE); + if (!thr->frame.buffer) + return false; + + thr->thread = sthread_create(thread_loop, thr); + if (!thr->thread) + return false; + thread_send_cmd(thr, CMD_INIT); + thread_wait_reply(thr, CMD_INIT); + return thr->cmd_data.b; +} + +static void thread_free(void *data) +{ + thread_video_t *thr = (thread_video_t*)data; + if (!thr) + return; + + thread_send_cmd(thr, CMD_FREE); + thread_wait_reply(thr, CMD_FREE); + sthread_join(thr->thread); + + free(thr->frame.buffer); + slock_free(thr->frame.lock); + slock_free(thr->lock); + scond_free(thr->cond_cmd); + scond_free(thr->cond_thread); + + free(thr); +} + +static const video_driver_t video_thread = { + thread_init_never_call, // Should never be called directly. + thread_frame, + thread_set_nonblock_state, + thread_alive, + thread_focus, + NULL, // set_shader + thread_free, + "Thread wrapper", + NULL, // set_rotation + NULL, // viewport_info + NULL, // read_viewport +#ifdef HAVE_OVERLAY + NULL, // get_overlay_interface +#endif +}; + +bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_data, + const input_driver_t **input, void **input_data, + const video_driver_t *driver, const video_info_t *info) +{ + thread_video_t *thr = (thread_video_t*)calloc(1, sizeof(*thr)); + if (!thr) + return false; + + thr->driver = driver; + *out_driver = &video_thread; + *out_data = thr; + return thread_init(thr, info, input, input_data); +} + + diff --git a/gfx/thread_wrapper.h b/gfx/thread_wrapper.h new file mode 100644 index 0000000000..6019803525 --- /dev/null +++ b/gfx/thread_wrapper.h @@ -0,0 +1,24 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - 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 . + */ + +#include "../driver.h" +#include "../boolean.h" + +// Starts a video driver in a new thread. +// Access to video driver will be mediated through this driver. +bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_data, + const input_driver_t **input, void **input_data, + const video_driver_t *driver, const video_info_t *info); + diff --git a/gfx/xvideo.c b/gfx/xvideo.c index a4db814332..ded1a37cd7 100644 --- a/gfx/xvideo.c +++ b/gfx/xvideo.c @@ -464,14 +464,17 @@ static void *xv_init(const video_info_t *video, const input_driver_t **input, vo driver.video_display = (uintptr_t)xv->display; driver.video_window = (Window)xv->window; - xinput = input_x.init(); - if (xinput) + if (input && input_data) { - *input = &input_x; - *input_data = xinput; + xinput = input_x.init(); + if (xinput) + { + *input = &input_x; + *input_data = xinput; + } + else + *input = NULL; } - else - *input = NULL; init_yuv_tables(xv); xv_init_font(xv, g_settings.video.font_path, g_settings.video.font_size); diff --git a/retroarch.cfg b/retroarch.cfg index 2237d20e35..22248ce2cf 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -65,6 +65,9 @@ # Video vsync. # video_vsync = true +# Use threaded video driver. Using this might improve performance at possible cost of latency and more video stuttering. +# video_threaded = false + # Smoothens picture with bilinear filtering. Should be disabled if using pixel shaders. # video_smooth = true diff --git a/settings.c b/settings.c index d6a798f20f..217924c87d 100644 --- a/settings.c +++ b/settings.c @@ -159,6 +159,7 @@ void config_set_defaults(void) g_settings.video.fullscreen_y = fullscreen_y; g_settings.video.disable_composition = disable_composition; g_settings.video.vsync = vsync; + g_settings.video.threaded = video_threaded; g_settings.video.smooth = video_smooth; g_settings.video.force_aspect = force_aspect; g_settings.video.scale_integer = scale_integer; @@ -438,6 +439,7 @@ bool config_load_file(const char *path) CONFIG_GET_INT(video.monitor_index, "video_monitor_index"); CONFIG_GET_BOOL(video.disable_composition, "video_disable_composition"); CONFIG_GET_BOOL(video.vsync, "video_vsync"); + CONFIG_GET_BOOL(video.threaded, "video_threaded"); CONFIG_GET_BOOL(video.smooth, "video_smooth"); CONFIG_GET_BOOL(video.force_aspect, "video_force_aspect"); CONFIG_GET_BOOL(video.scale_integer, "video_scale_integer"); From 02afa02f568f6acebc0fef13fa1bea0064970fe7 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 16 Feb 2013 11:21:18 +0100 Subject: [PATCH 2/8] Add more interfaces to threaded driver. --- gfx/thread_wrapper.c | 132 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 120 insertions(+), 12 deletions(-) diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 6f5337b478..851434c1dd 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -16,6 +16,7 @@ #include "thread_wrapper.h" #include "../thread.h" #include "../general.h" +#include "../performance.h" #include #include #include @@ -27,7 +28,6 @@ enum thread_cmd CMD_SET_SHADER, CMD_FREE, CMD_SET_ROTATION, - CMD_VIEWPORT_INFO, CMD_READ_VIEWPORT, CMD_SET_NONBLOCK, @@ -58,8 +58,18 @@ typedef struct thread_video int i; const char *str; void *v; + + struct + { + enum rarch_shader_type type; + const char *path; + unsigned index; + } set_shader; } cmd_data; + struct rarch_viewport vp; + struct rarch_viewport read_vp; // Last viewport reported to caller. + struct { slock_t *lock; @@ -71,6 +81,8 @@ typedef struct thread_video char msg[1024]; } frame; + video_driver_t video_thread; + } thread_video_t; static void *thread_init_never_call(const video_info_t *video, const input_driver_t **input, void **input_data) @@ -109,14 +121,13 @@ static void thread_loop(void *data) switch (thr->send_cmd) { case CMD_INIT: - //fprintf(stderr, "CMD_INIT\n"); thr->driver_data = thr->driver->init(&thr->info, thr->input, thr->input_data); thr->cmd_data.b = thr->driver_data; + thr->driver->viewport_info(thr->driver_data, &thr->vp); thread_reply(thr, CMD_INIT); break; case CMD_FREE: - //fprintf(stderr, "CMD_FREE\n"); if (thr->driver_data) thr->driver->free(thr->driver_data); thr->driver_data = NULL; @@ -124,20 +135,50 @@ static void thread_loop(void *data) return; case CMD_SET_NONBLOCK: - //fprintf(stderr, "CMD_SET_NONBLOCK\n"); thr->driver->set_nonblock_state(thr->driver_data, thr->cmd_data.b); thread_reply(thr, CMD_SET_NONBLOCK); break; + case CMD_SET_ROTATION: + thr->driver->set_rotation(thr->driver_data, thr->cmd_data.i); + thread_reply(thr, CMD_SET_ROTATION); + break; + + case CMD_READ_VIEWPORT: + { + struct rarch_viewport vp = {0}; + thr->driver->viewport_info(thr->driver_data, &vp); + if (memcmp(&vp, &thr->read_vp, sizeof(vp)) == 0) // We can read safely + { + thr->cmd_data.b = thr->driver->read_viewport(thr->driver_data, (uint8_t*)thr->cmd_data.v); + thread_reply(thr, CMD_READ_VIEWPORT); + } + else // Viewport dimensions changed right after main thread read the async value. Cannot read safely. + { + thr->cmd_data.b = false; + thread_reply(thr, CMD_READ_VIEWPORT); + } + break; + } + + case CMD_SET_SHADER: + { + bool ret = thr->driver->set_shader(thr->driver_data, + thr->cmd_data.set_shader.type, + thr->cmd_data.set_shader.path, + thr->cmd_data.set_shader.index); + thr->cmd_data.b = ret; + thread_reply(thr, CMD_SET_SHADER); + break; + } + default: - //fprintf(stderr, "CMD unknown ...\n"); thread_reply(thr, thr->send_cmd); break; } if (updated) { - //fprintf(stderr, "RUN FRAME\n"); slock_lock(thr->frame.lock); bool ret = thr->driver->frame(thr->driver_data, thr->frame.buffer, thr->frame.width, thr->frame.height, @@ -146,12 +187,15 @@ static void thread_loop(void *data) bool alive = ret && thr->driver->alive(thr->driver_data); bool focus = ret && thr->driver->focus(thr->driver_data); - //fprintf(stderr, "Alive: %d, Focus: %d.\n", alive, focus); + + struct rarch_viewport vp = {0}; + thr->driver->viewport_info(thr->driver_data, &vp); slock_lock(thr->lock); thr->alive = alive; thr->focus = focus; thr->frame.updated = false; + thr->vp = vp; slock_unlock(thr->lock); } } @@ -198,6 +242,9 @@ static bool thread_frame(void *data, const void *frame_, if (!frame_) return true; + RARCH_PERFORMANCE_INIT(thread_frame); + RARCH_PERFORMANCE_START(thread_frame); + thread_video_t *thr = (thread_video_t*)data; unsigned copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); @@ -226,6 +273,8 @@ static bool thread_frame(void *data, const void *frame_, } slock_unlock(thr->lock); + RARCH_PERFORMANCE_STOP(thread_frame); + return true; } @@ -263,6 +312,47 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info, const inp return thr->cmd_data.b; } +static bool thread_set_shader(void *data, enum rarch_shader_type type, const char *path, unsigned index) +{ + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.set_shader.type = type; + thr->cmd_data.set_shader.path = path; + thr->cmd_data.set_shader.index = index; + thread_send_cmd(thr, CMD_SET_SHADER); + thread_wait_reply(thr, CMD_SET_SHADER); + return thr->cmd_data.b; +} + +static void thread_set_rotation(void *data, unsigned rotation) +{ + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.i = rotation; + thread_send_cmd(thr, CMD_SET_ROTATION); + thread_wait_reply(thr, CMD_SET_ROTATION); +} + +// This value is set async as stalling on the video driver for every query is too slow. +// This means this value might not be correct, so viewport reads are not supported for now. +static void thread_viewport_info(void *data, struct rarch_viewport *vp) +{ + thread_video_t *thr = (thread_video_t*)data; + slock_lock(thr->lock); + *vp = thr->vp; + + // Explicitly mem-copied so we can use memcmp correctly later. + memcpy(&thr->read_vp, &thr->vp, sizeof(thr->vp)); + slock_unlock(thr->lock); +} + +static bool thread_read_viewport(void *data, uint8_t *buffer) +{ + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.v = buffer; + thread_send_cmd(thr, CMD_READ_VIEWPORT); + thread_wait_reply(thr, CMD_READ_VIEWPORT); + return thr->cmd_data.b; +} + static void thread_free(void *data) { thread_video_t *thr = (thread_video_t*)data; @@ -288,17 +378,33 @@ static const video_driver_t video_thread = { thread_set_nonblock_state, thread_alive, thread_focus, - NULL, // set_shader + thread_set_shader, thread_free, "Thread wrapper", - NULL, // set_rotation - NULL, // viewport_info - NULL, // read_viewport + thread_set_rotation, + thread_viewport_info, + thread_read_viewport, #ifdef HAVE_OVERLAY NULL, // get_overlay_interface #endif }; +static void thread_set_callbacks(thread_video_t *thr, const video_driver_t *driver) +{ + thr->video_thread = video_thread; + // Disable optional features if not present. + if (!driver->read_viewport) + thr->video_thread.read_viewport = NULL; + if (!driver->set_rotation) + thr->video_thread.set_rotation = NULL; + if (!driver->set_shader) + thr->video_thread.set_shader = NULL; +#ifdef HAVE_OVERLAY + if (!driver->overlay_interface) + thr->video_thread.overlay_interface = NULL; +#endif +} + bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_data, const input_driver_t **input, void **input_data, const video_driver_t *driver, const video_info_t *info) @@ -307,8 +413,10 @@ bool rarch_threaded_video_init(const video_driver_t **out_driver, void **out_dat if (!thr) return false; + thread_set_callbacks(thr, driver); + thr->driver = driver; - *out_driver = &video_thread; + *out_driver = &thr->video_thread; *out_data = thr; return thread_init(thr, info, input, input_data); } From cfd0984d92f9d40f47fbb63151b65d3e859b9b3a Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 16 Feb 2013 11:44:15 +0100 Subject: [PATCH 3/8] Start adding overlay interface. --- gfx/thread_wrapper.c | 87 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 851434c1dd..4562784a5f 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -27,6 +27,7 @@ enum thread_cmd CMD_INIT, CMD_SET_SHADER, CMD_FREE, + CMD_ALIVE, // Blocking alive check. Used when paused. CMD_SET_ROTATION, CMD_READ_VIEWPORT, CMD_SET_NONBLOCK, @@ -172,6 +173,11 @@ static void thread_loop(void *data) break; } + case CMD_ALIVE: + thr->cmd_data.b = thr->driver->alive(thr->driver_data); + thread_reply(thr, CMD_ALIVE); + break; + default: thread_reply(thr, thr->send_cmd); break; @@ -221,10 +227,19 @@ static void thread_wait_reply(thread_video_t *thr, enum thread_cmd cmd) static bool thread_alive(void *data) { thread_video_t *thr = (thread_video_t*)data; - slock_lock(thr->lock); - bool ret = thr->alive; - slock_unlock(thr->lock); - return ret; + if (g_extern.is_paused) + { + thread_send_cmd(thr, CMD_ALIVE); + thread_wait_reply(thr, CMD_ALIVE); + return thr->cmd_data.b; + } + else + { + slock_lock(thr->lock); + bool ret = thr->alive; + slock_unlock(thr->lock); + return ret; + } } static bool thread_focus(void *data) @@ -372,6 +387,68 @@ static void thread_free(void *data) free(thr); } +#ifdef HAVE_OVERLAY +static void thread_overlay_enable(void *data, bool state) +{ + (void)data; + (void)state; +} + +static bool thread_overlay_load(void *data, const uint32_t *image, unsigned width, unsigned height) +{ + (void)data; + (void)image; + (void)width; + (void)height; + return false; +} + +static void thread_overlay_tex_geom(void *data, float x, float y, float w, float h) +{ + (void)data; + (void)x; + (void)y; + (void)w; + (void)h; +} + +static void thread_overlay_vertex_geom(void *data, float x, float y, float w, float h) +{ + (void)data; + (void)x; + (void)y; + (void)w; + (void)h; +} + +static void thread_overlay_full_screen(void *data, bool enable) +{ + (void)data; + (void)enable; +} + +static void thread_overlay_set_alpha(void *data, float mod) +{ + (void)data; + (void)mod; +} + +static const video_overlay_interface_t thread_overlay = { + thread_overlay_enable, + thread_overlay_load, + thread_overlay_tex_geom, + thread_overlay_vertex_geom, + thread_overlay_full_screen, + thread_overlay_set_alpha, +}; + +static void thread_get_overlay_interface(void *data, const video_overlay_interface_t **iface) +{ + (void)data; + *iface = &thread_overlay; +} +#endif + static const video_driver_t video_thread = { thread_init_never_call, // Should never be called directly. thread_frame, @@ -385,7 +462,7 @@ static const video_driver_t video_thread = { thread_viewport_info, thread_read_viewport, #ifdef HAVE_OVERLAY - NULL, // get_overlay_interface + thread_get_overlay_interface, // get_overlay_interface #endif }; From 2cd60e0551de1adc78c8967e8db4a2d83e510f21 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 16 Feb 2013 12:05:15 +0100 Subject: [PATCH 4/8] Overlay works in thread_video. --- gfx/thread_wrapper.c | 123 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 101 insertions(+), 22 deletions(-) diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 4562784a5f..67efe230b3 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -32,6 +32,15 @@ enum thread_cmd CMD_READ_VIEWPORT, CMD_SET_NONBLOCK, +#ifdef HAVE_OVERLAY + CMD_OVERLAY_ENABLE, + CMD_OVERLAY_LOAD, + CMD_OVERLAY_TEX_GEOM, + CMD_OVERLAY_VERTEX_GEOM, + CMD_OVERLAY_FULL_SCREEN, + CMD_OVERLAY_SET_ALPHA, +#endif + CMD_DUMMY = INT_MAX }; @@ -44,6 +53,7 @@ typedef struct thread_video video_info_t info; const video_driver_t *driver; + const video_overlay_interface_t *overlay; void *driver_data; const input_driver_t **input; void **input_data; @@ -57,6 +67,7 @@ typedef struct thread_video { bool b; int i; + float f; const char *str; void *v; @@ -66,6 +77,18 @@ typedef struct thread_video const char *path; unsigned index; } set_shader; + + struct + { + float x, y, w, h; + } rect; + + struct + { + const uint32_t *data; + unsigned width; + unsigned height; + } image; } cmd_data; struct rarch_viewport vp; @@ -178,6 +201,49 @@ static void thread_loop(void *data) thread_reply(thr, CMD_ALIVE); break; +#ifdef HAVE_OVERLAY + case CMD_OVERLAY_ENABLE: + thr->overlay->enable(thr->driver_data, thr->cmd_data.b); + thread_reply(thr, CMD_OVERLAY_ENABLE); + break; + + case CMD_OVERLAY_LOAD: + thr->cmd_data.b = thr->overlay->load(thr->driver_data, + thr->cmd_data.image.data, + thr->cmd_data.image.width, + thr->cmd_data.image.height); + thread_reply(thr, CMD_OVERLAY_LOAD); + break; + + case CMD_OVERLAY_TEX_GEOM: + thr->overlay->tex_geom(thr->driver_data, + thr->cmd_data.rect.x, + thr->cmd_data.rect.y, + thr->cmd_data.rect.w, + thr->cmd_data.rect.h); + thread_reply(thr, CMD_OVERLAY_TEX_GEOM); + break; + + case CMD_OVERLAY_VERTEX_GEOM: + thr->overlay->vertex_geom(thr->driver_data, + thr->cmd_data.rect.x, + thr->cmd_data.rect.y, + thr->cmd_data.rect.w, + thr->cmd_data.rect.h); + thread_reply(thr, CMD_OVERLAY_VERTEX_GEOM); + break; + + case CMD_OVERLAY_FULL_SCREEN: + thr->overlay->full_screen(thr->driver_data, thr->cmd_data.b); + thread_reply(thr, CMD_OVERLAY_FULL_SCREEN); + break; + + case CMD_OVERLAY_SET_ALPHA: + thr->overlay->set_alpha(thr->driver_data, thr->cmd_data.f); + thread_reply(thr, CMD_OVERLAY_SET_ALPHA); + break; +#endif + default: thread_reply(thr, thr->send_cmd); break; @@ -390,47 +456,59 @@ static void thread_free(void *data) #ifdef HAVE_OVERLAY static void thread_overlay_enable(void *data, bool state) { - (void)data; - (void)state; + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.b = state; + thread_send_cmd(thr, CMD_OVERLAY_ENABLE); + thread_wait_reply(thr, CMD_OVERLAY_ENABLE); } static bool thread_overlay_load(void *data, const uint32_t *image, unsigned width, unsigned height) { - (void)data; - (void)image; - (void)width; - (void)height; - return false; + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.image.data = image; + thr->cmd_data.image.width = width; + thr->cmd_data.image.height = height; + thread_send_cmd(thr, CMD_OVERLAY_LOAD); + thread_wait_reply(thr, CMD_OVERLAY_LOAD); + return thr->cmd_data.b; } static void thread_overlay_tex_geom(void *data, float x, float y, float w, float h) { - (void)data; - (void)x; - (void)y; - (void)w; - (void)h; + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.rect.x = x; + thr->cmd_data.rect.y = y; + thr->cmd_data.rect.w = w; + thr->cmd_data.rect.h = h; + thread_send_cmd(thr, CMD_OVERLAY_TEX_GEOM); + thread_wait_reply(thr, CMD_OVERLAY_TEX_GEOM); } static void thread_overlay_vertex_geom(void *data, float x, float y, float w, float h) { - (void)data; - (void)x; - (void)y; - (void)w; - (void)h; + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.rect.x = x; + thr->cmd_data.rect.y = y; + thr->cmd_data.rect.w = w; + thr->cmd_data.rect.h = h; + thread_send_cmd(thr, CMD_OVERLAY_VERTEX_GEOM); + thread_wait_reply(thr, CMD_OVERLAY_VERTEX_GEOM); } static void thread_overlay_full_screen(void *data, bool enable) { - (void)data; - (void)enable; + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.b = enable; + thread_send_cmd(thr, CMD_OVERLAY_FULL_SCREEN); + thread_wait_reply(thr, CMD_OVERLAY_FULL_SCREEN); } static void thread_overlay_set_alpha(void *data, float mod) { - (void)data; - (void)mod; + thread_video_t *thr = (thread_video_t*)data; + thr->cmd_data.f = mod; + thread_send_cmd(thr, CMD_OVERLAY_SET_ALPHA); + thread_wait_reply(thr, CMD_OVERLAY_SET_ALPHA); } static const video_overlay_interface_t thread_overlay = { @@ -444,8 +522,9 @@ static const video_overlay_interface_t thread_overlay = { static void thread_get_overlay_interface(void *data, const video_overlay_interface_t **iface) { - (void)data; + thread_video_t *thr = (thread_video_t*)data; *iface = &thread_overlay; + thr->driver->overlay_interface(thr->driver_data, &thr->overlay); } #endif From 76bf41188aa3357f085f3e213e1097eb27e5edf1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 16 Feb 2013 12:30:26 +0100 Subject: [PATCH 5/8] Add video_threaded option to Android. --- android/native/jni/Android.mk | 3 +-- android/phoenix/res/xml/prefs.xml | 6 +++++- .../src/org/retroarch/browser/RetroArch.java | 1 + audio/resampler.h | 6 ++---- audio/sinc.c | 19 ++++++++++--------- console/griffin/griffin.c | 5 ++++- driver.c | 2 +- driver_funcs.h | 2 +- general.h | 2 +- gfx/context/androidegl_ctx.c | 6 ++++++ gfx/thread_wrapper.c | 11 ++++++++--- record/ffemu.c | 2 +- retroarch.c | 2 +- 13 files changed, 42 insertions(+), 25 deletions(-) diff --git a/android/native/jni/Android.mk b/android/native/jni/Android.mk index 25b1a45b9e..d14440b85f 100644 --- a/android/native/jni/Android.mk +++ b/android/native/jni/Android.mk @@ -6,7 +6,6 @@ HAVE_SINC := 1 HAVE_LOGGER := 1 include $(CLEAR_VARS) - ifeq ($(TARGET_ARCH),arm) LOCAL_CFLAGS += -DANDROID_ARM -marm LOCAL_ARM_MODE := arm @@ -52,7 +51,7 @@ ifeq ($(PERF_TEST), 1) LOCAL_CFLAGS += -DPERF_TEST endif -LOCAL_CFLAGS += -Wall -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DWANT_RZLIB -DHAVE_ZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREAD -D__LIBRETRO__ -DRARCH_PERFORMANCE_MODE -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -std=gnu99 -I../../../deps/rzlib +LOCAL_CFLAGS += -Wall -pthread -Wno-unused-function -O3 -fno-stack-protector -funroll-loops -DNDEBUG -DHAVE_GRIFFIN -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_FBO -DHAVE_OVERLAY -DHAVE_OPENGLES -DHAVE_VID_CONTEXT -DHAVE_OPENGLES2 -DGLSL_DEBUG -DHAVE_GLSL -DWANT_RZLIB -DHAVE_ZLIB -DINLINE=inline -DLSB_FIRST -DHAVE_THREADS -D__LIBRETRO__ -DRARCH_PERFORMANCE_MODE -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -std=gnu99 -I../../../deps/rzlib LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL -lGLESv2 $(LOGGER_LDLIBS) -ldl diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 8908a94155..521745440a 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -81,12 +81,16 @@ android:title="Aspect ratio" /> + - diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index de137fba09..83475fe87b 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -371,6 +371,7 @@ public class RetroArch extends Activity implements config.setInt("input_autodetect_icade_profile_pad4", prefs.getInt("input_autodetect_icade_profile_pad4", 0)); config.setDouble("video_refresh_rate", getRefreshRate()); + config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true)); String aspect = prefs.getString("video_aspect_ratio", "auto"); if (aspect.equals("full")) { diff --git a/audio/resampler.h b/audio/resampler.h index 981c44f541..c5f803e8d7 100644 --- a/audio/resampler.h +++ b/audio/resampler.h @@ -31,12 +31,10 @@ #define M_PI 3.14159265358979323846264338327 #endif -typedef float sample_t; - struct resampler_data { - const sample_t *data_in; - sample_t *data_out; + const float *data_in; + float *data_out; size_t input_frames; size_t output_frames; diff --git a/audio/sinc.c b/audio/sinc.c index 483e148a73..937f985ca9 100644 --- a/audio/sinc.c +++ b/audio/sinc.c @@ -104,9 +104,9 @@ typedef struct rarch_sinc_resampler { - sample_t *phase_table; - sample_t *buffer_l; - sample_t *buffer_r; + float *phase_table; + float *buffer_l; + float *buffer_r; unsigned taps; @@ -115,7 +115,7 @@ typedef struct rarch_sinc_resampler // A buffer for phase_table, buffer_l and buffer_r are created in a single calloc(). // Ensure that we get as good cache locality as we can hope for. - sample_t *main_buffer; + float *main_buffer; } rarch_sinc_resampler_t; static inline double sinc(double val) @@ -389,9 +389,10 @@ static void process_sinc_neon(rarch_sinc_resampler_t *resamp, float *out_buffer) const float *buffer_r = resamp->buffer_r + resamp->ptr; unsigned phase = resamp->time >> SUBPHASE_BITS; - const float *phase_table = resamp->phase_table[phase]; + unsigned taps = resamp->taps; + const float *phase_table = resamp->phase_table + phase * taps; - process_sinc_neon_asm(out_buffer, buffer_l, buffer_r, phase_table, resamp->taps); + process_sinc_neon_asm(out_buffer, buffer_l, buffer_r, phase_table, taps); } #else // Plain ol' C99 #define process_sinc_func process_sinc_C @@ -403,8 +404,8 @@ static void resampler_sinc_process(void *re_, struct resampler_data *data) uint32_t ratio = PHASES / data->ratio; - const sample_t *input = data->data_in; - sample_t *output = data->data_out; + const float *input = data->data_in; + float *output = data->data_out; size_t frames = data->input_frames; size_t out_frames = 0; @@ -475,7 +476,7 @@ static void *resampler_sinc_new(double bandwidth_mod) #endif size_t elems = phase_elems + 4 * re->taps; - re->main_buffer = (sample_t*)aligned_alloc__(128, sizeof(sample_t) * elems); + re->main_buffer = (float*)aligned_alloc__(128, sizeof(float) * elems); if (!re->main_buffer) goto error; diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index 950d609075..c75823d96b 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -377,15 +377,18 @@ RETROARCH /*============================================================ THREAD ============================================================ */ +// This is supposed to be HAVE_THREADS. #if defined(HAVE_THREAD) && defined(XENON) #include "../../thread/xenon_sdl_threads.c" -#elif defined(HAVE_THREAD) +#elif defined(HAVE_THREADS) #include "../../thread.c" +#include "../../gfx/thread_wrapper.c" #ifdef ANDROID #include "../../autosave.c" #endif #endif + /*============================================================ NETPLAY ============================================================ */ diff --git a/driver.c b/driver.c index 5db2e09af8..083b7a86e8 100644 --- a/driver.c +++ b/driver.c @@ -424,7 +424,7 @@ void init_audio(void) g_extern.audio_data.data_ptr = 0; rarch_assert(g_settings.audio.out_rate < g_settings.audio.in_rate * AUDIO_MAX_RATIO); - rarch_assert(g_extern.audio_data.outsamples = (sample_t*)malloc(outsamples_max * sizeof(sample_t))); + rarch_assert(g_extern.audio_data.outsamples = (float*)malloc(outsamples_max * sizeof(float))); if (g_extern.audio_active && g_settings.audio.rate_control) { diff --git a/driver_funcs.h b/driver_funcs.h index dd2461e31f..d6f776e679 100644 --- a/driver_funcs.h +++ b/driver_funcs.h @@ -18,7 +18,7 @@ #ifndef _RARCH_DRIVER_FUNCS_H #define _RARCH_DRIVER_FUNCS_H -#if !defined(HAVE_GRIFFIN) /* Normal */ +#if !defined(HAVE_GRIFFIN) || defined(ANDROID) /* Normal */ #define audio_init_func(device, rate, latency) driver.audio->init(device, rate, latency) #define audio_write_func(buf, size) driver.audio->write(driver.audio_data, buf, size) diff --git a/general.h b/general.h index 4398447637..ac621b62b0 100644 --- a/general.h +++ b/general.h @@ -397,7 +397,7 @@ struct global bool use_float; bool mute; - sample_t *outsamples; + float *outsamples; int16_t *conv_outsamples; int16_t *rewind_buf; diff --git a/gfx/context/androidegl_ctx.c b/gfx/context/androidegl_ctx.c index ba775cff8c..ce0e76633d 100644 --- a/gfx/context/androidegl_ctx.c +++ b/gfx/context/androidegl_ctx.c @@ -15,10 +15,12 @@ */ #include "../../driver.h" +#include "../../general.h" #include "../gfx_common.h" #include "../gl_common.h" #include /* Requires NDK r5 or newer */ +#include #include "../../frontend/frontend_android.h" #include "../image.h" @@ -148,6 +150,10 @@ static bool gfx_ctx_init(void) goto error; } + ALooper *looper = ALooper_forThread(); + if (!looper) + ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + return true; error: diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 67efe230b3..33845b8171 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -340,7 +340,6 @@ static bool thread_frame(void *data, const void *frame_, for (unsigned h = 0; h < height; h++, src += pitch, dst += copy_stride) memcpy(dst, src, copy_stride); thr->frame.updated = true; - scond_signal(thr->cond_thread); thr->frame.width = width; thr->frame.height = height; thr->frame.pitch = copy_stride; @@ -350,6 +349,7 @@ static bool thread_frame(void *data, const void *frame_, else *thr->frame.msg = '\0'; + scond_signal(thr->cond_thread); slock_unlock(thr->frame.lock); } slock_unlock(thr->lock); @@ -380,16 +380,21 @@ static bool thread_init(thread_video_t *thr, const video_info_t *info, const inp thr->alive = true; thr->focus = true; - thr->frame.buffer = (uint8_t*)malloc((info->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)) * - info->input_scale * info->input_scale * RARCH_SCALE_BASE * RARCH_SCALE_BASE); + size_t max_size = info->input_scale * RARCH_SCALE_BASE; + max_size *= max_size; + max_size *= info->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); + thr->frame.buffer = (uint8_t*)malloc(max_size); if (!thr->frame.buffer) return false; + memset(thr->frame.buffer, 0x80, max_size); + thr->thread = sthread_create(thread_loop, thr); if (!thr->thread) return false; thread_send_cmd(thr, CMD_INIT); thread_wait_reply(thr, CMD_INIT); + return thr->cmd_data.b; } diff --git a/record/ffemu.c b/record/ffemu.c index a7ffffe4ff..3b81a33410 100644 --- a/record/ffemu.c +++ b/record/ffemu.c @@ -1023,7 +1023,7 @@ static void ffemu_audio_resample(ffemu_t *handle, struct ffemu_audio_data *data) { // It's always two channels ... struct resampler_data info = {0}; - info.data_in = (const sample_t*)data->data; + info.data_in = (const float*)data->data; info.data_out = handle->audio.resample_out; info.input_frames = data->frames; info.ratio = handle->audio.ratio; diff --git a/retroarch.c b/retroarch.c index 01e52328d5..333513e76a 100644 --- a/retroarch.c +++ b/retroarch.c @@ -366,7 +366,7 @@ static bool audio_flush(const int16_t *data, size_t samples) if (!g_extern.audio_active) return false; - const sample_t *output_data = NULL; + const float *output_data = NULL; unsigned output_frames = 0; struct resampler_data src_data = {0}; From 351d5d268289594eaa3f3eb803b63e1a1253ea87 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 17 Feb 2013 00:45:30 +0100 Subject: [PATCH 6/8] Clarify in alert a bit. Make threaded mode non-default. --- android/phoenix/res/xml/prefs.xml | 2 +- android/phoenix/src/org/retroarch/browser/RetroArch.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index 521745440a..cb4a203e8f 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -82,7 +82,7 @@ diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index 83475fe87b..e6d62be7f6 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -299,7 +299,7 @@ public class RetroArch extends Activity implements prefs.edit().putBoolean("first_time_refreshrate_calculate", true).commit(); AlertDialog.Builder alert = new AlertDialog.Builder(this) .setTitle("Calculate Refresh Rate") - .setMessage("It is highly recommended you run the refresh rate calibration test before you use RetroArch. Do you want to run it now?\n\nIf you choose No, you can run it at any time in the video preferences.") + .setMessage("It is highly recommended you run the refresh rate calibration test before you use RetroArch. Do you want to run it now?\n\nIf you choose No, you can run it at any time in the video preferences.\n\nIf you get performance problems even after calibration, please try threaded video driver in video preferences.") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { From 5840fa8fb9db220d7e387d629818c6adaee1bc5b Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 17 Feb 2013 13:32:34 +0100 Subject: [PATCH 7/8] Fix so that threaded video is not enabled by default. --- android/phoenix/src/org/retroarch/browser/RetroArch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index a9c981dfed..ad360f0da7 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -371,7 +371,7 @@ public class RetroArch extends Activity implements config.setInt("input_autodetect_icade_profile_pad4", prefs.getInt("input_autodetect_icade_profile_pad4", 0)); config.setDouble("video_refresh_rate", getRefreshRate()); - config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true)); + config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", false)); String aspect = prefs.getString("video_aspect_ratio", "auto"); if (aspect.equals("full")) { From 4b97052f8cfc3a714aa54c2bf923febeb62362e1 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 17 Feb 2013 15:55:30 +0100 Subject: [PATCH 8/8] Fix threaded driver build on Win32. --- gfx/thread_wrapper.c | 2 ++ msvc/msvc-2010/RetroArch-msvc2010.vcxproj | 10 ++++++---- msvc/msvc-2010/RetroArch-msvc2010.vcxproj.filters | 6 ++++++ msvc/msvc_compat.h | 1 + 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 33845b8171..39d8397458 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -53,7 +53,9 @@ typedef struct thread_video video_info_t info; const video_driver_t *driver; +#ifdef HAVE_OVERLAY const video_overlay_interface_t *overlay; +#endif void *driver_data; const input_driver_t **input; void **input_data; diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj index b4cc93f5a8..40e35b3f1a 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj @@ -88,7 +88,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_SINC;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__ + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_SINC;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -108,7 +108,7 @@ Level3 Disabled - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_SINC;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__ + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_ZLIB;WANT_MINIZ;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_SINC;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreadedDebug CompileAsCpp @@ -130,7 +130,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_ZLIB;WANT_MINIZ;HAVE_SINC;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__ + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;HAVE_ZLIB;WANT_MINIZ;HAVE_SINC;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -154,7 +154,7 @@ MaxSpeed true true - WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_SINC;HAVE_ZLIB;WANT_MINIZ;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__ + WIN32;HAVE_WIN32_D3D9;HAVE_CG;HAVE_GLSL;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_SCREENSHOTS;HAVE_BSV_MOVIE;HAVE_DINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETPLAY;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_SINC;HAVE_ZLIB;WANT_MINIZ;PACKAGE_VERSION="0.9.8";_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\;$(CG_INC_PATH);%(AdditionalIncludeDirectories) MultiThreaded CompileAsCpp @@ -196,6 +196,8 @@ + + diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj.filters b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj.filters index 1cb7219c01..98dac513ab 100644 --- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj.filters +++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj.filters @@ -213,6 +213,12 @@ Source Files\deps + + Source Files\gfx + + + Source Files\input + diff --git a/msvc/msvc_compat.h b/msvc/msvc_compat.h index 43e1fe903b..eaa693e435 100644 --- a/msvc/msvc_compat.h +++ b/msvc/msvc_compat.h @@ -38,6 +38,7 @@ typedef int ssize_t; // Disable some of the annoying warnings. #pragma warning(disable : 4800) +#pragma warning(disable : 4805) #pragma warning(disable : 4244) #pragma warning(disable : 4305) #pragma warning(disable : 4146)