(Ozone/XMB) Prevent unnecessary thumbnail requests when scrolling through playlists

This commit is contained in:
jdgleaver 2022-05-19 16:40:21 +01:00
parent 30685c6e60
commit f2dca12a22
4 changed files with 433 additions and 106 deletions

View File

@ -247,19 +247,15 @@ void gfx_thumbnail_request(
gfx_thumbnail_path_data_t *path_data, enum gfx_thumbnail_id thumbnail_id,
playlist_t *playlist, size_t idx, gfx_thumbnail_t *thumbnail,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails
)
bool network_on_demand_thumbnails)
{
const char *thumbnail_path = NULL;
bool has_thumbnail = false;
gfx_thumbnail_state_t *p_gfx_thumb = NULL;
p_gfx_thumb = NULL;
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
if (!path_data || !thumbnail)
return;
p_gfx_thumb = &gfx_thumb_st;
/* Reset thumbnail, then set 'missing' status by default
* (saves a number of checks later) */
gfx_thumbnail_reset(thumbnail);
@ -354,8 +350,7 @@ end:
* once the image load is complete */
void gfx_thumbnail_request_file(
const char *file_path, gfx_thumbnail_t *thumbnail,
unsigned gfx_thumbnail_upscale_threshold
)
unsigned gfx_thumbnail_upscale_threshold)
{
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
gfx_thumbnail_tag_t *thumbnail_tag = NULL;
@ -424,6 +419,174 @@ void gfx_thumbnail_reset(gfx_thumbnail_t *thumbnail)
/* Stream processing */
/* Requests loading of the specified thumbnail via
* the stream interface
* - Must be called on each frame for the duration
* that specified thumbnail is on-screen
* - Actual load request is deferred by currently
* set stream delay
* - Function becomes a no-op once load request is
* made
* - Thumbnails loaded via this function must be
* deleted manually via gfx_thumbnail_reset()
* when they move off-screen
* NOTE 1: Must be called *after* gfx_thumbnail_set_system()
* and gfx_thumbnail_set_content*()
* NOTE 2: 'playlist' and 'idx' are only required here for
* on-demand thumbnail download support
* (an annoyance...)
* NOTE 3: This function is intended for use in situations
* where each menu entry has a *single* thumbnail.
* If each entry has two thumbnails, use
* gfx_thumbnail_request_streams() for improved
* performance */
void gfx_thumbnail_request_stream(
gfx_thumbnail_path_data_t *path_data,
gfx_animation_t *p_anim,
enum gfx_thumbnail_id thumbnail_id,
playlist_t *playlist, size_t idx,
gfx_thumbnail_t *thumbnail,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails)
{
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
/* Only process request if current status
* is GFX_THUMBNAIL_STATUS_UNKNOWN */
if (!thumbnail ||
(thumbnail->status != GFX_THUMBNAIL_STATUS_UNKNOWN))
return;
/* Check if stream delay timer has elapsed */
thumbnail->delay_timer += p_anim->delta_time;
if (thumbnail->delay_timer > p_gfx_thumb->stream_delay)
{
/* Sanity check */
if (!path_data)
{
/* No path information
* > Reset thumbnail and set missing status
* to prevent repeated load attempts */
gfx_thumbnail_reset(thumbnail);
thumbnail->status = GFX_THUMBNAIL_STATUS_MISSING;
thumbnail->alpha = 1.0f;
return;
}
/* Request image load */
gfx_thumbnail_request(
path_data, thumbnail_id, playlist, idx, thumbnail,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
}
}
/* Requests loading of the specified thumbnails via
* the stream interface
* - Must be called on each frame for the duration
* that specified thumbnails are on-screen
* - Actual load request is deferred by currently
* set stream delay
* - Function becomes a no-op once load request is
* made
* - Thumbnails loaded via this function must be
* deleted manually via gfx_thumbnail_reset()
* when they move off-screen
* NOTE 1: Must be called *after* gfx_thumbnail_set_system()
* and gfx_thumbnail_set_content*()
* NOTE 2: 'playlist' and 'idx' are only required here for
* on-demand thumbnail download support
* (an annoyance...)
* NOTE 3: This function is intended for use in situations
* where each menu entry has *two* thumbnails.
* If each entry only has a single thumbnail, use
* gfx_thumbnail_request_stream() for improved
* performance */
void gfx_thumbnail_request_streams(
gfx_thumbnail_path_data_t *path_data,
gfx_animation_t *p_anim,
playlist_t *playlist, size_t idx,
gfx_thumbnail_t *right_thumbnail,
gfx_thumbnail_t *left_thumbnail,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails)
{
bool process_right = false;
bool process_left = false;
if (!right_thumbnail || !left_thumbnail)
return;
/* Only process request if current status
* is GFX_THUMBNAIL_STATUS_UNKNOWN */
process_right = (right_thumbnail->status == GFX_THUMBNAIL_STATUS_UNKNOWN);
process_left = (left_thumbnail->status == GFX_THUMBNAIL_STATUS_UNKNOWN);
if (process_right || process_left)
{
/* Check if stream delay timer has elapsed */
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
float delta_time = p_anim->delta_time;
bool request_right = false;
bool request_left = false;
if (process_right)
{
right_thumbnail->delay_timer += delta_time;
request_right =
(right_thumbnail->delay_timer > p_gfx_thumb->stream_delay);
}
if (process_left)
{
left_thumbnail->delay_timer += delta_time;
request_left =
(left_thumbnail->delay_timer > p_gfx_thumb->stream_delay);
}
/* Check if one or more thumbnails should be requested */
if (request_right || request_left)
{
/* Sanity check */
if (!path_data)
{
/* No path information
* > Reset thumbnail and set missing status
* to prevent repeated load attempts */
if (request_right)
{
gfx_thumbnail_reset(right_thumbnail);
right_thumbnail->status = GFX_THUMBNAIL_STATUS_MISSING;
right_thumbnail->alpha = 1.0f;
}
if (request_left)
{
gfx_thumbnail_reset(left_thumbnail);
left_thumbnail->status = GFX_THUMBNAIL_STATUS_MISSING;
left_thumbnail->alpha = 1.0f;
}
return;
}
/* Request image load */
if (request_right)
gfx_thumbnail_request(
path_data, GFX_THUMBNAIL_RIGHT, playlist, idx, right_thumbnail,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (request_left)
gfx_thumbnail_request(
path_data, GFX_THUMBNAIL_LEFT, playlist, idx, left_thumbnail,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
}
}
}
/* Handles streaming of the specified thumbnail as it moves
* on/off screen
* - Must be called each frame for every on-screen entry
@ -440,13 +603,11 @@ void gfx_thumbnail_process_stream(
gfx_thumbnail_path_data_t *path_data,
gfx_animation_t *p_anim,
enum gfx_thumbnail_id thumbnail_id,
playlist_t *playlist,
size_t idx,
playlist_t *playlist, size_t idx,
gfx_thumbnail_t *thumbnail,
bool on_screen,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails
)
bool network_on_demand_thumbnails)
{
if (!thumbnail)
return;
@ -458,10 +619,10 @@ void gfx_thumbnail_process_stream(
* GFX_THUMBNAIL_STATUS_UNKNOWN */
if (thumbnail->status == GFX_THUMBNAIL_STATUS_UNKNOWN)
{
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
/* Check if stream delay timer has elapsed */
thumbnail->delay_timer += p_anim->delta_time;
thumbnail->delay_timer += p_anim->delta_time;
if (thumbnail->delay_timer > p_gfx_thumb->stream_delay)
{
@ -482,8 +643,7 @@ void gfx_thumbnail_process_stream(
gfx_thumbnail_request(
path_data, thumbnail_id, playlist, idx, thumbnail,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails
);
network_on_demand_thumbnails);
}
}
}
@ -521,8 +681,7 @@ void gfx_thumbnail_process_streams(
gfx_thumbnail_t *left_thumbnail,
bool on_screen,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails
)
bool network_on_demand_thumbnails)
{
if (!right_thumbnail || !left_thumbnail)
return;
@ -538,7 +697,7 @@ void gfx_thumbnail_process_streams(
if (process_right || process_left)
{
/* Check if stream delay timer has elapsed */
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
gfx_thumbnail_state_t *p_gfx_thumb = &gfx_thumb_st;
float delta_time = p_anim->delta_time;
bool request_right = false;
bool request_left = false;

View File

@ -171,8 +171,7 @@ void gfx_thumbnail_request(
gfx_thumbnail_path_data_t *path_data, enum gfx_thumbnail_id thumbnail_id,
playlist_t *playlist, size_t idx, gfx_thumbnail_t *thumbnail,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails
);
bool network_on_demand_thumbnails);
/* Requests loading of a specific thumbnail image file
* (may be used, for example, to load savestate images)
@ -192,6 +191,66 @@ void gfx_thumbnail_reset(gfx_thumbnail_t *thumbnail);
/* Stream processing */
/* Requests loading of the specified thumbnail via
* the stream interface
* - Must be called on each frame for the duration
* that specified thumbnail is on-screen
* - Actual load request is deferred by currently
* set stream delay
* - Function becomes a no-op once load request is
* made
* - Thumbnails loaded via this function must be
* deleted manually via gfx_thumbnail_reset()
* when they move off-screen
* NOTE 1: Must be called *after* gfx_thumbnail_set_system()
* and gfx_thumbnail_set_content*()
* NOTE 2: 'playlist' and 'idx' are only required here for
* on-demand thumbnail download support
* (an annoyance...)
* NOTE 3: This function is intended for use in situations
* where each menu entry has a *single* thumbnail.
* If each entry has two thumbnails, use
* gfx_thumbnail_request_streams() for improved
* performance */
void gfx_thumbnail_request_stream(
gfx_thumbnail_path_data_t *path_data,
gfx_animation_t *p_anim,
enum gfx_thumbnail_id thumbnail_id,
playlist_t *playlist, size_t idx,
gfx_thumbnail_t *thumbnail,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails);
/* Requests loading of the specified thumbnails via
* the stream interface
* - Must be called on each frame for the duration
* that specified thumbnails are on-screen
* - Actual load request is deferred by currently
* set stream delay
* - Function becomes a no-op once load request is
* made
* - Thumbnails loaded via this function must be
* deleted manually via gfx_thumbnail_reset()
* when they move off-screen
* NOTE 1: Must be called *after* gfx_thumbnail_set_system()
* and gfx_thumbnail_set_content*()
* NOTE 2: 'playlist' and 'idx' are only required here for
* on-demand thumbnail download support
* (an annoyance...)
* NOTE 3: This function is intended for use in situations
* where each menu entry has *two* thumbnails.
* If each entry only has a single thumbnail, use
* gfx_thumbnail_request_stream() for improved
* performance */
void gfx_thumbnail_request_streams(
gfx_thumbnail_path_data_t *path_data,
gfx_animation_t *p_anim,
playlist_t *playlist, size_t idx,
gfx_thumbnail_t *right_thumbnail,
gfx_thumbnail_t *left_thumbnail,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails);
/* Handles streaming of the specified thumbnail as it moves
* on/off screen
* - Must be called each frame for every on-screen entry
@ -208,13 +267,11 @@ void gfx_thumbnail_process_stream(
gfx_thumbnail_path_data_t *path_data,
gfx_animation_t *p_anim,
enum gfx_thumbnail_id thumbnail_id,
playlist_t *playlist,
size_t idx,
playlist_t *playlist, size_t idx,
gfx_thumbnail_t *thumbnail,
bool on_screen,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails
);
bool network_on_demand_thumbnails);
/* Handles streaming of the specified thumbnails as they move
* on/off screen
@ -236,8 +293,7 @@ void gfx_thumbnail_process_streams(
gfx_thumbnail_t *left_thumbnail,
bool on_screen,
unsigned gfx_thumbnail_upscale_threshold,
bool network_on_demand_thumbnails
);
bool network_on_demand_thumbnails);
/* Thumbnail rendering */

View File

@ -63,6 +63,8 @@
#define ANIMATION_CURSOR_DURATION 133
#define ANIMATION_CURSOR_PULSE 500
#define OZONE_THUMBNAIL_STREAM_DELAY 166.66667f
#define FONT_SIZE_FOOTER 18
#define FONT_SIZE_TITLE 36
#define FONT_SIZE_TIME 22
@ -317,6 +319,14 @@ enum
OZONE_ENTRIES_ICONS_TEXTURE_LAST
};
enum ozone_pending_thumbnail_type
{
OZONE_PENDING_THUMBNAIL_NONE = 0,
OZONE_PENDING_THUMBNAIL_RIGHT,
OZONE_PENDING_THUMBNAIL_LEFT,
OZONE_PENDING_THUMBNAIL_BOTH
};
/* This structure holds all objects + metadata
* corresponding to a particular font */
typedef struct
@ -432,6 +442,8 @@ struct ozone_handle
{
gfx_thumbnail_t right; /* uintptr_t alignment */
gfx_thumbnail_t left; /* uintptr_t alignment */
float stream_delay;
enum ozone_pending_thumbnail_type pending;
} thumbnails;
uintptr_t textures[OZONE_THEME_TEXTURE_LAST];
uintptr_t icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_LAST];
@ -3378,6 +3390,11 @@ static void ozone_entries_update_thumbnail_bar(
}
ozone->pending_hide_thumbnail_bar = false;
/* Want thumbnails to load instantly when thumbnail
* sidebar first opens */
ozone->thumbnails.stream_delay = 0.0f;
gfx_thumbnail_set_stream_delay(ozone->thumbnails.stream_delay);
}
/* Hide it */
else
@ -3989,6 +4006,11 @@ static void ozone_refresh_sidebars(
{
ozone->animations.thumbnail_bar_position = ozone->dimensions.thumbnail_bar_width;
ozone->show_thumbnail_bar = true;
/* Want thumbnails to load instantly when thumbnail
* sidebar first opens */
ozone->thumbnails.stream_delay = 0.0f;
gfx_thumbnail_set_stream_delay(ozone->thumbnails.stream_delay);
}
else
{
@ -6818,6 +6840,17 @@ static enum menu_action ozone_parse_menu_entry_action(
size_t selection;
size_t selection_total;
/* We have to override the thumbnail stream
* delay when opening the thumbnail sidebar;
* ensure that the proper value is restored
* whenever the user performs regular navigation */
if ((action != MENU_ACTION_NOOP) &&
(ozone->thumbnails.stream_delay != OZONE_THUMBNAIL_STREAM_DELAY))
{
ozone->thumbnails.stream_delay = OZONE_THUMBNAIL_STREAM_DELAY;
gfx_thumbnail_set_stream_delay(ozone->thumbnails.stream_delay);
}
/* If fullscreen thumbnail view is active, any
* valid menu action will disable it... */
if (ozone->show_fullscreen_thumbnails)
@ -7225,7 +7258,9 @@ static void *ozone_init(void **userdata, bool video_is_threaded)
ozone->animations.left_thumbnail_alpha = 1.0f;
ozone->force_metadata_display = false;
gfx_thumbnail_set_stream_delay(-1.0f);
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_NONE;
ozone->thumbnails.stream_delay = OZONE_THUMBNAIL_STREAM_DELAY;
gfx_thumbnail_set_stream_delay(ozone->thumbnails.stream_delay);
gfx_thumbnail_set_fade_duration(-1.0f);
gfx_thumbnail_set_fade_missing(false);
@ -7407,47 +7442,29 @@ static void ozone_free(void *data)
static void ozone_update_thumbnail_image(void *data)
{
ozone_handle_t *ozone = (ozone_handle_t*)data;
size_t selection = menu_navigation_get_selection();
settings_t *settings = config_get_ptr();
playlist_t *playlist = playlist_get_cached();
unsigned gfx_thumbnail_upscale_threshold = settings->uints.gfx_thumbnail_upscale_threshold;
bool network_on_demand_thumbnails = settings->bools.network_on_demand_thumbnails;
ozone_handle_t *ozone = (ozone_handle_t*)data;
if (!ozone)
return;
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_cancel_pending_requests();
gfx_thumbnail_reset(&ozone->thumbnails.right);
gfx_thumbnail_reset(&ozone->thumbnails.left);
gfx_thumbnail_request(
ozone->thumbnail_path_data,
GFX_THUMBNAIL_RIGHT,
playlist,
selection,
&ozone->thumbnails.right,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails
);
/* Right thumbnail */
if (gfx_thumbnail_is_enabled(ozone->thumbnail_path_data,
GFX_THUMBNAIL_RIGHT))
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_RIGHT;
/* Image (and video/music) content requires special
* treatment... */
if (ozone->selection_core_is_viewer)
{
/* Left thumbnail is simply reset */
gfx_thumbnail_reset(&ozone->thumbnails.left);
}
else
{
/* Left thumbnail */
gfx_thumbnail_request(
ozone->thumbnail_path_data,
GFX_THUMBNAIL_LEFT,
playlist,
selection,
&ozone->thumbnails.left,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
}
/* Left thumbnail
* > Disabled for image (and video/music) content */
if (!ozone->selection_core_is_viewer &&
gfx_thumbnail_is_enabled(ozone->thumbnail_path_data,
GFX_THUMBNAIL_LEFT))
ozone->thumbnails.pending =
(ozone->thumbnails.pending == OZONE_PENDING_THUMBNAIL_RIGHT) ?
OZONE_PENDING_THUMBNAIL_BOTH : OZONE_PENDING_THUMBNAIL_LEFT;
}
static void ozone_refresh_thumbnail_image(void *data, unsigned i)
@ -7847,6 +7864,7 @@ static void ozone_unload_thumbnail_textures(void *data)
if (!ozone)
return;
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_cancel_pending_requests();
gfx_thumbnail_reset(&ozone->thumbnails.right);
gfx_thumbnail_reset(&ozone->thumbnails.left);
@ -8646,6 +8664,59 @@ static void ozone_render(void *data,
}
}
/* Handle any pending thumbnail load requests */
if (ozone->show_thumbnail_bar &&
(ozone->thumbnails.pending != OZONE_PENDING_THUMBNAIL_NONE))
{
size_t selection = menu_navigation_get_selection();
playlist_t *playlist = playlist_get_cached();
unsigned gfx_thumbnail_upscale_threshold = settings->uints.gfx_thumbnail_upscale_threshold;
bool network_on_demand_thumbnails = settings->bools.network_on_demand_thumbnails;
switch (ozone->thumbnails.pending)
{
case OZONE_PENDING_THUMBNAIL_BOTH:
gfx_thumbnail_request_streams(
ozone->thumbnail_path_data,
p_anim,
playlist, selection,
&ozone->thumbnails.right,
&ozone->thumbnails.left,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if ((ozone->thumbnails.right.status != GFX_THUMBNAIL_STATUS_UNKNOWN) &&
(ozone->thumbnails.left.status != GFX_THUMBNAIL_STATUS_UNKNOWN))
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_NONE;
break;
case OZONE_PENDING_THUMBNAIL_RIGHT:
gfx_thumbnail_request_stream(
ozone->thumbnail_path_data,
p_anim,
GFX_THUMBNAIL_RIGHT,
playlist, selection,
&ozone->thumbnails.right,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (ozone->thumbnails.right.status != GFX_THUMBNAIL_STATUS_UNKNOWN)
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_NONE;
break;
case OZONE_PENDING_THUMBNAIL_LEFT:
gfx_thumbnail_request_stream(
ozone->thumbnail_path_data,
p_anim,
GFX_THUMBNAIL_LEFT,
playlist, selection,
&ozone->thumbnails.left,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (ozone->thumbnails.left.status != GFX_THUMBNAIL_STATUS_UNKNOWN)
ozone->thumbnails.pending = OZONE_PENDING_THUMBNAIL_NONE;
break;
default:
break;
}
}
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i);
if (i >= entries_end)

View File

@ -72,6 +72,8 @@
#define XMB_DELAY 166.66667f
#endif
#define XMB_THUMBNAIL_STREAM_DELAY 166.66667f
/* Specifies minimum period (in usec) between
* tab switch events when input repeat is
* active (i.e. when navigating between top level
@ -255,6 +257,14 @@ enum
XMB_SYSTEM_TAB_MAX_LENGTH
};
enum xmb_pending_thumbnail_type
{
XMB_PENDING_THUMBNAIL_NONE = 0,
XMB_PENDING_THUMBNAIL_RIGHT,
XMB_PENDING_THUMBNAIL_LEFT,
XMB_PENDING_THUMBNAIL_BOTH
};
/* NOTE: If you change this you HAVE to update
* xmb_alloc_node() and xmb_copy_node() */
typedef struct
@ -317,6 +327,7 @@ typedef struct xmb_handle
gfx_thumbnail_t right;
gfx_thumbnail_t left;
gfx_thumbnail_t savestate;
enum xmb_pending_thumbnail_type pending;
} thumbnails;
struct
@ -1213,70 +1224,44 @@ static void xmb_update_savestate_thumbnail_path(void *data, unsigned i)
static void xmb_update_thumbnail_image(void *data)
{
xmb_handle_t *xmb = (xmb_handle_t*)data;
const char *core_name = NULL;
xmb_handle_t *xmb = (xmb_handle_t*)data;
size_t selection = menu_navigation_get_selection();
playlist_t *playlist = playlist_get_cached();
settings_t *settings = config_get_ptr();
unsigned thumbnail_upscale_threshold = settings->uints.gfx_thumbnail_upscale_threshold;
bool network_on_demand_thumbnails = settings->bools.network_on_demand_thumbnails;
if (!xmb)
return;
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_cancel_pending_requests();
gfx_thumbnail_reset(&xmb->thumbnails.right);
gfx_thumbnail_reset(&xmb->thumbnails.left);
/* imageviewer content requires special treatment... */
gfx_thumbnail_get_core_name(xmb->thumbnail_path_data, &core_name);
if (string_is_equal(core_name, "imageviewer"))
{
gfx_thumbnail_reset(&xmb->thumbnails.right);
gfx_thumbnail_reset(&xmb->thumbnails.left);
/* Right thumbnail */
if (gfx_thumbnail_is_enabled(xmb->thumbnail_path_data,
GFX_THUMBNAIL_RIGHT))
gfx_thumbnail_request(
xmb->thumbnail_path_data,
GFX_THUMBNAIL_RIGHT,
playlist,
selection,
&xmb->thumbnails.right,
thumbnail_upscale_threshold,
network_on_demand_thumbnails);
GFX_THUMBNAIL_RIGHT))
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_RIGHT;
/* Left thumbnail */
else if (gfx_thumbnail_is_enabled(xmb->thumbnail_path_data,
GFX_THUMBNAIL_LEFT))
gfx_thumbnail_request(
xmb->thumbnail_path_data,
GFX_THUMBNAIL_LEFT,
playlist,
selection,
&xmb->thumbnails.left,
thumbnail_upscale_threshold,
network_on_demand_thumbnails);
GFX_THUMBNAIL_LEFT))
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_LEFT;
}
else
{
/* Right thumbnail */
gfx_thumbnail_request(
xmb->thumbnail_path_data,
GFX_THUMBNAIL_RIGHT,
playlist,
selection,
&xmb->thumbnails.right,
thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (gfx_thumbnail_is_enabled(xmb->thumbnail_path_data,
GFX_THUMBNAIL_RIGHT))
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_RIGHT;
/* Left thumbnail */
gfx_thumbnail_request(
xmb->thumbnail_path_data,
GFX_THUMBNAIL_LEFT,
playlist,
selection,
&xmb->thumbnails.left,
thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (gfx_thumbnail_is_enabled(xmb->thumbnail_path_data,
GFX_THUMBNAIL_LEFT))
xmb->thumbnails.pending =
(xmb->thumbnails.pending == XMB_PENDING_THUMBNAIL_RIGHT) ?
XMB_PENDING_THUMBNAIL_BOTH : XMB_PENDING_THUMBNAIL_LEFT;
}
}
@ -1338,6 +1323,7 @@ static void xmb_unload_thumbnail_textures(void *data)
if (!xmb)
return;
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_cancel_pending_requests();
gfx_thumbnail_reset(&xmb->thumbnails.right);
gfx_thumbnail_reset(&xmb->thumbnails.left);
@ -1577,6 +1563,7 @@ static void xmb_selection_pointer_changed(
* content + right/left thumbnails
* (otherwise last loaded thumbnail will
* persist, and be shown on the wrong entry) */
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_set_content(xmb->thumbnail_path_data, NULL);
gfx_thumbnail_cancel_pending_requests();
gfx_thumbnail_reset(&xmb->thumbnails.right);
@ -2563,6 +2550,7 @@ static void xmb_populate_entries(void *data,
* file list is populated... */
if (xmb->is_file_list)
{
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_set_content(xmb->thumbnail_path_data, NULL);
gfx_thumbnail_cancel_pending_requests();
gfx_thumbnail_reset(&xmb->thumbnails.right);
@ -4286,6 +4274,58 @@ static void xmb_render(void *data,
}
}
/* Handle any pending thumbnail load requests */
if (xmb->thumbnails.pending != XMB_PENDING_THUMBNAIL_NONE)
{
size_t selection = menu_navigation_get_selection();
playlist_t *playlist = playlist_get_cached();
unsigned gfx_thumbnail_upscale_threshold = settings->uints.gfx_thumbnail_upscale_threshold;
bool network_on_demand_thumbnails = settings->bools.network_on_demand_thumbnails;
switch (xmb->thumbnails.pending)
{
case XMB_PENDING_THUMBNAIL_BOTH:
gfx_thumbnail_request_streams(
xmb->thumbnail_path_data,
p_anim,
playlist, selection,
&xmb->thumbnails.right,
&xmb->thumbnails.left,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if ((xmb->thumbnails.right.status != GFX_THUMBNAIL_STATUS_UNKNOWN) &&
(xmb->thumbnails.left.status != GFX_THUMBNAIL_STATUS_UNKNOWN))
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
break;
case XMB_PENDING_THUMBNAIL_RIGHT:
gfx_thumbnail_request_stream(
xmb->thumbnail_path_data,
p_anim,
GFX_THUMBNAIL_RIGHT,
playlist, selection,
&xmb->thumbnails.right,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (xmb->thumbnails.right.status != GFX_THUMBNAIL_STATUS_UNKNOWN)
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
break;
case XMB_PENDING_THUMBNAIL_LEFT:
gfx_thumbnail_request_stream(
xmb->thumbnail_path_data,
p_anim,
GFX_THUMBNAIL_LEFT,
playlist, selection,
&xmb->thumbnails.left,
gfx_thumbnail_upscale_threshold,
network_on_demand_thumbnails);
if (xmb->thumbnails.left.status != GFX_THUMBNAIL_STATUS_UNKNOWN)
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
break;
default:
break;
}
}
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i);
if (i >= end)
@ -6008,7 +6048,8 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
xmb->fullscreen_thumbnail_selection = 0;
xmb->fullscreen_thumbnail_label[0] = '\0';
gfx_thumbnail_set_stream_delay(-1.0f);
xmb->thumbnails.pending = XMB_PENDING_THUMBNAIL_NONE;
gfx_thumbnail_set_stream_delay(XMB_THUMBNAIL_STREAM_DELAY);
gfx_thumbnail_set_fade_duration(-1.0f);
gfx_thumbnail_set_fade_missing(false);