Reimplement image loading using tasks

This commit is contained in:
Higor Eurípedes 2015-11-23 00:17:27 -03:00
parent c21ffeff71
commit 5d92e9061c
9 changed files with 135 additions and 331 deletions

View File

@ -25,6 +25,7 @@
#include "../../general.h"
#include "../../runloop_data.h"
#include "../../tasks/tasks.h"
#include "../../input/input_remapping.h"
#include "../../system.h"
@ -628,9 +629,8 @@ static int generic_action_ok(const char *path,
if (path_file_exists(action_path))
{
strlcpy(settings->menu.wallpaper, action_path, sizeof(settings->menu.wallpaper));
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE, action_path, "cb_menu_wallpaper", 0, 1,
true);
rarch_task_push_image_load(action_path,
"cb_menu_wallpaper", menu_display_handle_wallpaper_upload);
}
break;
case ACTION_OK_LOAD_CORE:

View File

@ -40,6 +40,7 @@
#include "../../runloop.h"
#include "../../runloop_data.h"
#include "../../verbosity.h"
#include "../../tasks/tasks.h"
enum
{
@ -1163,8 +1164,8 @@ static void mui_context_reset(void)
mui_allocate_white_texture(mui);
mui_context_reset_textures(mui, iconpath);
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE,
settings->menu.wallpaper, "cb_menu_wallpaper", 0, 1, true);
rarch_task_push_image_load(settings->menu.wallpaper, "cb_menu_wallpaper",
menu_display_handle_wallpaper_upload);
}
static int mui_environ(menu_environ_cb_t type, void *data)

View File

@ -46,6 +46,7 @@
#include "../../runloop.h"
#include "../../runloop_data.h"
#include "../../tasks/tasks.h"
#ifndef XMB_THEME
#define XMB_THEME "monochrome"
@ -540,8 +541,8 @@ static void xmb_update_boxart_path(xmb_handle_t *xmb, unsigned i)
static void xmb_update_boxart_image(xmb_handle_t *xmb)
{
if (path_file_exists(xmb->boxart_file_path))
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE, xmb->boxart_file_path,
"cb_menu_boxart", 0, 1, true);
rarch_task_push_image_load(xmb->boxart_file_path, "cb_menu_boxart",
menu_display_handle_boxart_upload);
else if (xmb->depth == 1)
xmb->boxart = 0;
}
@ -814,9 +815,8 @@ static void xmb_list_switch_new(xmb_handle_t *xmb,
if(strcmp(path, xmb->background_file_path) != 0) {
if(path_file_exists(path)) {
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE, path,
"cb_menu_wallpaper", 0, 1, true);
strlcpy(xmb->background_file_path, path, sizeof(xmb->background_file_path));
rarch_task_push_image_load(path, "cb_menu_wallpaper", menu_display_handle_wallpaper_upload);
strlcpy(xmb->background_file_path, path, sizeof(xmb->background_file_path));
}
}
}
@ -2248,8 +2248,7 @@ static void xmb_context_reset_background(const char *iconpath)
strlcpy(path, settings->menu.wallpaper, sizeof(path));
if (path_file_exists(path))
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE, path,
"cb_menu_wallpaper", 0, 1, true);
rarch_task_push_image_load(path, "cb_menu_wallpaper", menu_display_handle_wallpaper_upload);
}
static void xmb_context_reset(void)

View File

@ -47,6 +47,7 @@
#include "../../configuration.h"
#include "../../runloop.h"
#include "../../verbosity.h"
#include "../../tasks/tasks.h"
#if 0
#define ZARCH_DEBUG
@ -1109,8 +1110,8 @@ static void *zarch_init(void)
zui->font_size = 28;
if (settings->menu.wallpaper[0] != '\0')
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE,
settings->menu.wallpaper, "cb_menu_wallpaper", 0, 1, true);
rarch_task_push_image_load(settings->menu.wallpaper,
"cb_menu_wallpaper", menu_display_handle_wallpaper_upload);
zui->ca.allocated = 0;
@ -1228,8 +1229,8 @@ static void zarch_context_reset(void)
zarch_context_bg_destroy(zui);
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE,
settings->menu.wallpaper, "cb_menu_wallpaper", 0, 1, true);
rarch_task_push_image_load(settings->menu.wallpaper,
"cb_menu_wallpaper", menu_display_handle_wallpaper_upload);
zarch_allocate_white_texture(zui);

View File

