(RGUI) Add optional delay when loading thumbnails

This commit is contained in:
jdgleaver 2019-04-12 15:50:27 +01:00
parent 3345bed1d3
commit a446f8ad51
10 changed files with 201 additions and 117 deletions

View File

@ -387,6 +387,7 @@ static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN;
static bool rgui_inline_thumbnails = false;
static bool rgui_swap_thumbnails = false;
static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT;
static unsigned rgui_thumbnail_delay = 0;
static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE;
static bool rgui_full_width_layout = true;
static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3;

View File

@ -1699,6 +1699,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
#ifdef HAVE_RGUI
SETTING_UINT("rgui_menu_color_theme", &settings->uints.menu_rgui_color_theme, true, rgui_color_theme, false);
SETTING_UINT("rgui_thumbnail_downscaler", &settings->uints.menu_rgui_thumbnail_downscaler, true, rgui_thumbnail_downscaler, false);
SETTING_UINT("rgui_thumbnail_delay", &settings->uints.menu_rgui_thumbnail_delay, true, rgui_thumbnail_delay, false);
SETTING_UINT("rgui_internal_upscale_level", &settings->uints.menu_rgui_internal_upscale_level, true, rgui_internal_upscale_level, false);
SETTING_UINT("rgui_aspect_ratio", &settings->uints.menu_rgui_aspect_ratio, true, rgui_aspect, false);
SETTING_UINT("rgui_aspect_ratio_lock", &settings->uints.menu_rgui_aspect_ratio_lock, true, rgui_aspect_lock, false);

View File

@ -435,6 +435,7 @@ typedef struct settings
unsigned menu_thumbnails;
unsigned menu_left_thumbnails;
unsigned menu_rgui_thumbnail_downscaler;
unsigned menu_rgui_thumbnail_delay;
unsigned menu_dpi_override_value;
unsigned menu_rgui_color_theme;
unsigned menu_xmb_layout;

View File

@ -1131,6 +1131,8 @@ MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
"xmb_vertical_thumbnails")
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
"rgui_thumbnail_downscaler")
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY,
"rgui_thumbnail_delay")
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS,
"rgui_inline_thumbnails")
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS,

View File

@ -3002,6 +3002,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS,
"Swaps the display positions of 'Top Thumbnail' and 'Bottom Thumbnail'."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DELAY,
"Thumbnail Delay (ms)"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DELAY,
"Applies a time delay between selecting a playlist entry and loading its associated thumbnails. Setting this to a value of at least 256 ms enables fast lag-free scrolling on even the slowest devices."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DOWNSCALER,
"Thumbnail Downscaling Method"

View File

@ -532,6 +532,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_shadows,
default_sublabel_macro(action_bind_sublabel_menu_rgui_inline_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS)
default_sublabel_macro(action_bind_sublabel_menu_rgui_swap_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS)
default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER)
default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_delay, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DELAY)
default_sublabel_macro(action_bind_sublabel_content_runtime_log, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG)
default_sublabel_macro(action_bind_sublabel_content_runtime_log_aggregate, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE)
default_sublabel_macro(action_bind_sublabel_playlist_sublabel_runtime_type, MENU_ENUM_SUBLABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE)
@ -2438,6 +2439,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_downscaler);
break;
case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_delay);
break;
case MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_runtime_log);
break;

View File

