mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-09 17:29:21 -10:00
gfx/gfx_display.c (+46) — Adds #include "../tasks/tasks_internal.h". Adds gfx_display_load_icon(), the single dispatch function. A #if defined(__ANDROID__) sets GFX_DISPLAY_ICON_LOAD_SYNCHRONOUS which routes to gfx_display_reset_icon_texture() (blocking file read + GPU upload in one call, pre-async behavior). All other platforms route to task_push_icon_load() (async task queue).
gfx/gfx_display.h (+20) — Declares gfx_display_load_icon() with doc comment explaining the mechanism, that generation/generation_ptr are async-only, and that callers should use this instead of task_push_icon_load() directly.
gfx/gfx_widgets.c (-4/+5) — Replaces task_push_icon_load() with gfx_display_load_icon() in the widget icon loading loop. Updates comments to be path-neutral ("When loads complete" instead of "When async loads complete").
gfx/widgets/gfx_widget_volume.c (-1/+1) — Replaces task_push_icon_load() with gfx_display_load_icon() for volume indicator icons.
menu/drivers/ozone.c (-6/+6) — Replaces 6 task_push_icon_load() calls with gfx_display_load_icon(): theme textures, horizontal list icons, main textures, sidebar tab textures, entry icons.
menu/drivers/materialui.c (-2/+2) — Replaces 2 task_push_icon_load() calls with gfx_display_load_icon(): playlist icons and main texture list.
menu/drivers/xmb.c (-3/+3) — Replaces 3 task_push_icon_load() calls with gfx_display_load_icon(): horizontal list icons (system + content) and context reset textures.
menu/menu_explore.c (-1/+1) — Replaces task_push_icon_load() with gfx_display_load_icon() for explore view system icons.
menu/menu_contentless_cores.c (-2/+2) — Replaces 2 task_push_icon_load() calls with gfx_display_load_icon(): fallback icon and per-core icons.
tasks/task_file_transfer.c (-9) — Reverts b8c7860: removes the #ifdef __ANDROID__ that forced synchronous NBIO file transfer. Unnecessary since Android no longer enters the async icon path.
tasks/task_image.c (-14) — Reverts b8c7860: removes the two #ifdef __ANDROID__ blocks that forced synchronous image decode loops. Same reason — Android icons load synchronously one layer up, never reaching this code.
Net: 86 insertions, 42 deletions across 11 files. One #if defined(__ANDROID__) in one file controls everything.
This commit is contained in:
1 parent
b8c78609ee
commit
5c1e31a81f
11 files changed
+86
-42
No files matched your search
@@ -19,6 +19,7 @@
|
||||
#include "gfx_display.h"
|
||||
|
||||
#include "../configuration.h"
|
||||
#include "../tasks/tasks_internal.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
#ifdef HAVE_MIST
|
||||
@@ -1175,6 +1176,51 @@ bool gfx_display_reset_icon_texture(
|
||||
return true;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------
|
||||
* Platform-adaptive icon/texture loading
|
||||
*
|
||||
* Dispatches to either the synchronous (blocking) or asynchronous
|
||||
* (task-queue) icon loading path depending on the platform.
|
||||
*
|
||||
* Platforms that define GFX_DISPLAY_ICON_LOAD_SYNCHRONOUS get the
|
||||
* pre-async behavior: image_texture_load -> video_driver_texture_load
|
||||
* in one call, no task queue involvement. This avoids frame-spread
|
||||
* I/O and GL context contention on platforms where the async path is
|
||||
* actually slower (e.g. Android behind SAF / fuse storage).
|
||||
*
|
||||
* To opt a new platform into the synchronous path, add it to the
|
||||
* ifdef below.
|
||||
* ----------------------------------------------------------------------- */
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#define GFX_DISPLAY_ICON_LOAD_SYNCHRONOUS
|
||||
#endif
|
||||
|
||||
bool gfx_display_load_icon(
|
||||
const char *fullpath,
|
||||
bool supports_rgba,
|
||||
uintptr_t *target_texture,
|
||||
uint64_t generation,
|
||||
uint64_t *generation_ptr)
|
||||
{
|
||||
#ifdef GFX_DISPLAY_ICON_LOAD_SYNCHRONOUS
|
||||
/* Synchronous path - identical to pre-async behavior.
|
||||
* Generation counter is irrelevant: the load completes
|
||||
* before this function returns, so there is no in-flight
|
||||
* callback that could write to a freed pointer. */
|
||||
(void)supports_rgba;
|
||||
(void)generation;
|
||||
(void)generation_ptr;
|
||||
return gfx_display_reset_icon_texture(
|
||||
fullpath, target_texture,
|
||||
TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL);
|
||||
#else
|
||||
return task_push_icon_load(
|
||||
fullpath, supports_rgba,
|
||||
target_texture, generation, generation_ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void gfx_display_deinit_white_texture(void)
|
||||
{
|
||||
if (gfx_white_texture)
|
||||
|
||||
@@ -293,6 +293,26 @@ bool gfx_display_reset_icon_texture(
|
||||
uintptr_t *item, enum texture_filter_type filter_type,
|
||||
unsigned *width, unsigned *height);
|
||||
|
||||
/* Platform-adaptive icon/texture loading.
|
||||
*
|
||||
* On platforms where async task-based image loading is detrimental
|
||||
* to performance (e.g. Android with SAF I/O overhead), falls back
|
||||
* to synchronous loading identical to the pre-async behavior.
|
||||
*
|
||||
* All menu drivers and gfx_widgets should call this instead of
|
||||
* task_push_icon_load() directly so that adding a new platform
|
||||
* to the synchronous path requires changing only one place.
|
||||
*
|
||||
* |generation| / |generation_ptr| are only used on the async path
|
||||
* to guard against stale callbacks; on the synchronous path they
|
||||
* are ignored (the load completes before the function returns). */
|
||||
bool gfx_display_load_icon(
|
||||
const char *fullpath,
|
||||
bool supports_rgba,
|
||||
uintptr_t *target_texture,
|
||||
uint64_t generation,
|
||||
uint64_t *generation_ptr);
|
||||
|
||||
bool gfx_display_reset_textures_list_buffer(
|
||||
uintptr_t *item,
|
||||
enum texture_filter_type filter_type,
|
||||
|
||||
+5
-4
@@ -2006,11 +2006,12 @@ static void gfx_widgets_context_reset(
|
||||
widget_icon_load_gen++;
|
||||
|
||||
/* Start with no-icons layout — text positions are correct for
|
||||
* text-only rendering. When async loads complete, the callback
|
||||
* sets MSG_QUEUE_HAS_ICONS and recomputes icon-dependent layout. */
|
||||
* text-only rendering. When loads complete (immediately on sync
|
||||
* platforms, via callback on async), the frame-loop detects
|
||||
* non-zero textures and recomputes icon-dependent layout. */
|
||||
p_dispwidget->flags &= ~DISPGFX_WIDGET_FLAG_MSG_QUEUE_HAS_ICONS;
|
||||
|
||||
/* Queue async icon loads */
|
||||
/* Load icons */
|
||||
for (i = 0; i < MENU_WIDGETS_ICON_LAST; i++)
|
||||
{
|
||||
char texpath[PATH_MAX_LENGTH];
|
||||
@@ -2018,7 +2019,7 @@ static void gfx_widgets_context_reset(
|
||||
p_dispwidget->monochrome_png_path,
|
||||
gfx_widgets_icons_names[i],
|
||||
sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&p_dispwidget->gfx_widgets_icons_textures[i],
|
||||
widget_icon_load_gen, &widget_icon_load_gen);
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ static void gfx_widget_volume_context_reset(bool is_threaded,
|
||||
char texpath[PATH_MAX_LENGTH];
|
||||
fill_pathname_join_special(texpath,
|
||||
menu_png_path, ICONS_NAMES[i], sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&state->textures[i], volume_icon_load_gen,
|
||||
&volume_icon_load_gen);
|
||||
}
|
||||
|
||||
@@ -2293,7 +2293,7 @@ static void materialui_context_reset_playlist_icons(
|
||||
fill_pathname_join_special(texpath,
|
||||
mui->sysicons_path, image_file,
|
||||
sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&mui->textures.playlist.icons[i].image,
|
||||
mui_icon_load_gen, &mui_icon_load_gen);
|
||||
}
|
||||
@@ -2569,7 +2569,7 @@ static void materialui_context_reset_textures(materialui_handle_t *mui)
|
||||
fill_pathname_join_special(texpath,
|
||||
mui->icons_path, materialui_texture_path(i),
|
||||
sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&mui->textures.list[i], mui_icon_load_gen,
|
||||
&mui_icon_load_gen);
|
||||
}
|
||||
|
||||
@@ -2951,7 +2951,7 @@ static void ozone_reset_theme_textures(ozone_handle_t *ozone)
|
||||
fill_pathname_join_special(texpath,
|
||||
theme_path, OZONE_THEME_TEXTURES_FILES[i],
|
||||
sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&theme->textures[i], ozone_ctx_icon_load_gen,
|
||||
&ozone_ctx_icon_load_gen);
|
||||
}
|
||||
@@ -5136,7 +5136,7 @@ static void ozone_context_reset_horizontal_list(ozone_handle_t *ozone)
|
||||
texturepath, ozone->icons_path, "default.png",
|
||||
sizeof(texturepath));
|
||||
|
||||
task_push_icon_load(texturepath, supports_rgba,
|
||||
gfx_display_load_icon(texturepath, supports_rgba,
|
||||
&node->icon, ozone_icon_load_gen,
|
||||
&ozone_icon_load_gen);
|
||||
|
||||
@@ -5149,7 +5149,7 @@ static void ozone_context_reset_horizontal_list(ozone_handle_t *ozone)
|
||||
fill_pathname_join_delim(texturepath, ozone->icons_path_default,
|
||||
"content.png", '-', sizeof(texturepath));
|
||||
|
||||
task_push_icon_load(texturepath, supports_rgba,
|
||||
gfx_display_load_icon(texturepath, supports_rgba,
|
||||
&node->content_icon, ozone_icon_load_gen,
|
||||
&ozone_icon_load_gen);
|
||||
|
||||
@@ -9831,7 +9831,7 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
fill_pathname_join_special(texpath,
|
||||
ozone->png_path, OZONE_TEXTURES_FILES[i],
|
||||
sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&ozone->textures[i], ozone_ctx_icon_load_gen,
|
||||
&ozone_ctx_icon_load_gen);
|
||||
}
|
||||
@@ -9855,7 +9855,7 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
sizeof(texpath));
|
||||
break;
|
||||
}
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&ozone->tab_textures[i], ozone_ctx_icon_load_gen,
|
||||
&ozone_ctx_icon_load_gen);
|
||||
}
|
||||
@@ -9870,7 +9870,7 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
fill_pathname_join_special(texpath,
|
||||
ozone->icons_path, ozone_entries_icon_texture_path(i),
|
||||
sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&ozone->icons_textures[i], ozone_ctx_icon_load_gen,
|
||||
&ozone_ctx_icon_load_gen);
|
||||
}
|
||||
|
||||
+3
-3
@@ -2988,7 +2988,7 @@ static void xmb_context_reset_horizontal_list(xmb_handle_t *xmb)
|
||||
strlcpy(texturepath + __len, ".png", sizeof(texturepath) - __len);
|
||||
}
|
||||
|
||||
task_push_icon_load(texturepath, supports_rgba,
|
||||
gfx_display_load_icon(texturepath, supports_rgba,
|
||||
&node->icon, xmb_icon_load_gen,
|
||||
&xmb_icon_load_gen);
|
||||
|
||||
@@ -3000,7 +3000,7 @@ static void xmb_context_reset_horizontal_list(xmb_handle_t *xmb)
|
||||
fill_pathname_join_delim(texturepath, icons_path_default,
|
||||
FILE_PATH_CONTENT_BASENAME, '-', sizeof(texturepath));
|
||||
|
||||
task_push_icon_load(texturepath, supports_rgba,
|
||||
gfx_display_load_icon(texturepath, supports_rgba,
|
||||
&node->content_icon, xmb_icon_load_gen,
|
||||
&xmb_icon_load_gen);
|
||||
|
||||
@@ -6674,7 +6674,7 @@ static void xmb_context_reset_textures(
|
||||
|
||||
fill_pathname_join_special(texpath,
|
||||
iconpath, texture_path, sizeof(texpath));
|
||||
task_push_icon_load(texpath, supports_rgba,
|
||||
gfx_display_load_icon(texpath, supports_rgba,
|
||||
&xmb->textures.list[i], xmb_ctx_icon_load_gen,
|
||||
&xmb_ctx_icon_load_gen);
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ static void contentless_cores_load_icons(contentless_cores_state_t *state)
|
||||
CONTENTLESS_CORE_ICON_DEFAULT, sizeof(icon_path));
|
||||
|
||||
if (path_is_valid(icon_path))
|
||||
task_push_icon_load(icon_path, rgba_supported,
|
||||
gfx_display_load_icon(icon_path, rgba_supported,
|
||||
&state->icons->fallback, contentless_icon_load_gen,
|
||||
&contentless_icon_load_gen);
|
||||
|
||||
@@ -338,7 +338,7 @@ static void contentless_cores_load_icons(contentless_cores_state_t *state)
|
||||
RHMAP_SET_STR(state->icons->system,
|
||||
core_info->core_file_id.str, icon);
|
||||
|
||||
task_push_icon_load(icon_path, rgba_supported,
|
||||
gfx_display_load_icon(icon_path, rgba_supported,
|
||||
icon, contentless_icon_load_gen,
|
||||
&contentless_icon_load_gen);
|
||||
}
|
||||
|
||||
+1
-1
@@ -440,7 +440,7 @@ static void explore_load_icons(explore_state_t *state)
|
||||
if (!path_is_valid(path))
|
||||
continue;
|
||||
|
||||
task_push_icon_load(path, supports_rgba,
|
||||
gfx_display_load_icon(path, supports_rgba,
|
||||
&state->icons[i], explore_icon_load_gen,
|
||||
&explore_icon_load_gen);
|
||||
}
|
||||
|
||||
@@ -53,14 +53,6 @@ static int task_file_transfer_iterate_transfer(nbio_handle_t *nbio)
|
||||
iters = nbio->pos_increment ? nbio->pos_increment
|
||||
: NBIO_DEFAULT_POS_INCREMENT;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* Android: complete the entire file read in one pass to avoid
|
||||
* spreading I/O across frames, which causes menu freezes and
|
||||
* icon glitches when combined with async image decoding. */
|
||||
(void)iters;
|
||||
while (!nbio_iterate(nbio->handle));
|
||||
return -1;
|
||||
#else
|
||||
for (i = 0; i < iters; i++)
|
||||
{
|
||||
if (nbio_iterate(nbio->handle))
|
||||
@@ -68,7 +60,6 @@ static int task_file_transfer_iterate_transfer(nbio_handle_t *nbio)
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int task_file_transfer_iterate_parse(nbio_handle_t *nbio)
|
||||
|
||||
@@ -151,16 +151,8 @@ static int task_image_iterate_process_transfer(struct nbio_image_handle *image)
|
||||
if ((retval = task_image_process(image, &width, &height))
|
||||
!= IMAGE_PROCESS_NEXT)
|
||||
break;
|
||||
#ifndef __ANDROID__
|
||||
/* On non-Android platforms, budget image processing across
|
||||
* multiple frames to avoid blocking the UI thread.
|
||||
* On Android this causes freezes and icon glitches with all
|
||||
* menu drivers, so we complete the entire decode in one pass. */
|
||||
}while (cpu_features_get_time_usec() - start_time
|
||||
< image->frame_duration);
|
||||
#else
|
||||
}while (1);
|
||||
#endif
|
||||
|
||||
if (retval == IMAGE_PROCESS_NEXT)
|
||||
return 0;
|
||||
@@ -358,14 +350,8 @@ bool task_image_load_handler(retro_task_t *task)
|
||||
image->status = IMAGE_STATUS_TRANSFER_PARSE;
|
||||
break;
|
||||
}
|
||||
#ifndef __ANDROID__
|
||||
}while (cpu_features_get_time_usec() - start_time
|
||||
< image->frame_duration);
|
||||
#else
|
||||
/* Android: complete transfer in one pass to avoid
|
||||
* context contention causing freezes/glitches */
|
||||
}while (1);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case IMAGE_STATUS_PROCESS_TRANSFER_PARSE:
|
||||
|
||||
Reference in new issue
Block a user