(XMB/Ozone) Add optional thumbnail upscaling

This commit is contained in:
jdgleaver 2019-06-05 17:04:23 +01:00
parent 146f974274
commit c4bb2f5ad7
17 changed files with 137 additions and 30 deletions

View File

@ -821,6 +821,8 @@ static const unsigned menu_thumbnails_default = 3;
static const unsigned menu_left_thumbnails_default = 0;
static const unsigned menu_thumbnail_upscale_threshold = 0;
static const unsigned menu_timedate_style = 5;
static const bool xmb_vertical_thumbnails = false;

View File

@ -1740,6 +1740,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
#ifdef HAVE_MENU
SETTING_UINT("dpi_override_value", &settings->uints.menu_dpi_override_value, true, menu_dpi_override_value, false);
SETTING_UINT("menu_thumbnails", &settings->uints.menu_thumbnails, true, menu_thumbnails_default, false);
SETTING_UINT("menu_thumbnail_upscale_threshold", &settings->uints.menu_thumbnail_upscale_threshold, true, menu_thumbnail_upscale_threshold, false);
SETTING_UINT("menu_timedate_style", &settings->uints.menu_timedate_style, true, menu_timedate_style, false);
SETTING_UINT("menu_ticker_type", &settings->uints.menu_ticker_type, true, menu_ticker_type, false);
#ifdef HAVE_RGUI

View File

@ -457,6 +457,7 @@ typedef struct settings
unsigned menu_timedate_style;
unsigned menu_thumbnails;
unsigned menu_left_thumbnails;
unsigned menu_thumbnail_upscale_threshold;
unsigned menu_rgui_thumbnail_downscaler;
unsigned menu_rgui_thumbnail_delay;
unsigned menu_dpi_override_value;

View File

@ -1151,6 +1151,8 @@ MSG_HASH(MENU_ENUM_LABEL_LEFT_THUMBNAILS,
"left thumbnails")
MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
"xmb_vertical_thumbnails")
MSG_HASH(MENU_ENUM_LABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD,
"menu_thumbnail_upscale_threshold")
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
"rgui_thumbnail_downscaler")
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY,

View File

@ -3034,6 +3034,14 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS,
"Thumbnails Vertical Disposition"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_THUMBNAIL_UPSCALE_THRESHOLD,
"Thumbnail Upscaling Threshold"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD,
"Automatically upscale thumbnail images with a width/height smaller than the specified value. Improves picture quality. Has a moderate performance impact."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_RGUI_INLINE_THUMBNAILS,
"Show Playlist Thumbnails"

View File

@ -1388,7 +1388,7 @@ static int generic_action_ok(const char *path,
action_path, sizeof(settings->paths.path_menu_wallpaper));
task_push_image_load(action_path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
}
break;

View File

@ -357,6 +357,7 @@ default_sublabel_macro(action_bind_sublabel_thumbnails_rgui, MENU_
default_sublabel_macro(action_bind_sublabel_left_thumbnails, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS)
default_sublabel_macro(action_bind_sublabel_left_thumbnails_rgui, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_RGUI)
default_sublabel_macro(action_bind_sublabel_left_thumbnails_ozone, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_OZONE)
default_sublabel_macro(action_bind_sublabel_menu_thumbnail_upscale_threshold, MENU_ENUM_SUBLABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD)
default_sublabel_macro(action_bind_sublabel_timedate_enable, MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE)
default_sublabel_macro(action_bind_sublabel_timedate_style, MENU_ENUM_SUBLABEL_TIMEDATE_STYLE)
default_sublabel_macro(action_bind_sublabel_battery_level_enable, MENU_ENUM_SUBLABEL_BATTERY_LEVEL_ENABLE)
@ -1719,6 +1720,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_left_thumbnails);
}
break;
case MENU_ENUM_LABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_thumbnail_upscale_threshold);
break;
case MENU_ENUM_LABEL_MOUSE_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_mouse_enable);
break;

View File

@ -1885,7 +1885,7 @@ static void materialui_context_reset(void *data, bool is_threaded)
if (path_is_valid(settings->paths.path_menu_wallpaper))
task_push_image_load(settings->paths.path_menu_wallpaper,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
}

