mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 16:09:47 +00:00
(XMB/Ozone) Add optional thumbnail upscaling
This commit is contained in:
parent
146f974274
commit
c4bb2f5ad7
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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(
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user