@ -58,6 +58,7 @@
#include <streams/file_stream.h>
#include "../../tasks/tasks_internal.h"
#include <gfx/scaler/scaler.h>
#include <features/features_cpu.h>
#if defined(GEKKO)
#define RGUI_TERM_START_X(fb_width) (fb_width / 21)
@ -494,6 +495,8 @@ typedef struct
menu_thumbnail_path_data_t *thumbnail_path_data;
uint32_t thumbnail_queue_size;
uint32_t left_thumbnail_queue_size;
bool thumbnail_load_pending;
retro_time_t thumbnail_load_trigger_time;
bool show_wallpaper;
char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */
char menu_title[255]; /* Must be a fixed length array... */
@ -2727,6 +2730,8 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
rgui->thumbnail_queue_size = 0;
rgui->left_thumbnail_queue_size = 0;
rgui->thumbnail_load_pending = false;
rgui->thumbnail_load_trigger_time = 0;
/* Ensure that we start with fullscreen thumbnails disabled */
rgui->show_fs_thumbnail = false;
@ -2766,89 +2771,6 @@ static void rgui_free(void *data)
}
}
static void rgui_frame(void *data, video_frame_info_t *video_info)
{
rgui_t *rgui = (rgui_t*)data;
settings_t *settings = config_get_ptr();
if (settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness)
{
rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness)
{
rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_border_filler_enable != rgui->border_enable)
{
rgui->border_enable = settings->bools.menu_rgui_border_filler_enable;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_shadows != rgui->shadow_enable)
{
rgui_set_blit_line_function(
settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii);
rgui->shadow_enable = settings->bools.menu_rgui_shadows;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_extended_ascii != rgui->extended_ascii_enable)
{
rgui_set_blit_line_function(
settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii);
rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii;
rgui->force_redraw = true;
}
if (settings->uints.menu_rgui_color_theme != rgui->color_theme)
{
prepare_rgui_colors(rgui, settings);
}
else if (settings->uints.menu_rgui_color_theme == RGUI_THEME_CUSTOM)
{
if (string_is_not_equal_fast(settings->paths.path_rgui_theme_preset, rgui->theme_preset_path, sizeof(rgui->theme_preset_path)))
{
prepare_rgui_colors(rgui, settings);
}
}
/* Note: both rgui_set_aspect_ratio() and rgui_set_video_config()
* normally call command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL)
* ## THIS CANNOT BE DONE INSIDE rgui_frame() IF THREADED VIDEO IS ENABLED ##
* Attempting to do so creates a deadlock, and causes RetroArch to hang.
* We therefore have to set the 'delay_update' argument, which causes
* command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) to be called at
* the next instance of rgui_render() */
if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio)
rgui_set_aspect_ratio(rgui, true);
if (settings->uints.menu_rgui_aspect_ratio_lock != rgui->menu_aspect_ratio_lock)
{
rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock;
if (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_NONE)
{
rgui_set_video_config(rgui, &rgui->content_video_settings, true);
}
else
{
rgui_update_menu_viewport(rgui);
rgui_set_video_config(rgui, &rgui->menu_video_settings, true);
}
}
}
static void rgui_set_texture(void)
{
size_t fb_pitch;
@ -2969,54 +2891,79 @@ static void rgui_set_thumbnail_system(void *userdata, char *s, size_t len)
menu_thumbnail_set_system(rgui->thumbnail_path_data, s);
}
static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui)
static void rgui_load_current_thumbnails(rgui_t *rgui)
{
const char *thumbnail_path = NULL;
const char *left_thumbnail_path = NULL;
/* Right (or fullscreen) thumbnail */
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
MENU_THUMBNAIL_RIGHT, &thumbnail_path))
{
rgui->entry_has_thumbnail = request_thumbnail(
rgui->show_fs_thumbnail ? &fs_thumbnail : &mini_thumbnail,
MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path);
}
/* Left thumbnail
* (Note: there is no need to load this when viewing
* fullscreen thumbnails) */
if (!rgui->show_fs_thumbnail)
{
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
MENU_THUMBNAIL_LEFT, &left_thumbnail_path))
{
rgui->entry_has_left_thumbnail = request_thumbnail(
&mini_left_thumbnail, MENU_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, left_thumbnail_path);
}
}
/* Reset 'load pending' state */
rgui->thumbnail_load_pending = false;
/* Force a redraw (so 'entry_has_thumbnail' values are
* applied immediately) */
rgui->force_redraw = true;
}
static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui, bool force_load)
{
bool has_thumbnail = false;
settings_t *settings = config_get_ptr();
if (!settings)
return;
rgui->entry_has_thumbnail = false;
rgui->entry_has_thumbnail = false;
rgui->entry_has_left_thumbnail = false;
rgui->thumbnail_load_pending = false;
/* Update thumbnail content/path */
if ((rgui->show_fs_thumbnail || settings->bools.menu_rgui_inline_thumbnails) && rgui->is_playlist)
{
if (menu_thumbnail_set_content_playlist(rgui->thumbnail_path_data,
playlist_get_cached(), menu_navigation_get_selection()))
{
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
{
if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT))
{
const char *thumbnail_path = NULL;
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
MENU_THUMBNAIL_RIGHT, &thumbnail_path))
{
if (rgui->show_fs_thumbnail)
rgui->entry_has_thumbnail = request_thumbnail(
&fs_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path);
else
rgui->entry_has_thumbnail = request_thumbnail(
&mini_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path);
}
}
}
has_thumbnail = menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT);
if (settings->bools.menu_rgui_inline_thumbnails && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
{
if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_LEFT))
{
const char *left_thumbnail_path = NULL;
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
MENU_THUMBNAIL_LEFT, &left_thumbnail_path))
{
rgui->entry_has_left_thumbnail = request_thumbnail(
&mini_left_thumbnail, MENU_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, left_thumbnail_path);
}
}
}
has_thumbnail = menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_LEFT) ||
has_thumbnail;
}
}
/* Check whether thumbnails should be loaded */
if (has_thumbnail)
{
/* Check whether thumbnails should be loaded immediately */
if ((settings->uints.menu_rgui_thumbnail_delay == 0) || force_load)
rgui_load_current_thumbnails(rgui);
else
{
/* Schedule a delayed load */
rgui->thumbnail_load_pending = true;
rgui->thumbnail_load_trigger_time = cpu_features_get_time_usec();
}
}
}
@ -3055,7 +3002,11 @@ static void rgui_update_thumbnail_image(void *userdata)
}
}
rgui_scan_selected_entry_thumbnail(rgui);
/* Note that we always load thumbnails immediately
* when toggling via the 'scan' button (scheduling a
* delayed load here would make for a poor user
* experience...) */
rgui_scan_selected_entry_thumbnail(rgui, true);
}
static void rgui_update_menu_sublabel(rgui_t *rgui)
@ -3116,7 +3067,7 @@ static void rgui_navigation_set(void *data, bool scroll)
if (!rgui)
return;
rgui_scan_selected_entry_thumbnail(rgui);
rgui_scan_selected_entry_thumbnail(rgui, false);
rgui_update_menu_sublabel(rgui);
if (!scroll)
@ -3179,6 +3130,9 @@ static void rgui_populate_entries(void *data,
/* Set menu title */
menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title));
/* Cancel any pending thumbnail load operations */
rgui->thumbnail_load_pending = false;
rgui_navigation_set(data, true);
/* If aspect ratio lock is enabled, must restore
@ -3251,6 +3205,101 @@ static int rgui_pointer_tap(void *data,
return 0;
}
static void rgui_frame(void *data, video_frame_info_t *video_info)
{
rgui_t *rgui = (rgui_t*)data;
settings_t *settings = config_get_ptr();
if (settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness)
{
rgui->bg_thickness = settings->bools.menu_rgui_background_filler_thickness_enable;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_border_filler_thickness_enable != rgui->border_thickness)
{
rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_border_filler_enable != rgui->border_enable)
{
rgui->border_enable = settings->bools.menu_rgui_border_filler_enable;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_shadows != rgui->shadow_enable)
{
rgui_set_blit_line_function(
settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii);
rgui->shadow_enable = settings->bools.menu_rgui_shadows;
rgui->bg_modified = true;
rgui->force_redraw = true;
}
if (settings->bools.menu_rgui_extended_ascii != rgui->extended_ascii_enable)
{
rgui_set_blit_line_function(
settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii);
rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii;
rgui->force_redraw = true;
}
if (settings->uints.menu_rgui_color_theme != rgui->color_theme)
{
prepare_rgui_colors(rgui, settings);
}
else if (settings->uints.menu_rgui_color_theme == RGUI_THEME_CUSTOM)
{
if (string_is_not_equal_fast(settings->paths.path_rgui_theme_preset, rgui->theme_preset_path, sizeof(rgui->theme_preset_path)))
{
prepare_rgui_colors(rgui, settings);
}
}
/* Note: both rgui_set_aspect_ratio() and rgui_set_video_config()
* normally call command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL)
* ## THIS CANNOT BE DONE INSIDE rgui_frame() IF THREADED VIDEO IS ENABLED ##
* Attempting to do so creates a deadlock, and causes RetroArch to hang.
* We therefore have to set the 'delay_update' argument, which causes
* command_event(CMD_EVENT_VIDEO_SET_ASPECT_RATIO, NULL) to be called at
* the next instance of rgui_render() */
if (settings->uints.menu_rgui_aspect_ratio != rgui->menu_aspect_ratio)
rgui_set_aspect_ratio(rgui, true);
if (settings->uints.menu_rgui_aspect_ratio_lock != rgui->menu_aspect_ratio_lock)
{
rgui->menu_aspect_ratio_lock = settings->uints.menu_rgui_aspect_ratio_lock;
if (settings->uints.menu_rgui_aspect_ratio_lock == RGUI_ASPECT_RATIO_LOCK_NONE)
{
rgui_set_video_config(rgui, &rgui->content_video_settings, true);
}
else
{
rgui_update_menu_viewport(rgui);
rgui_set_video_config(rgui, &rgui->menu_video_settings, true);
}
}
/* Handle pending thumbnail load operations */
if (rgui->thumbnail_load_pending)
{
/* Check whether current 'load delay' duration has elapsed
* Note: Delay is increased when viewing fullscreen thumbnails,
* since the flicker when switching between playlist view and
* fullscreen thumbnail view is incredibly jarring...) */
if ((cpu_features_get_time_usec() - rgui->thumbnail_load_trigger_time) >=
(settings->uints.menu_rgui_thumbnail_delay * 1000 * (rgui->show_fs_thumbnail ? 1.5f : 1.0f)))
rgui_load_current_thumbnails(rgui);
}
}
static void rgui_toggle(void *userdata, bool menu_on)
{
rgui_t *rgui = (rgui_t*)userdata;

View File

@ -6238,6 +6238,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist
MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
PARSE_ONLY_UINT, false) == 0)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY,
PARSE_ONLY_UINT, false) == 0)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_MENU_TICKER_TYPE,
PARSE_ONLY_UINT, false) == 0)

View File

@ -9497,6 +9497,19 @@ static bool setting_append_list(
(*list)[list_info->index - 1].get_string_representation =
&setting_get_string_representation_uint_rgui_thumbnail_scaler;
menu_settings_list_current_add_range(list, list_info, 0, RGUI_THUMB_SCALE_LAST-1, 1, true, true);
CONFIG_UINT(
list, list_info,
&settings->uints.menu_rgui_thumbnail_delay,
MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DELAY,
MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DELAY,
rgui_thumbnail_delay,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0.0f, 1024.0f, 64.0f, true, true);
}
CONFIG_BOOL(

View File

@ -912,6 +912,7 @@ enum msg_hash_enums
MENU_LABEL(MENU_RGUI_INLINE_THUMBNAILS),
MENU_LABEL(MENU_RGUI_SWAP_THUMBNAILS),
MENU_LABEL(MENU_RGUI_THUMBNAIL_DOWNSCALER),
MENU_LABEL(MENU_RGUI_THUMBNAIL_DELAY),
MENU_LABEL(TIMEDATE_ENABLE),
MENU_LABEL(TIMEDATE_STYLE),
MENU_LABEL(BATTERY_LEVEL_ENABLE),