View File

@ -392,6 +392,7 @@ static void ozone_update_thumbnail_path(void *data, unsigned i, char pos)
static void ozone_update_thumbnail_image(void *data)
{
settings_t *settings = config_get_ptr();
ozone_handle_t *ozone = (ozone_handle_t*)data;
const char *right_thumbnail_path = NULL;
const char *left_thumbnail_path = NULL;
@ -404,14 +405,14 @@ static void ozone_update_thumbnail_image(void *data)
bool thumbnails_missing = false;
#endif
if (!ozone)
if (!ozone || !settings)
return;
if (menu_thumbnail_get_path(ozone->thumbnail_path_data, MENU_THUMBNAIL_RIGHT, &right_thumbnail_path))
{
if (path_is_valid(right_thumbnail_path))
task_push_image_load(right_thumbnail_path,
supports_rgba,
supports_rgba, settings->uints.menu_thumbnail_upscale_threshold,
menu_display_handle_thumbnail_upload, NULL);
else
{
@ -428,7 +429,7 @@ static void ozone_update_thumbnail_image(void *data)
{
if (path_is_valid(left_thumbnail_path))
task_push_image_load(left_thumbnail_path,
supports_rgba,
supports_rgba, settings->uints.menu_thumbnail_upscale_threshold,
menu_display_handle_left_thumbnail_upload, NULL);
else
{
@ -445,11 +446,6 @@ static void ozone_update_thumbnail_image(void *data)
/* On demand thumbnail downloads */
if (thumbnails_missing)
{
settings_t *settings = config_get_ptr();
if (!settings)
return;
if (settings->bools.network_on_demand_thumbnails)
{
const char *system = NULL;

View File

@ -1602,7 +1602,7 @@ static bool request_thumbnail(
/* Would like to cancel any existing image load tasks
* here, but can't see how to do it... */
if(task_push_image_load(thumbnail->path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
(thumbnail_id == MENU_THUMBNAIL_LEFT) ?
menu_display_handle_left_thumbnail_upload : menu_display_handle_thumbnail_upload, NULL))
{
@ -2204,7 +2204,7 @@ end:
* here - in general, wallpaper is loaded once per session
* and then forgotten, so performance issues are not a concern */
task_push_image_load(wallpaper_path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
}
}

View File

@ -1065,7 +1065,7 @@ static void stripes_update_thumbnail_image(void *data)
{
if (path_is_valid(stripes->thumbnail_file_path))
task_push_image_load(stripes->thumbnail_file_path,
supports_rgba,
supports_rgba, 0,
menu_display_handle_thumbnail_upload, NULL);
else
video_driver_texture_unload(&stripes->thumbnail);
@ -1078,7 +1078,7 @@ static void stripes_update_thumbnail_image(void *data)
{
if (path_is_valid(stripes->left_thumbnail_file_path))
task_push_image_load(stripes->left_thumbnail_file_path,
supports_rgba,
supports_rgba, 0,
menu_display_handle_left_thumbnail_upload, NULL);
else
video_driver_texture_unload(&stripes->left_thumbnail);
@ -1142,7 +1142,7 @@ static void stripes_update_savestate_thumbnail_image(void *data)
if (path_is_valid(stripes->savestate_thumbnail_file_path))
task_push_image_load(stripes->savestate_thumbnail_file_path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_savestate_thumbnail_upload, NULL);
else
video_driver_texture_unload(&stripes->savestate_thumbnail);
@ -1519,7 +1519,7 @@ static void stripes_list_switch_new(stripes_handle_t *stripes,
if (path_is_valid(path))
{
task_push_image_load(path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
if (!string_is_empty(stripes->bg_file_path))
free(stripes->bg_file_path);
@ -3681,7 +3681,7 @@ static void stripes_context_reset_background(const char *iconpath)
if (path_is_valid(path))
task_push_image_load(path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
if (path)

View File

@ -1008,6 +1008,7 @@ static void xmb_update_savestate_thumbnail_path(void *data, unsigned i)
static void xmb_update_thumbnail_image(void *data)
{
settings_t *settings = config_get_ptr();
xmb_handle_t *xmb = (xmb_handle_t*)data;
const char *right_thumbnail_path = NULL;
const char *left_thumbnail_path = NULL;
@ -1020,14 +1021,14 @@ static void xmb_update_thumbnail_image(void *data)
bool thumbnails_missing = false;
#endif
if (!xmb)
if (!xmb || !settings)
return;
if (menu_thumbnail_get_path(xmb->thumbnail_path_data, MENU_THUMBNAIL_RIGHT, &right_thumbnail_path))
{
if (path_is_valid(right_thumbnail_path))
task_push_image_load(right_thumbnail_path,
supports_rgba,
supports_rgba, settings->uints.menu_thumbnail_upscale_threshold,
menu_display_handle_thumbnail_upload, NULL);
else
{
@ -1044,7 +1045,7 @@ static void xmb_update_thumbnail_image(void *data)
{
if (path_is_valid(left_thumbnail_path))
task_push_image_load(left_thumbnail_path,
supports_rgba,
supports_rgba, settings->uints.menu_thumbnail_upscale_threshold,
menu_display_handle_left_thumbnail_upload, NULL);
else
{
@ -1061,11 +1062,6 @@ static void xmb_update_thumbnail_image(void *data)
/* On demand thumbnail downloads */
if (thumbnails_missing)
{
settings_t *settings = config_get_ptr();
if (!settings)
return;
if (settings->bools.network_on_demand_thumbnails)
{
const char *system = NULL;
@ -1234,7 +1230,7 @@ static void xmb_update_savestate_thumbnail_image(void *data)
if (path_is_valid(xmb->savestate_thumbnail_file_path))
task_push_image_load(xmb->savestate_thumbnail_file_path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_savestate_thumbnail_upload, NULL);
else
video_driver_texture_unload(&xmb->savestate_thumbnail);
@ -1690,7 +1686,7 @@ static void xmb_list_switch_new(xmb_handle_t *xmb,
if (path_is_valid(path))
{
task_push_image_load(path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
if (!string_is_empty(xmb->bg_file_path))
free(xmb->bg_file_path);
@ -5065,7 +5061,7 @@ static void xmb_context_reset_background(const char *iconpath)
if (path_is_valid(path))
task_push_image_load(path,
video_driver_supports_rgba(),
video_driver_supports_rgba(), 0,
menu_display_handle_wallpaper_upload, NULL);
#ifdef ORBIS

View File

@ -4462,6 +4462,7 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct
{MENU_ENUM_LABEL_THUMBNAILS, PARSE_ONLY_UINT },
{MENU_ENUM_LABEL_LEFT_THUMBNAILS, PARSE_ONLY_UINT },
{MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, PARSE_ONLY_BOOL },
{MENU_ENUM_LABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD, PARSE_ONLY_UINT },
{MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS, PARSE_ONLY_BOOL },
{MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER, PARSE_ONLY_UINT },
{MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY, PARSE_ONLY_UINT },

View File

@ -12289,6 +12289,23 @@ static bool setting_append_list(
SD_FLAG_NONE);
}
if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone"))
{
CONFIG_UINT(
list, list_info,
&settings->uints.menu_thumbnail_upscale_threshold,
MENU_ENUM_LABEL_MENU_THUMBNAIL_UPSCALE_THRESHOLD,
MENU_ENUM_LABEL_VALUE_MENU_THUMBNAIL_UPSCALE_THRESHOLD,
menu_thumbnail_upscale_threshold,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
menu_settings_list_current_add_range(list, list_info, 0, 1024, 256, true, true);
}
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
{
CONFIG_UINT(

View File

@ -935,6 +935,7 @@ enum msg_hash_enums
MENU_LABEL(LEFT_THUMBNAILS_RGUI),
MENU_LABEL(LEFT_THUMBNAILS_OZONE),
MENU_LABEL(XMB_VERTICAL_THUMBNAILS),
MENU_LABEL(MENU_THUMBNAIL_UPSCALE_THRESHOLD),
MENU_LABEL(MENU_RGUI_INLINE_THUMBNAILS),
MENU_LABEL(MENU_RGUI_SWAP_THUMBNAILS),
MENU_LABEL(MENU_RGUI_THUMBNAIL_DOWNSCALER),

View File

@ -49,6 +49,7 @@ struct nbio_image_handle
int processing_final_state;
unsigned frame_duration;
size_t size;
unsigned upscale_threshold;
void *handle;
transfer_cb_t cb;
struct texture_image ti;
@ -226,6 +227,48 @@ static int cb_nbio_image_thumbnail(void *data, size_t len)
return 0;
}
static bool upscale_image(
unsigned scale_factor,
struct texture_image *image_src,
struct texture_image *image_dst)
{
uint32_t x_ratio, y_ratio;
unsigned x_src, y_src;
unsigned x_dst, y_dst;
/* Sanity check */
if ((scale_factor < 1) || !image_src || !image_dst)
return false;
if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1))
return false;
/* Get output dimensions */
image_dst->width = image_src->width * scale_factor;
image_dst->height = image_src->height * scale_factor;
/* Allocate pixel buffer */
image_dst->pixels = (uint32_t*)calloc(image_dst->width * image_dst->height, sizeof(uint32_t));
if (!image_dst->pixels)
return false;
/* Perform nearest neighbour resampling */
x_ratio = ((image_src->width << 16) / image_dst->width);
y_ratio = ((image_src->height << 16) / image_dst->height);
for (y_dst = 0; y_dst < image_dst->height; y_dst++)
{
y_src = (y_dst * y_ratio) >> 16;
for (x_dst = 0; x_dst < image_dst->width; x_dst++)
{
x_src = (x_dst * x_ratio) >> 16;
image_dst->pixels[(y_dst * image_dst->width) + x_dst] = image_src->pixels[(y_src * image_src->width) + x_src];
}
}
return true;
}
bool task_image_load_handler(retro_task_t *task)
{
nbio_handle_t *nbio = (nbio_handle_t*)task->state;
@ -286,6 +329,40 @@ bool task_image_load_handler(retro_task_t *task)
if (img)
{
/* Upscale image, if required */
if (image->upscale_threshold > 0)
{
if (((image->ti.width > 0) && (image->ti.height > 0)) &&
((image->ti.width < image->upscale_threshold) ||
(image->ti.height < image->upscale_threshold)))
{
unsigned min_size = (image->ti.width < image->ti.height) ?
image->ti.width : image->ti.height;
float scale_factor = (float)image->upscale_threshold /
(float)min_size;
unsigned scale_factor_int = (unsigned)scale_factor;
struct texture_image img_resampled = {
0,
0,
NULL,
false
};
if (scale_factor - (float)scale_factor_int > 0.0f)
scale_factor_int += 1;
if (upscale_image(scale_factor_int, &image->ti, &img_resampled))
{
image->ti.width = img_resampled.width;
image->ti.height = img_resampled.height;
if (image->ti.pixels)
free(image->ti.pixels);
image->ti.pixels = img_resampled.pixels;
}
}
}
img->width = image->ti.width;
img->height = image->ti.height;
img->pixels = image->ti.pixels;
@ -301,7 +378,7 @@ bool task_image_load_handler(retro_task_t *task)
}
bool task_push_image_load(const char *fullpath,
bool supports_rgba,
bool supports_rgba, unsigned upscale_threshold,
retro_task_callback_t cb, void *user_data)
{
nbio_handle_t *nbio = NULL;
@ -350,6 +427,7 @@ bool task_push_image_load(const char *fullpath,
image->processing_final_state = 0;
image->frame_duration = 0;
image->size = 0;
image->upscale_threshold = upscale_threshold;
image->handle = NULL;
image->ti.width = 0;

View File

@ -74,7 +74,7 @@ bool task_push_pl_entry_thumbnail_download(
#endif
bool task_push_image_load(const char *fullpath,
bool supports_rgba,
bool supports_rgba, unsigned upscale_threshold,
retro_task_callback_t cb, void *userdata);
#ifdef HAVE_LIBRETRODB