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); #if defined(HAVE_MENU) free(thr->texture.frame); #endif 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->alpha_mod); slock_free(thr->alpha_lock); RARCH_LOG("Threaded video stats: Frames pushed: %u, Frames dropped: %u.\n", thr->hit_count, thr->miss_count); free(thr); }
static void thread_set_aspect_ratio(void *data, unsigned aspectratio_index) { thread_video_t *thr = (thread_video_t*)data; thr->cmd_data.i = aspectratio_index; thread_send_cmd(thr, CMD_POKE_SET_ASPECT_RATIO); thread_wait_reply(thr, CMD_POKE_SET_ASPECT_RATIO); }
static void thread_overlay_full_screen(void *data, bool 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_enable(void *data, bool 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 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); }
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->alpha_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; 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->target_frame_time = (retro_time_t)roundf(1000000LL / g_settings.video.refresh_rate); thr->last_time = rarch_get_time_usec(); 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_overlay_set_alpha(void *data, float 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 void thread_set_filtering(void *data, unsigned index, bool smooth) { thread_video_t *thr = (thread_video_t*)data; thr->cmd_data.filtering.index = index; thr->cmd_data.filtering.smooth = smooth; thread_send_cmd(thr, CMD_POKE_SET_FILTERING); thread_wait_reply(thr, CMD_POKE_SET_FILTERING); }
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_overlay_set_alpha(void *data, unsigned index, float mod) { thread_video_t *thr = (thread_video_t*)data; thr->cmd_data.alpha.index = index; thr->cmd_data.alpha.mod = mod; thread_send_cmd(thr, CMD_OVERLAY_SET_ALPHA); thread_wait_reply(thr, CMD_OVERLAY_SET_ALPHA); }
static bool thread_overlay_load(void *data, const struct texture_image *images, unsigned num_images) { thread_video_t *thr = (thread_video_t*)data; thr->cmd_data.image.data = images; thr->cmd_data.image.num = num_images; thread_send_cmd(thr, CMD_OVERLAY_LOAD); thread_wait_reply(thr, CMD_OVERLAY_LOAD); return thr->cmd_data.b; }
static bool thread_set_shader(void *data, enum rarch_shader_type type, const char *path) { thread_video_t *thr = (thread_video_t*)data; thr->cmd_data.set_shader.type = type; thr->cmd_data.set_shader.path = path; thread_send_cmd(thr, CMD_SET_SHADER); thread_wait_reply(thr, CMD_SET_SHADER); return thr->cmd_data.b; }
static void thread_overlay_vertex_geom(void *data, float x, float y, float w, float 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 bool thread_overlay_load(void *data, const uint32_t *image, unsigned width, unsigned height) { 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 bool thread_alive(void *data) { thread_video_t *thr = (thread_video_t*)data; 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; } }