@ -662,3 +662,19 @@ const float *menu_display_get_tex_coords(void)
return menu_disp->get_tex_coords();
}
void menu_display_handle_wallpaper_upload(void *task_data, void *user_data, const char *err)
{
struct texture_image *img = (struct texture_image*)task_data;
menu_driver_load_image(img, MENU_IMAGE_WALLPAPER);
texture_image_free(img);
free(img);
}
void menu_display_handle_boxart_upload(void *task_data, void *user_data, const char *err)
{
struct texture_image *img = (struct texture_image*)task_data;
menu_driver_load_image(img, MENU_IMAGE_BOXART);
texture_image_free(img);
free(img);
}

View File

@ -178,6 +178,10 @@ void menu_display_clear_color(float r, float g, float b, float a);
void menu_display_texture_unload(uintptr_t *id);
void menu_display_handle_wallpaper_upload(void *task_data, void *user_data, const char *err);
void menu_display_handle_boxart_upload(void *task_data, void *user_data, const char *err);
const float *menu_display_get_tex_coords(void);
extern menu_display_ctx_driver_t menu_display_ctx_gl;

View File

@ -85,7 +85,6 @@ void rarch_main_data_deinit(void)
void rarch_main_data_free(void)
{
rarch_main_data_nbio_uninit();
#ifdef HAVE_NETWORKING
rarch_main_data_http_uninit();
#endif
@ -95,12 +94,6 @@ void rarch_main_data_free(void)
static void data_runloop_iterate(bool is_thread)
{
rarch_main_data_nbio_iterate (is_thread);
#ifdef HAVE_MENU
#ifdef HAVE_RPNG
rarch_main_data_nbio_image_iterate (is_thread);
#endif
#endif
#ifdef HAVE_NETWORKING
rarch_main_data_http_iterate (is_thread);
#endif
@ -113,10 +106,6 @@ bool rarch_main_data_active(void)
if (input_overlay_data_is_active())
return true;
#endif
if (rarch_main_data_nbio_image_get_handle())
return true;
if (rarch_main_data_nbio_get_handle())
return true;
#ifdef HAVE_NETWORKING
if (rarch_main_data_http_get_handle())
return true;
@ -219,11 +208,6 @@ void rarch_main_data_iterate(void)
}
#endif
#ifdef HAVE_RPNG
#ifdef HAVE_MENU
rarch_main_data_nbio_image_upload_iterate();
#endif
#endif
#ifdef HAVE_OVERLAY
rarch_main_data_overlay_iterate();
#endif
@ -266,7 +250,6 @@ void rarch_main_data_clear_state(void)
rarch_main_data_free();
rarch_main_data_init();
rarch_main_data_nbio_init();
#ifdef HAVE_NETWORKING
rarch_main_data_http_init();
#endif
@ -278,7 +261,6 @@ void rarch_main_data_init_queues(void)
#ifdef HAVE_NETWORKING
rarch_main_data_http_init_msg_queue();
#endif
rarch_main_data_nbio_init_msg_queue();
}
@ -297,12 +279,8 @@ void rarch_main_data_msg_queue_push(unsigned type,
case DATA_TYPE_NONE:
break;
case DATA_TYPE_FILE:
queue = rarch_main_data_nbio_get_msg_queue_ptr();
fill_pathname_join_delim(new_msg, msg, msg2, '|', sizeof(new_msg));
break;
case DATA_TYPE_IMAGE:
queue = rarch_main_data_nbio_image_get_msg_queue_ptr();
fill_pathname_join_delim(new_msg, msg, msg2, '|', sizeof(new_msg));
break;
#ifdef HAVE_NETWORKING
case DATA_TYPE_HTTP:

View File

@ -63,7 +63,6 @@ typedef struct nbio_image_handle
unsigned pos_increment;
uint64_t frame_count;
int processing_final_state;
msg_queue_t *msg_queue;
unsigned status;
} nbio_image_handle_t;
@ -79,54 +78,15 @@ typedef struct nbio_handle
unsigned status;
} nbio_handle_t;
static nbio_handle_t *nbio_ptr;
msg_queue_t *rarch_main_data_nbio_get_msg_queue_ptr(void)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
if (!nbio)
return NULL;
return nbio->msg_queue;
}
void *rarch_main_data_nbio_get_handle(void)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
if (!nbio)
return NULL;
return nbio->handle;
}
msg_queue_t *rarch_main_data_nbio_image_get_msg_queue_ptr(void)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
if (!nbio)
return NULL;
#ifdef HAVE_RPNG
return nbio->image.msg_queue;
#else
return NULL;
#endif
}
void *rarch_main_data_nbio_image_get_handle(void)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
if (!nbio)
return NULL;
#ifdef HAVE_RPNG
return nbio->image.handle;
#else
return NULL;
#endif
}
static void rarch_task_file_load_handler(rarch_task_t *task);
#ifdef HAVE_MENU
#include "../menu/menu_driver.h"
#ifdef HAVE_RPNG
static int cb_image_menu_upload_generic(nbio_handle_t *nbio)
static int cb_image_menu_upload_generic(void *data, size_t len)
{
nbio_handle_t *nbio = (nbio_handle_t*)data;
unsigned r_shift, g_shift, b_shift, a_shift;
if (!nbio)
@ -150,34 +110,6 @@ static int cb_image_menu_upload_generic(nbio_handle_t *nbio)
return 0;
}
static int cb_image_menu_wallpaper_upload(void *data, size_t len)
{
nbio_handle_t *nbio = (nbio_handle_t*)data;
if (cb_image_menu_upload_generic(nbio) != 0)
return -1;
menu_driver_load_image(&nbio->image.ti, MENU_IMAGE_WALLPAPER);
texture_image_free(&nbio->image.ti);
return 0;
}
static int cb_image_menu_boxart_upload(void *data, size_t len)
{
nbio_handle_t *nbio = (nbio_handle_t*)data;
if (cb_image_menu_upload_generic(nbio) != 0)
return -1;
menu_driver_load_image(&nbio->image.ti, MENU_IMAGE_BOXART);
texture_image_free(&nbio->image.ti);
return 0;
}
static int cb_image_menu_generic(nbio_handle_t *nbio)
{
unsigned width = 0, height = 0;
@ -210,7 +142,7 @@ static int cb_image_menu_wallpaper(void *data, size_t len)
if (cb_image_menu_generic(nbio) != 0)
return -1;
nbio->image.cb = &cb_image_menu_wallpaper_upload;
nbio->image.cb = &cb_image_menu_upload_generic;
return 0;
}
@ -222,31 +154,7 @@ static int cb_image_menu_boxart(void *data, size_t len)
if (cb_image_menu_generic(nbio) != 0)
return -1;
nbio->image.cb = &cb_image_menu_boxart_upload;
return 0;
}
static int rarch_main_data_image_iterate_poll(nbio_handle_t *nbio)
{
const char *path = NULL;
if (!nbio)
return -1;
path = msg_queue_pull(nbio->image.msg_queue);
if (!path)
return -1;
/* Can only deal with one image transfer at a time for now */
if (nbio->image.handle)
return -1;
/* We need to load the image file first. */
msg_queue_clear(nbio->msg_queue);
msg_queue_push(nbio->msg_queue, path, 0, 1);
nbio->image.cb = &cb_image_menu_upload_generic;
return 0;
}
@ -301,83 +209,26 @@ static int rarch_main_data_image_iterate_process_transfer(nbio_handle_t *nbio)
return -1;
}
static int rarch_main_data_image_iterate_parse_free(nbio_handle_t *nbio)
static int rarch_main_data_image_iterate_process_transfer_parse(nbio_handle_t *nbio)
{
if (!nbio)
return -1;
rpng_nbio_load_image_free(nbio->image.handle);
nbio->image.handle = NULL;
nbio->image.frame_count = 0;
msg_queue_clear(nbio->image.msg_queue);
if (nbio->image.handle && nbio->image.cb)
{
size_t len = 0;
nbio->image.cb(nbio, len);
}
return 0;
}
void rarch_main_data_nbio_image_iterate(bool is_thread)
static int rarch_main_data_image_iterate_transfer_parse(nbio_handle_t *nbio)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
nbio_image_handle_t *image = nbio ? &nbio->image : NULL;
if (!image || !nbio)
return;
(void)is_thread;
switch (image->status)
if (nbio->image.handle && nbio->image.cb)
{
case NBIO_IMAGE_STATUS_PROCESS_TRANSFER:
if (rarch_main_data_image_iterate_process_transfer(nbio) == -1)
image->status = NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE;
break;
case NBIO_IMAGE_STATUS_TRANSFER_PARSE:
if (nbio->image.handle && nbio->image.cb)
{
size_t len = 0;
nbio->image.cb(nbio, len);
}
if (image->is_blocking_on_processing)
image->status = NBIO_IMAGE_STATUS_PROCESS_TRANSFER;
break;
case NBIO_IMAGE_STATUS_TRANSFER:
if (!image->is_blocking)
if (rarch_main_data_image_iterate_transfer(nbio) == -1)
image->status = NBIO_IMAGE_STATUS_TRANSFER_PARSE;
break;
default:
case NBIO_IMAGE_STATUS_POLL:
if (rarch_main_data_image_iterate_poll(nbio) == 0)
image->status = NBIO_IMAGE_STATUS_TRANSFER;
break;
size_t len = 0;
nbio->image.cb(nbio, len);
}
}
void rarch_main_data_nbio_image_upload_iterate(void)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
nbio_image_handle_t *image = nbio ? &nbio->image : NULL;
if (!image || !nbio)
return;
switch (image->status)
{
case NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE:
if (nbio->image.handle && nbio->image.cb)
{
size_t len = 0;
nbio->image.cb(nbio, len);
}
if (image->is_finished)
image->status = NBIO_IMAGE_STATUS_TRANSFER_PARSE_FREE;
break;
case NBIO_IMAGE_STATUS_TRANSFER_PARSE_FREE:
rarch_main_data_image_iterate_parse_free(nbio);
image->status = NBIO_IMAGE_STATUS_POLL;
break;
}
return 0;
}
#endif
@ -462,92 +313,50 @@ static int cb_nbio_image_menu_boxart(void *data, size_t len)
return cb_nbio_generic(nbio, &len);
}
#endif
#endif
static int rarch_main_data_nbio_iterate_poll(nbio_handle_t *nbio)
bool rarch_task_push_image_load(const char *fullpath, const char *type, rarch_task_callback_t cb)
{
char elem0[PATH_MAX_LENGTH];
unsigned elem0_hash = 0;
rarch_task_t *t;
nbio_handle_t *nbio;
uint32_t cb_type_hash = 0;
struct nbio_t* handle = NULL;
struct string_list *str_list = NULL;
const char *path = NULL;
if (!nbio)
return -1;
path = msg_queue_pull(nbio->msg_queue);
cb_type_hash = djb2_calculate(type);
if (!path)
return -1;
/* Can only deal with one NBIO transfer at a time for now */
if (nbio->handle)
return -1;
str_list = string_split(path, "|");
if (!str_list || (str_list->size < 1))
goto error;
strlcpy(elem0, str_list->elems[0].data, sizeof(elem0));
elem0_hash = djb2_calculate(elem0);
/* TODO/FIXME - should be able to deal with this
* in a better way. */
switch(elem0_hash)
{
case CB_MENU_WALLPAPER:
case CB_MENU_BOXART:
goto error;
default:
break;
}
if (str_list->size > 1)
cb_type_hash = djb2_calculate(str_list->elems[1].data);
handle = nbio_open(elem0, NBIO_READ);
handle = nbio_open(fullpath, NBIO_READ);
if (!handle)
{
RARCH_ERR("Could not create new file loading handle.\n");
goto error;
return false;
}
nbio->handle = handle;
nbio->is_finished = false;
nbio->cb = &cb_nbio_default;
nbio = (nbio_handle_t*)calloc(1, sizeof(*nbio));
nbio->handle = handle;
nbio->is_finished = false;
nbio->cb = &cb_nbio_default;
nbio->status = NBIO_STATUS_TRANSFER;
nbio->image.status = NBIO_IMAGE_STATUS_TRANSFER;
switch (cb_type_hash)
{
#if defined(HAVE_MENU) && defined(HAVE_RPNG)
case CB_MENU_WALLPAPER:
nbio->cb = &cb_nbio_image_menu_wallpaper;
break;
case CB_MENU_BOXART:
nbio->cb = &cb_nbio_image_menu_boxart;
break;
#endif
case 0:
default:
break;
}
if (cb_type_hash == CB_MENU_WALLPAPER)
nbio->cb = &cb_nbio_image_menu_wallpaper;
else if (cb_type_hash == CB_MENU_BOXART)
nbio->cb = &cb_nbio_image_menu_boxart;
nbio_begin_read(handle);
string_list_free(str_list);
t = (rarch_task_t*)calloc(1, sizeof(*t));
t->state = nbio;
t->handler = rarch_task_file_load_handler;
t->callback = cb;
rarch_task_push(t);
return 0;
error:
if (str_list)
string_list_free(str_list);
return -1;
return true;
}
#endif
#endif
static int rarch_main_data_nbio_iterate_transfer(nbio_handle_t *nbio)
{
@ -571,21 +380,6 @@ static int rarch_main_data_nbio_iterate_transfer(nbio_handle_t *nbio)
return 0;
}
static int rarch_main_data_nbio_iterate_parse_free(nbio_handle_t *nbio)
{
if (!nbio || !nbio->is_finished)
return -1;
nbio_free(nbio->handle);
nbio->handle = NULL;
nbio->is_finished = false;
nbio->frame_count = 0;
msg_queue_clear(nbio->msg_queue);
return 0;
}
static int rarch_main_data_nbio_iterate_parse(nbio_handle_t *nbio)
{
if (!nbio)
@ -600,11 +394,10 @@ static int rarch_main_data_nbio_iterate_parse(nbio_handle_t *nbio)
return 0;
}
void rarch_main_data_nbio_iterate(bool is_thread)
static void rarch_task_file_load_handler(rarch_task_t *task)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
if (!nbio)
return;
nbio_handle_t *nbio = (nbio_handle_t*)task->state;
nbio_image_handle_t *image = nbio ? &nbio->image : NULL;
switch (nbio->status)
{
@ -617,37 +410,65 @@ void rarch_main_data_nbio_iterate(bool is_thread)
nbio->status = NBIO_STATUS_TRANSFER_PARSE;
break;
case NBIO_STATUS_TRANSFER_PARSE_FREE:
rarch_main_data_nbio_iterate_parse_free(nbio);
nbio->status = NBIO_STATUS_POLL;
break;
case NBIO_STATUS_POLL:
default:
if (rarch_main_data_nbio_iterate_poll(nbio) == 0)
nbio->status = NBIO_STATUS_TRANSFER;
break;
}
}
void rarch_main_data_nbio_init_msg_queue(void)
{
nbio_handle_t *nbio = (nbio_handle_t*)nbio_ptr;
if (!nbio)
return;
if (nbio->image.handle)
{
switch (image->status)
{
case NBIO_IMAGE_STATUS_PROCESS_TRANSFER:
if (rarch_main_data_image_iterate_process_transfer(nbio) == -1)
image->status = NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE;
break;
case NBIO_IMAGE_STATUS_TRANSFER_PARSE:
rarch_main_data_image_iterate_transfer_parse(nbio);
if (image->is_blocking_on_processing)
image->status = NBIO_IMAGE_STATUS_PROCESS_TRANSFER;
break;
case NBIO_IMAGE_STATUS_TRANSFER:
if (!image->is_blocking)
if (rarch_main_data_image_iterate_transfer(nbio) == -1)
image->status = NBIO_IMAGE_STATUS_TRANSFER_PARSE;
break;
case NBIO_IMAGE_STATUS_PROCESS_TRANSFER_PARSE:
rarch_main_data_image_iterate_process_transfer_parse(nbio);
if (!image->is_finished)
break;
case NBIO_IMAGE_STATUS_TRANSFER_PARSE_FREE:
case NBIO_IMAGE_STATUS_POLL:
default:
break;
}
if (!nbio->msg_queue)
retro_assert(nbio->msg_queue = msg_queue_new(8));
if (!nbio->image.msg_queue)
retro_assert(nbio->image.msg_queue = msg_queue_new(8));
}
if (nbio->is_finished && nbio->image.is_finished)
{
task->task_data = malloc(sizeof(nbio->image.ti));
memcpy(task->task_data, &nbio->image.ti, sizeof(nbio->image.ti));
goto task_finished;
}
void rarch_main_data_nbio_uninit(void)
{
if (nbio_ptr)
free(nbio_ptr);
nbio_ptr = NULL;
}
} else if (nbio->is_finished)
goto task_finished;
void rarch_main_data_nbio_init(void)
{
nbio_ptr = (nbio_handle_t*)calloc(1, sizeof(*nbio_ptr));
return;
task_finished:
task->finished = true;
if (image->handle)
{
rpng_nbio_load_image_free(image->handle);
image->handle = NULL;
image->frame_count = 0;
}
nbio_free(nbio->handle);
nbio->handle = NULL;
nbio->is_finished = false;
nbio->frame_count = 0;
free(nbio);
}

View File

@ -64,21 +64,6 @@ void rarch_task_check(void);
/* MAIN AND TASK THREADS */
void rarch_task_push(rarch_task_t *task);
void rarch_main_data_nbio_uninit(void);
void rarch_main_data_nbio_init(void);
void rarch_main_data_nbio_init_msg_queue(void);
msg_queue_t *rarch_main_data_nbio_get_msg_queue_ptr(void);
msg_queue_t *rarch_main_data_nbio_image_get_msg_queue_ptr(void);
void *rarch_main_data_nbio_get_handle(void);
void *rarch_main_data_nbio_image_get_handle(void);
#ifdef HAVE_NETWORKING
/**
* rarch_main_data_http_iterate_transfer:
@ -104,8 +89,7 @@ void rarch_main_data_http_init(void);
#endif
#ifdef HAVE_RPNG
void rarch_main_data_nbio_image_iterate(bool is_thread);
void rarch_main_data_nbio_image_upload_iterate(void);
bool rarch_task_push_image_load(const char *fullpath, const char *type, rarch_task_callback_t cb);
#endif
#ifdef HAVE_LIBRETRODB