MENU/GFX: Eliminate data races on mutable static color arrays

The menu drivers and widget system use file-scope and function-scope
static float arrays as scratch buffers for color data passed to the
GPU display backends.  These arrays are mutated per-frame via
gfx_display_set_alpha() and read by D3D12/Vulkan backends through
draw.color pointers.  Under threaded video, the GPU command pipeline
from frame N-1 can still be consuming a color pointer while frame N
overwrites the underlying static, producing torn alpha values,
visual corruption, or driver-level validation errors.

This patch moves all mutable color data out of shared static storage
and into either stack locals (per-frame scratch) or per-instance
struct members (persistent theme state), so each frame operates on
its own copy.

The full rendering pipeline was audited:

  menu/drivers/xmb.c          - 5 statics fixed (see below)
  menu/drivers/ozone.c        - 14 statics fixed, 94 arrays
                                 marked const (see below)
  menu/drivers/rgui.c         - clean (software-rendered,
                                 no GPU color pipeline)
  menu/drivers/materialui.c   - clean (all colors per-instance)
  gfx/gfx_display.c           - 1 static fixed (see below)
  gfx/gfx_widgets.c           - 10 statics fixed (see below)
  gfx/widgets/ (4 files)      - 4 statics fixed (see below)
  gfx/gfx_animation.c         - clean (no static color arrays;
                                 tween writes into menu driver
                                 state are the write side of the
                                 same races mitigated on the read
                                 side by the frame-local copies
                                 introduced in this patch)
  gfx/gfx_thumbnail.c         - not addressed here; has structural
                                 races on gfx_thumbnail_t fields
                                 written from task callbacks that
                                 require atomic operations or
                                 deferred callback delivery

XMB changes (menu/drivers/xmb.c):

- xmb_coord_shadow: stack local in xmb_draw_icon().
- xmb_coord_black, xmb_coord_white: replaced with static const
  templates; mutable copies are stack locals in xmb_frame().
- xmb_item_color: base RGB stored in xmb_handle_t.item_color_base,
  stack-local scratch copy in xmb_frame().
  xmb_draw_no_thumbnail_available() and
  xmb_draw_fullscreen_thumbnails() gain a float *color parameter.
- xmb_scale_mod: moved into xmb_handle_t.scale_mod.
  xmb_init_scale_mod() takes a float * target parameter.

Ozone changes (menu/drivers/ozone.c):

- 64 sidebar gradient/background/background_libretro_running
  file-scope arrays: marked static const.  Mutable per-instance
  copies added to ozone_handle (sidebar_top_gradient,
  sidebar_background, sidebar_bottom_gradient, background_running).
  Initialized on theme change, mutated per-frame for alpha.
- 30 border color arrays: marked static const (hardening).
- ozone_theme_t sidebar/cursor/background pointers: const float *.
- ozone_animate_cursor() target parameter: const float *.
- ozone_backdrop, ozone_osk_backdrop, fullscreen thumbnail
  background_color: function-scope statics replaced with stack
  locals.
- ozone_frame background_color: copied into stack buffer before
  alpha mutation when pointing at static theme struct member.
- Removed function-scope static last_alpha cache guards in cursor
  and selection draw helpers (caused stale comparisons after theme
  switches; saved only four float writes per frame).
- Removed unnecessary static storage on background_running_alpha
  temporaries.

gfx_display changes (gfx/gfx_display.c):

- gfx_display_draw_bg(): static struct video_coords replaced with
  stack local.  The struct is fully overwritten on every call and
  its address is stored in the caller's draw struct; the static
  qualifier served no caching purpose and created a shared mutable
  surface that could be overwritten by a concurrent call.

gfx_widgets changes (gfx/gfx_widgets.c):

- gfx_widgets_draw_task_msg(): 5 static float[16] arrays
  (msg_queue_background, msg_queue_bar, msg_queue_task_progress,
  msg_queue_task_negative, msg_queue_task_positive) replaced with
  stack locals.
- gfx_widgets_draw_regular_msg(): 5 static float[16] arrays
  (msg_queue_info_blue/yellow/red/green, msg_queue_bar) replaced
  with stack locals.

Widget sub-file changes:

- gfx_widget_achievement_popup.c: static pure_white -> stack local.
- gfx_widget_leaderboard_display.c: static pure_white -> stack local.
- gfx_widget_screenshot.c: static pure_white -> stack local.
- gfx_widget_volume.c: static pure_white -> stack local.

No behavioral or visual changes.  Stack cost is negligible (~350
bytes in xmb_frame, ~200 bytes across ozone draw helpers, ~40
bytes in gfx_display_draw_bg, ~640 bytes across widget draw
functions).

Files changed: 8
 gfx/gfx_display.c
 gfx/gfx_widgets.c
 gfx/widgets/gfx_widget_achievement_popup.c
 gfx/widgets/gfx_widget_leaderboard_display.c
This commit is contained in:
U-DESKTOP-SPFP6AQ\twistedtechre committed 2026-04-16 04:19:05 +02:00
1 parent 97ac67e21f
commit 0abe6dc47d
8 files changed
+243 -212

No files matched your search

+1 -1
View File
@@ -461,7 +461,7 @@ void gfx_display_draw_bg(
void *userdata, bool add_opacity_to_wallpaper,
float override_opacity)
{
static struct video_coords coords;
struct video_coords coords;
const float *new_vertex = NULL;
const float *new_tex_coord = NULL;
gfx_display_ctx_driver_t *dispctx = p_disp->dispctx;
+10 -10
View File
@@ -1137,11 +1137,11 @@ static void gfx_widgets_draw_task_msg(
unsigned video_width,
unsigned video_height)
{
static float msg_queue_background[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_DEFAULT, 1.0f);
static float msg_queue_bar[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_MARGIN, 1.0f);
static float msg_queue_task_progress[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_PROGRESS, 1.0f);
static float msg_queue_task_negative[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_RED, 1.0f);
static float msg_queue_task_positive[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_GREEN, 1.0f);
float msg_queue_background[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_DEFAULT, 1.0f);
float msg_queue_bar[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_MARGIN, 1.0f);
float msg_queue_task_progress[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_PROGRESS, 1.0f);
float msg_queue_task_negative[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_RED, 1.0f);
float msg_queue_task_positive[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_GREEN, 1.0f);
unsigned msg_queue_height = p_dispwidget->msg_queue_height;
unsigned text_color;
@@ -1370,11 +1370,11 @@ static void gfx_widgets_draw_regular_msg(
unsigned video_width,
unsigned video_height)
{
static float msg_queue_info_blue[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_BLUE, 1.0f);
static float msg_queue_info_yellow[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_YELLOW, 1.0f);
static float msg_queue_info_red[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_RED, 1.0f);
static float msg_queue_info_green[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_GREEN, 1.0f);
static float msg_queue_bar[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_MARGIN, 1.0f);
float msg_queue_info_blue[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_BLUE, 1.0f);
float msg_queue_info_yellow[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_YELLOW, 1.0f);
float msg_queue_info_red[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_RED, 1.0f);
float msg_queue_info_green[16] = COLOR_HEX_TO_FLOAT(ICON_COLOR_GREEN, 1.0f);
float msg_queue_bar[16] = COLOR_HEX_TO_FLOAT(BG_COLOR_MARGIN, 1.0f);
float* msg_queue_info;
float text_y_base;
unsigned rect_width;
+1 -1
View File
@@ -142,7 +142,7 @@ static void gfx_widget_achievement_popup_frame(void* data, void* userdata)
#endif
{
static float pure_white[16] = {
float pure_white[16] = {
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
+1 -1
View File
@@ -132,7 +132,7 @@ static void gfx_widget_leaderboard_display_frame(void* data, void* userdata)
#endif
{
static float pure_white[16] = {
float pure_white[16] = {
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
+1 -1
View File
@@ -231,7 +231,7 @@ static void gfx_widget_screenshot_context_destroy(void)
static void gfx_widget_screenshot_frame(void* data, void *user_data)
{
static float pure_white[16] = {
float pure_white[16] = {
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
+1 -1
View File
@@ -86,7 +86,7 @@ static gfx_widget_volume_state_t p_w_volume_st = {
static void gfx_widget_volume_frame(void* data, void *user_data)
{
static float pure_white[16] = {
float pure_white[16] = {
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
1.00, 1.00, 1.00, 1.00,
+151 -135
View File
@@ -346,7 +346,7 @@ typedef struct ozone_theme
{
/* Background color */
float background[16];
float *background_libretro_running;
const float *background_libretro_running;
/* Float colors for quads and icons */
float header_footer_separator[16];
@@ -367,14 +367,14 @@ typedef struct ozone_theme
/* Screensaver 'tint' (RGB24) */
uint32_t screensaver_tint;
/* Sidebar color */
float *sidebar_background;
float *sidebar_top_gradient;
float *sidebar_bottom_gradient;
/* Sidebar color (const templates — mutable copies live in ozone_handle) */
const float *sidebar_background;
const float *sidebar_top_gradient;
const float *sidebar_bottom_gradient;
/* Fancy cursor colors */
float *cursor_border_0;
float *cursor_border_1;
/* Fancy cursor colors (read-only, used as memcpy source) */
const float *cursor_border_0;
const float *cursor_border_1;
uintptr_t textures[OZONE_THEME_TEXTURE_LAST];
@@ -662,397 +662,406 @@ struct ozone_handle
float amplitude;
enum menu_action direction;
} cursor_wiggle_state;
/* Per-instance mutable copies of theme sidebar/background colors.
* The file-scope theme arrays are now const; these are copied on
* theme change and mutated per-frame for alpha. Avoids data races
* with threaded video backends (was file-scope mutable statics). */
float sidebar_top_gradient[16];
float sidebar_background[16];
float sidebar_bottom_gradient[16];
float background_running[16];
};
typedef struct ozone_handle ozone_handle_t;
static float ozone_sidebar_gradient_top_light[16] = {
static const float ozone_sidebar_gradient_top_light[16] = {
0.94f, 0.94f, 0.94f, 1.00f,
0.94f, 0.94f, 0.94f, 1.00f,
0.922f, 0.922f, 0.922f, 1.00f,
0.922f, 0.922f, 0.922f, 1.00f,
};
static float ozone_sidebar_gradient_bottom_light[16] = {
static const float ozone_sidebar_gradient_bottom_light[16] = {
0.922f, 0.922f, 0.922f, 1.00f,
0.922f, 0.922f, 0.922f, 1.00f,
0.94f, 0.94f, 0.94f, 1.00f,
0.94f, 0.94f, 0.94f, 1.00f,
};
static float ozone_sidebar_gradient_top_dark[16] = {
static const float ozone_sidebar_gradient_top_dark[16] = {
0.2f, 0.2f, 0.2f, 1.00f,
0.2f, 0.2f, 0.2f, 1.00f,
0.18f, 0.18f, 0.18f, 1.00f,
0.18f, 0.18f, 0.18f, 1.00f,
};
static float ozone_sidebar_gradient_bottom_dark[16] = {
static const float ozone_sidebar_gradient_bottom_dark[16] = {
0.18f, 0.18f, 0.18f, 1.00f,
0.18f, 0.18f, 0.18f, 1.00f,
0.2f, 0.2f, 0.2f, 1.00f,
0.2f, 0.2f, 0.2f, 1.00f,
};
static float ozone_sidebar_gradient_top_nord[16] = {
static const float ozone_sidebar_gradient_top_nord[16] = {
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
0.1921569f, 0.2196078f, 0.2705882f, 0.9f,
0.1921569f, 0.2196078f, 0.2705882f, 0.9f,
};
static float ozone_sidebar_gradient_bottom_nord[16] = {
static const float ozone_sidebar_gradient_bottom_nord[16] = {
0.1921569f, 0.2196078f, 0.2705882f, 0.9f,
0.1921569f, 0.2196078f, 0.2705882f, 0.9f,
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
};
static float ozone_sidebar_gradient_top_gruvbox_dark[16] = {
static const float ozone_sidebar_gradient_top_gruvbox_dark[16] = {
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
0.1686275f, 0.1686275f, 0.1686275f, 0.9f,
0.1686275f, 0.1686275f, 0.1686275f, 0.9f,
};
static float ozone_sidebar_gradient_bottom_gruvbox_dark[16] = {
static const float ozone_sidebar_gradient_bottom_gruvbox_dark[16] = {
0.1686275f, 0.1686275f, 0.1686275f, 0.9f,
0.1686275f, 0.1686275f, 0.1686275f, 0.9f,
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
};
static float ozone_sidebar_gradient_top_boysenberry[16] = {
static const float ozone_sidebar_gradient_top_boysenberry[16] = {
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
0.19215686274f, 0.0f, 0.04705882352f, 1.00f,
0.19215686274f, 0.0f, 0.04705882352f, 1.00f,
};
static float ozone_sidebar_gradient_bottom_boysenberry[16] = {
static const float ozone_sidebar_gradient_bottom_boysenberry[16] = {
0.19215686274f, 0.0f, 0.04705882352f, 1.00f,
0.19215686274f, 0.0f, 0.04705882352f, 1.00f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
};
static float ozone_sidebar_gradient_top_hacking_the_kernel[16] = {
static const float ozone_sidebar_gradient_top_hacking_the_kernel[16] = {
0.0f, 0.13333333f, 0.0f, 1.0f,
0.0f, 0.13333333f, 0.0f, 1.0f,
0.0f, 0.13333333f, 0.0f, 1.0f,
0.0f, 0.13333333f, 0.0f, 1.0f,
};
static float ozone_sidebar_gradient_bottom_hacking_the_kernel[16] = {
static const float ozone_sidebar_gradient_bottom_hacking_the_kernel[16] = {
0.0f, 0.0666666f, 0.0f, 1.0f,
0.0f, 0.0666666f, 0.0f, 1.0f,
0.0f, 0.13333333f, 0.0f, 1.0f,
0.0f, 0.13333333f, 0.0f, 1.0f,
};
static float ozone_sidebar_gradient_top_twilight_zone[16] = {
static const float ozone_sidebar_gradient_top_twilight_zone[16] = {
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
};
static float ozone_sidebar_gradient_bottom_twilight_zone[16] = {
static const float ozone_sidebar_gradient_bottom_twilight_zone[16] = {
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
};
static float ozone_sidebar_gradient_top_dracula[16] = {
static const float ozone_sidebar_gradient_top_dracula[16] = {
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
};
static float ozone_sidebar_gradient_bottom_dracula[16] = {
static const float ozone_sidebar_gradient_bottom_dracula[16] = {
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
};
static float ozone_sidebar_gradient_top_evergarden[16] =
static const float ozone_sidebar_gradient_top_evergarden[16] =
COLOR_HEX_TO_FLOAT(0x1C2225, 1.0f);
static float ozone_sidebar_gradient_bottom_evergarden[16] =
static const float ozone_sidebar_gradient_bottom_evergarden[16] =
COLOR_HEX_TO_FLOAT(0x1C2225, 1.0f);
static float ozone_sidebar_gradient_top_selenium[16] = {
static const float ozone_sidebar_gradient_top_selenium[16] = {
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
};
static float ozone_sidebar_gradient_top_solarized_dark[16] = {
static const float ozone_sidebar_gradient_top_solarized_dark[16] = {
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
};
static float ozone_sidebar_gradient_bottom_selenium[16] = {
static const float ozone_sidebar_gradient_bottom_selenium[16] = {
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
};
static float ozone_sidebar_gradient_bottom_solarized_dark[16] = {
static const float ozone_sidebar_gradient_bottom_solarized_dark[16] = {
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
};
static float ozone_sidebar_gradient_top_solarized_light[16] = {
static const float ozone_sidebar_gradient_top_solarized_light[16] = {
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
};
static float ozone_sidebar_gradient_bottom_solarized_light[16] = {
static const float ozone_sidebar_gradient_bottom_solarized_light[16] = {
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
};
static float ozone_sidebar_background_gray_dark[16] =
static const float ozone_sidebar_background_gray_dark[16] =
COLOR_HEX_TO_FLOAT(0x101010, 0.0f);
static float ozone_sidebar_background_gray_light[16] =
static const float ozone_sidebar_background_gray_light[16] =
COLOR_HEX_TO_FLOAT(0x202020, 0.0f);
static float ozone_sidebar_background_light[16] = {
static const float ozone_sidebar_background_light[16] = {
0.94f, 0.94f, 0.94f, 1.00f,
0.94f, 0.94f, 0.94f, 1.00f,
0.94f, 0.94f, 0.94f, 1.00f,
0.94f, 0.94f, 0.94f, 1.00f,
};
static float ozone_sidebar_background_dark[16] = {
static const float ozone_sidebar_background_dark[16] = {
0.2f, 0.2f, 0.2f, 1.00f,
0.2f, 0.2f, 0.2f, 1.00f,
0.2f, 0.2f, 0.2f, 1.00f,
0.2f, 0.2f, 0.2f, 1.00f,
};
static float ozone_sidebar_background_nord[16] = {
static const float ozone_sidebar_background_nord[16] = {
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
0.2078431f, 0.2352941f, 0.2901961f, 1.0f,
};
static float ozone_sidebar_background_gruvbox_dark[16] = {
static const float ozone_sidebar_background_gruvbox_dark[16] = {
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
0.1960784f, 0.1882353f, 0.1843137f, 1.0f,
};
static float ozone_sidebar_background_boysenberry[16] = {
static const float ozone_sidebar_background_boysenberry[16] = {
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 1.00f,
};
static float ozone_sidebar_background_hacking_the_kernel[16] = {
static const float ozone_sidebar_background_hacking_the_kernel[16] = {
0.0f, 0.1333333f, 0.0f, 1.0f,
0.0f, 0.1333333f, 0.0f, 1.0f,
0.0f, 0.1333333f, 0.0f, 1.0f,
0.0f, 0.1333333f, 0.0f, 1.0f,
};
static float ozone_sidebar_background_twilight_zone[16] = {
static const float ozone_sidebar_background_twilight_zone[16] = {
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
};
static float ozone_sidebar_background_dracula[16] = {
static const float ozone_sidebar_background_dracula[16] = {
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
0.2666666f, 0.2784314f, 0.3529412f, 1.0f,
};
static float ozone_sidebar_background_evergarden[16] =
static const float ozone_sidebar_background_evergarden[16] =
COLOR_HEX_TO_FLOAT(0x1C2225, 1.0f);
static float ozone_sidebar_background_selenium[16] = {
static const float ozone_sidebar_background_selenium[16] = {
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
0.1019608f, 0.1019608f, 0.1019608f, 1.0f,
};
static float ozone_sidebar_background_solarized_dark[16] = {
static const float ozone_sidebar_background_solarized_dark[16] = {
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
};
static float ozone_sidebar_background_solarized_light[16] = {
static const float ozone_sidebar_background_solarized_light[16] = {
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
};
static float ozone_sidebar_background_purple_rain[16] = {
static const float ozone_sidebar_background_purple_rain[16] = {
0.0862745f, 0.0f, 0.1294117f, 1.0f,
0.0862745f, 0.0f, 0.1294117f, 1.0f,
0.0862745f, 0.0f, 0.1294117f, 1.0f,
0.0862745f, 0.0f, 0.1294117f, 1.0f,
};
static float ozone_background_libretro_running_gray_dark[16] =
static const float ozone_background_libretro_running_gray_dark[16] =
COLOR_HEX_TO_FLOAT(0x101010, 1.0f);
static float ozone_background_libretro_running_gray_light[16] =
static const float ozone_background_libretro_running_gray_light[16] =
COLOR_HEX_TO_FLOAT(0x202020, 1.0f);
static float ozone_background_libretro_running_light[16] = {
static const float ozone_background_libretro_running_light[16] = {
0.690f, 0.690f, 0.690f, 0.75f,
0.690f, 0.690f, 0.690f, 0.75f,
0.922f, 0.922f, 0.922f, 1.0f,
0.922f, 0.922f, 0.922f, 1.0f
};
static float ozone_background_libretro_running_dark[16] = {
static const float ozone_background_libretro_running_dark[16] = {
0.176f, 0.176f, 0.176f, 0.75f,
0.176f, 0.176f, 0.176f, 0.75f,
0.178f, 0.178f, 0.178f, 1.0f,
0.178f, 0.178f, 0.178f, 1.0f,
};
static float ozone_background_libretro_running_nord[16] = {
static const float ozone_background_libretro_running_nord[16] = {
0.1803922f, 0.2039216f, 0.2509804f, 0.75f,
0.1803922f, 0.2039216f, 0.2509804f, 0.75f,
0.1803922f, 0.2039216f, 0.2509804f, 1.0f,
0.1803922f, 0.2039216f, 0.2509804f, 1.0f,
};
static float ozone_background_libretro_running_gruvbox_dark[16] = {
static const float ozone_background_libretro_running_gruvbox_dark[16] = {
0.1568627f, 0.1568627f, 0.1568627f, 0.75f,
0.1568627f, 0.1568627f, 0.1568627f, 0.75f,
0.1568627f, 0.1568627f, 0.1568627f, 1.0f,
0.1568627f, 0.1568627f, 0.1568627f, 1.0f,
};
static float ozone_background_libretro_running_boysenberry[16] = {
static const float ozone_background_libretro_running_boysenberry[16] = {
0.27058823529f, 0.09803921568f, 0.14117647058f, 0.75f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 0.75f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 0.75f,
0.27058823529f, 0.09803921568f, 0.14117647058f, 0.75f,
};
static float ozone_background_libretro_running_hacking_the_kernel[16] = {
static const float ozone_background_libretro_running_hacking_the_kernel[16] = {
0.0f, 0.0666666f, 0.0f, 0.75f,
0.0f, 0.0666666f, 0.0f, 0.75f,
0.0f, 0.0666666f, 0.0f, 1.0f,
0.0f, 0.0666666f, 0.0f, 1.0f,
};
static float ozone_background_libretro_running_twilight_zone[16] = {
static const float ozone_background_libretro_running_twilight_zone[16] = {
0.0078431f, 0.0f, 0.0156862f, 0.75f,
0.0078431f, 0.0f, 0.0156862f, 0.75f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
0.0078431f, 0.0f, 0.0156862f, 1.0f,
};
static float ozone_background_libretro_running_dracula[16] = {
static const float ozone_background_libretro_running_dracula[16] = {
0.1568627f, 0.1647058f, 0.2117647f, 0.75f,
0.1568627f, 0.1647058f, 0.2117647f, 0.75f,
0.1568627f, 0.1647058f, 0.2117647f, 1.0f,
0.1568627f, 0.1647058f, 0.2117647f, 1.0f,
};
static float ozone_background_libretro_running_evergarden[16] = {
static const float ozone_background_libretro_running_evergarden[16] = {
0.1568627f, 0.1647058f, 0.2117647f, 0.75f,
0.1568627f, 0.1647058f, 0.2117647f, 0.75f,
0.1568627f, 0.1647058f, 0.2117647f, 1.0f,
0.1568627f, 0.1647058f, 0.2117647f, 1.0f,
};
static float ozone_background_libretro_running_selenium[16] = {
static const float ozone_background_libretro_running_selenium[16] = {
0.1647059f, 0.1647059f, 0.1647059f, 1.0f,
0.1647059f, 0.1647059f, 0.1647059f, 1.0f,
0.1647059f, 0.1647059f, 0.1647059f, 1.0f,
0.1647059f, 0.1647059f, 0.1647059f, 1.0f,
};
static float ozone_background_libretro_running_solarized_dark[16] = {
static const float ozone_background_libretro_running_solarized_dark[16] = {
0.0000000f, 0.1294118f, 0.1725490f, .85f,
0.0000000f, 0.1294118f, 0.1725490f, .85f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
0.0000000f, 0.1294118f, 0.1725490f, 1.0f,
};
static float ozone_background_libretro_running_solarized_light[16] = {
static const float ozone_background_libretro_running_solarized_light[16] = {
1.0000000f, 1.0000000f, 0.9294118f, 0.85f,
1.0000000f, 1.0000000f, 0.9294118f, 0.85f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
1.0000000f, 1.0000000f, 0.9294118f, 1.0f,
};
static float ozone_background_libretro_running_purple_rain[16] = {
static const float ozone_background_libretro_running_purple_rain[16] = {
0.0862745f, 0.0f, 0.1294117f, 0.75f,
0.0862745f, 0.0f, 0.1294117f, 0.75f,
0.0862745f, 0.0f, 0.1294117f, 1.0f,
0.0862745f, 0.0f, 0.1294117f, 1.0f,
};
static float ozone_border_gray[16] = COLOR_HEX_TO_FLOAT(0x303030, 1.0f);
static const float ozone_border_gray[16] = COLOR_HEX_TO_FLOAT(0x303030, 1.0f);
static float ozone_border_0_light[16] = COLOR_HEX_TO_FLOAT(0x50EFD9, 1.00);
static float ozone_border_1_light[16] = COLOR_HEX_TO_FLOAT(0x0DB6D5, 1.00);
static const float ozone_border_0_light[16] = COLOR_HEX_TO_FLOAT(0x50EFD9, 1.00);
static const float ozone_border_1_light[16] = COLOR_HEX_TO_FLOAT(0x0DB6D5, 1.00);
static float ozone_border_0_dark[16] = COLOR_HEX_TO_FLOAT(0x198AC6, 1.00);
static float ozone_border_1_dark[16] = COLOR_HEX_TO_FLOAT(0x89F1F2, 1.00);
static const float ozone_border_0_dark[16] = COLOR_HEX_TO_FLOAT(0x198AC6, 1.00);
static const float ozone_border_1_dark[16] = COLOR_HEX_TO_FLOAT(0x89F1F2, 1.00);
static float ozone_border_0_nord[16] = COLOR_HEX_TO_FLOAT(0x5E81AC, 1.0f);
static float ozone_border_1_nord[16] = COLOR_HEX_TO_FLOAT(0x88C0D0, 1.0f);
static const float ozone_border_0_nord[16] = COLOR_HEX_TO_FLOAT(0x5E81AC, 1.0f);
static const float ozone_border_1_nord[16] = COLOR_HEX_TO_FLOAT(0x88C0D0, 1.0f);
static float ozone_border_0_gruvbox_dark[16] = COLOR_HEX_TO_FLOAT(0xAF3A03, 1.0f);
static float ozone_border_1_gruvbox_dark[16] = COLOR_HEX_TO_FLOAT(0xFE8019, 1.0f);
static const float ozone_border_0_gruvbox_dark[16] = COLOR_HEX_TO_FLOAT(0xAF3A03, 1.0f);
static const float ozone_border_1_gruvbox_dark[16] = COLOR_HEX_TO_FLOAT(0xFE8019, 1.0f);
static float ozone_border_0_boysenberry[16] = COLOR_HEX_TO_FLOAT(0x50EFD9, 1.00);
static float ozone_border_1_boysenberry[16] = COLOR_HEX_TO_FLOAT(0x0DB6D5, 1.00);
static const float ozone_border_0_boysenberry[16] = COLOR_HEX_TO_FLOAT(0x50EFD9, 1.00);
static const float ozone_border_1_boysenberry[16] = COLOR_HEX_TO_FLOAT(0x0DB6D5, 1.00);
static float ozone_border_0_hacking_the_kernel[16] = COLOR_HEX_TO_FLOAT(0x008C00, 1.0f);
static float ozone_border_1_hacking_the_kernel[16] = COLOR_HEX_TO_FLOAT(0x00E000, 1.0f);
static const float ozone_border_0_hacking_the_kernel[16] = COLOR_HEX_TO_FLOAT(0x008C00, 1.0f);
static const float ozone_border_1_hacking_the_kernel[16] = COLOR_HEX_TO_FLOAT(0x00E000, 1.0f);
static float ozone_border_0_twilight_zone[16] = COLOR_HEX_TO_FLOAT(0xC3A0E0, 1.0f);
static float ozone_border_1_twilight_zone[16] = COLOR_HEX_TO_FLOAT(0x9B61CC, 1.0f);
static const float ozone_border_0_twilight_zone[16] = COLOR_HEX_TO_FLOAT(0xC3A0E0, 1.0f);
static const float ozone_border_1_twilight_zone[16] = COLOR_HEX_TO_FLOAT(0x9B61CC, 1.0f);
static float ozone_border_0_dracula[16] = COLOR_HEX_TO_FLOAT(0xBD93F9, 1.0f);
static float ozone_border_1_dracula[16] = COLOR_HEX_TO_FLOAT(0xFF79C6, 1.0f);
static const float ozone_border_0_dracula[16] = COLOR_HEX_TO_FLOAT(0xBD93F9, 1.0f);
static const float ozone_border_1_dracula[16] = COLOR_HEX_TO_FLOAT(0xFF79C6, 1.0f);
static float ozone_border_0_evergarden[16] = COLOR_HEX_TO_FLOAT(0xCBE3B3, 1.0f);
static float ozone_border_1_evergarden[16] = COLOR_HEX_TO_FLOAT(0xB3E6DB, 1.0f);
static const float ozone_border_0_evergarden[16] = COLOR_HEX_TO_FLOAT(0xCBE3B3, 1.0f);
static const float ozone_border_1_evergarden[16] = COLOR_HEX_TO_FLOAT(0xB3E6DB, 1.0f);
static float ozone_border_0_selenium[16] = COLOR_HEX_TO_FLOAT(0x91a666, 1.0f);
static float ozone_border_1_selenium[16] = COLOR_HEX_TO_FLOAT(0x566646, 1.0f);
static const float ozone_border_0_selenium[16] = COLOR_HEX_TO_FLOAT(0x91a666, 1.0f);
static const float ozone_border_1_selenium[16] = COLOR_HEX_TO_FLOAT(0x566646, 1.0f);
static float ozone_border_0_solarized_dark[16] = COLOR_HEX_TO_FLOAT(0x67ECE2, 1.0f);
static float ozone_border_1_solarized_dark[16] = COLOR_HEX_TO_FLOAT(0x2AA198, 1.0f);
static const float ozone_border_0_solarized_dark[16] = COLOR_HEX_TO_FLOAT(0x67ECE2, 1.0f);
static const float ozone_border_1_solarized_dark[16] = COLOR_HEX_TO_FLOAT(0x2AA198, 1.0f);
static float ozone_border_0_solarized_light[16] = COLOR_HEX_TO_FLOAT(0x8F120F, 1.0f);
static float ozone_border_1_solarized_light[16] = COLOR_HEX_TO_FLOAT(0xDC322F, 1.0f);
static const float ozone_border_0_solarized_light[16] = COLOR_HEX_TO_FLOAT(0x8F120F, 1.0f);
static const float ozone_border_1_solarized_light[16] = COLOR_HEX_TO_FLOAT(0xDC322F, 1.0f);
static float ozone_border_0_purple_rain[16] = COLOR_HEX_TO_FLOAT(0xC3A0E0, 1.0f);
static float ozone_border_1_purple_rain[16] = COLOR_HEX_TO_FLOAT(0x8C3DCC, 1.0f);
static const float ozone_border_0_purple_rain[16] = COLOR_HEX_TO_FLOAT(0xC3A0E0, 1.0f);
static const float ozone_border_1_purple_rain[16] = COLOR_HEX_TO_FLOAT(0x8C3DCC, 1.0f);
static ozone_theme_t ozone_theme_light = {
COLOR_HEX_TO_FLOAT(0xEBEBEB, 1.00f), /* background */
@@ -1655,7 +1664,7 @@ static INLINE uint8_t ozone_count_lines(const char *str)
static void ozone_animate_cursor(ozone_handle_t *ozone,
float *dst,
float *target)
const float *target)
{
int i;
gfx_animation_ctx_entry_t entry;
@@ -1684,7 +1693,7 @@ static void ozone_animate_cursor(ozone_handle_t *ozone,
static void ozone_cursor_animation_cb(void *userdata)
{
float *target = NULL;
const float *target = NULL;
ozone_handle_t *ozone = (ozone_handle_t*)userdata;
switch (ozone->theme_dynamic_cursor_state)
@@ -1797,6 +1806,23 @@ static void ozone_set_color_theme(ozone_handle_t *ozone,
ozone->theme->message_background,
sizeof(ozone->theme_dynamic.message_background));
/* Copy sidebar/background colors into per-instance mutable arrays.
* The theme arrays are now const; these copies are what gets
* alpha-mutated per-frame. */
memcpy(ozone->sidebar_top_gradient,
ozone->theme->sidebar_top_gradient,
sizeof(ozone->sidebar_top_gradient));
memcpy(ozone->sidebar_background,
ozone->theme->sidebar_background,
sizeof(ozone->sidebar_background));
memcpy(ozone->sidebar_bottom_gradient,
ozone->theme->sidebar_bottom_gradient,
sizeof(ozone->sidebar_bottom_gradient));
if (ozone->theme->background_libretro_running)
memcpy(ozone->background_running,
ozone->theme->background_libretro_running,
sizeof(ozone->background_running));
if (ozone->flags & OZONE_FLAG_HAS_ALL_ASSETS || ozone->flags2 & OZONE_FLAG2_IGNORE_MISSING_ASSETS)
ozone_restart_cursor_animation(ozone);
@@ -1830,10 +1856,10 @@ static void ozone_set_background_running_opacity(
float framebuffer_opacity)
{
#if USE_BG_GRADIENT
static float background_running_alpha_top = 1.0f;
static float background_running_alpha_bottom = 0.75f;
float background_running_alpha_top;
float background_running_alpha_bottom;
float *background =
ozone->theme->background_libretro_running;
ozone->background_running;
/* When content is running, background is a
* gradient that from top to bottom transitions
@@ -1862,7 +1888,7 @@ static void ozone_set_background_running_opacity(
background[7] = background_running_alpha_bottom;
#else
float *background =
ozone->theme->background_libretro_running;
ozone->background_running;
background[11] = framebuffer_opacity;
background[15] = framebuffer_opacity;
@@ -1872,12 +1898,13 @@ static void ozone_set_background_running_opacity(
ozone->last_framebuffer_opacity = framebuffer_opacity;
/* Set sidebar background to half opacity if transparent */
if (ozone->theme->sidebar_background[3] > 0)
/* Set sidebar background to half opacity if transparent —
* now mutates instance copies, not the const theme arrays */
if (ozone->sidebar_background[3] > 0)
{
gfx_display_set_alpha(ozone->theme->sidebar_top_gradient, 0.5f);
gfx_display_set_alpha(ozone->theme->sidebar_background, 0.5f);
gfx_display_set_alpha(ozone->theme->sidebar_bottom_gradient, 0.5f);
gfx_display_set_alpha(ozone->sidebar_top_gradient, 0.5f);
gfx_display_set_alpha(ozone->sidebar_background, 0.5f);
gfx_display_set_alpha(ozone->sidebar_bottom_gradient, 0.5f);
}
}
@@ -3129,7 +3156,6 @@ static void ozone_draw_cursor_slice(
{
gfx_display_ctx_driver_t
*dispctx = p_disp->dispctx;
static float last_alpha = 0.0f;
float scale_factor = ozone->last_scale_factor;
int slice_x = x_offset - (12 + 1) * scale_factor;
int slice_y = (int)y + 8 * scale_factor;
@@ -3139,12 +3165,8 @@ static void ozone_draw_cursor_slice(
unsigned slice_h = 80;
unsigned offset = 20;
if (alpha != last_alpha)
{
gfx_display_set_alpha(ozone->theme_dynamic.cursor_alpha, alpha);
gfx_display_set_alpha(ozone->theme_dynamic.cursor_border, alpha);
last_alpha = alpha;
}
gfx_display_set_alpha(ozone->theme_dynamic.cursor_alpha, alpha);
gfx_display_set_alpha(ozone->theme_dynamic.cursor_border, alpha);
if (dispctx && dispctx->blend_begin)
dispctx->blend_begin(userdata);
@@ -3207,14 +3229,8 @@ static void ozone_draw_cursor_fallback(
size_t y,
float alpha)
{
static float last_alpha = 0.0f;
if (alpha != last_alpha)
{
gfx_display_set_alpha(ozone->theme_dynamic.selection_border, alpha);
gfx_display_set_alpha(ozone->theme_dynamic.selection, alpha);
last_alpha = alpha;
}
gfx_display_set_alpha(ozone->theme_dynamic.selection_border, alpha);
gfx_display_set_alpha(ozone->theme_dynamic.selection, alpha);
/* Fill */
gfx_display_draw_quad(
@@ -3486,7 +3502,7 @@ static void ozone_draw_sidebar(
ozone->dimensions.sidebar_gradient_height,
video_width,
video_height,
ozone->theme->sidebar_top_gradient,
ozone->sidebar_top_gradient,
NULL);
gfx_display_draw_quad(
p_disp,
@@ -3500,7 +3516,7 @@ static void ozone_draw_sidebar(
sidebar_height,
video_width,
video_height,
ozone->theme->sidebar_background,
ozone->sidebar_background,
NULL);
gfx_display_draw_quad(
p_disp,
@@ -3515,7 +3531,7 @@ static void ozone_draw_sidebar(
ozone->dimensions.sidebar_gradient_height,
video_width,
video_height,
ozone->theme->sidebar_bottom_gradient,
ozone->sidebar_bottom_gradient,
NULL);
}
@@ -6397,7 +6413,7 @@ static void ozone_draw_thumbnail_bar(
ozone->dimensions.sidebar_gradient_height,
video_width,
video_height,
ozone->theme->sidebar_top_gradient,
ozone->sidebar_top_gradient,
NULL);
gfx_display_draw_quad(
p_disp,
@@ -6411,7 +6427,7 @@ static void ozone_draw_thumbnail_bar(
sidebar_height,
video_width,
video_height,
ozone->theme->sidebar_background,
ozone->sidebar_background,
NULL);
gfx_display_draw_quad(
p_disp,
@@ -6426,7 +6442,7 @@ static void ozone_draw_thumbnail_bar(
ozone->dimensions.sidebar_gradient_height,
video_width,
video_height,
ozone->theme->sidebar_bottom_gradient,
ozone->sidebar_bottom_gradient,
NULL);
}
@@ -7003,21 +7019,16 @@ static void ozone_draw_backdrop(
unsigned video_height,
float alpha)
{
static float ozone_backdrop[16] = {
/* Stack-local scratch — avoids data race with threaded
* video backends reading a previous frame's color data */
float ozone_backdrop[16] = {
0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75,
};
static float last_alpha = 0.0f;
/* TODO: Replace this backdrop by a blur shader
* on the whole screen if available */
if (alpha != last_alpha)
{
gfx_display_set_alpha(ozone_backdrop, alpha);
last_alpha = alpha;
}
gfx_display_set_alpha(ozone_backdrop, alpha);
gfx_display_draw_quad(
(gfx_display_t*)disp_data,
@@ -7046,7 +7057,7 @@ static void ozone_draw_osk(
gfx_display_t *p_disp = (gfx_display_t*)disp_userdata;
const char *text = str;
unsigned text_color = 0xffffffff;
static float ozone_osk_backdrop[16] = {
float ozone_osk_backdrop[16] = {
0.00, 0.00, 0.00, 0.15,
0.00, 0.00, 0.00, 0.15,
0.00, 0.00, 0.00, 0.15,
@@ -7537,7 +7548,7 @@ static void ozone_draw_fullscreen_thumbnails(
float left_thumbnail_draw_width = 0.0f;
float left_thumbnail_draw_height = 0.0f;
float background_alpha = 0.95f;
static float background_color[16] = {
float background_color[16] = {
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
@@ -7703,7 +7714,7 @@ static void ozone_draw_fullscreen_thumbnails(
ozone->animations.fullscreen_thumbnail_alpha);
/* > Thumbnail frame */
memcpy(frame_color, ozone->theme->sidebar_background, sizeof(frame_color));
memcpy(frame_color, ozone->sidebar_background, sizeof(frame_color));
gfx_display_set_alpha(
frame_color,
ozone->animations.fullscreen_thumbnail_alpha);
@@ -11837,6 +11848,7 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
bool draw_osk = menu_input_dialog_get_display_kb();
static bool draw_osk_old = false;
float *background_color = NULL;
float background_color_buf[16]; /* stack copy to avoid mutating static theme struct */
void *userdata = video_info->userdata;
unsigned video_width = video_info->width;
unsigned video_height = video_info->height;
@@ -11979,10 +11991,14 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
if (ozone->theme->background_libretro_running)
ozone_set_background_running_opacity(ozone, menu_framebuffer_opacity);
background_color = ozone->theme->background_libretro_running;
background_color = ozone->background_running;
}
else
background_color = ozone->theme->background;
{
memcpy(background_color_buf, ozone->theme->background,
sizeof(background_color_buf));
background_color = background_color_buf;
}
gfx_display_set_alpha(background_color, menu_framebuffer_opacity * ozone->animations.alpha);
+77 -62
View File
@@ -487,35 +487,24 @@ typedef struct xmb_handle
/* Whether to show entry index for current list */
bool entry_idx_enabled;
/* Per-instance layout scale modifiers (was file-scope static) */
float scale_mod[8];
/* Base item color: 0,0,0 for inverted themes, 1,1,1 otherwise
* (was file-scope static xmb_item_color) */
float item_color_base[16];
} xmb_handle_t;
static float xmb_scale_mod[8] = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
static float xmb_coord_shadow[] = {
/* Constant color templates — safe to share across threads.
* Mutable scratch copies are created on the stack where needed. */
static const float xmb_color_black[16] = {
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
};
static float xmb_coord_black[] = {
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
};
static float xmb_coord_white[] = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
};
static float xmb_item_color[] = {
static const float xmb_color_white[16] = {
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
@@ -1010,9 +999,15 @@ static void xmb_draw_icon(
if (shadows_enable)
{
gfx_display_set_alpha(xmb_coord_shadow, color[3] * GFX_SHADOW_ALPHA * 0.75f);
float shadow_color[16] = {
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
};
gfx_display_set_alpha(shadow_color, color[3] * GFX_SHADOW_ALPHA * 0.75f);
coords.color = xmb_coord_shadow;
coords.color = shadow_color;
draw.x = x + shadow_offset;
draw.y = height - y - shadow_offset;
@@ -4971,8 +4966,8 @@ static int xmb_draw_item(
uintptr_t texture_switch = 0;
bool draw_text_value = false;
int extra_margins_setting_left = 0;
unsigned ticker_limit = ((xmb->use_ps3_layout) ? 37 : 37) * xmb_scale_mod[0];
unsigned line_ticker_width = ((xmb->use_ps3_layout) ? 58 : 58) * xmb_scale_mod[3];
unsigned ticker_limit = ((xmb->use_ps3_layout) ? 37 : 37) * xmb->scale_mod[0];
unsigned line_ticker_width = ((xmb->use_ps3_layout) ? 58 : 58) * xmb->scale_mod[3];
xmb_node_t *node = (xmb_node_t*)list->list[i].userdata;
bool use_smooth_ticker = settings->bools.menu_ticker_smooth;
enum gfx_animation_ticker_type menu_ticker_type
@@ -5117,7 +5112,7 @@ static int xmb_draw_item(
|| (show_left_thumbnail && vertical_thumbnails))
)
{
ticker_limit = 37 * xmb_scale_mod[0];
ticker_limit = 37 * xmb->scale_mod[0];
/* Can increase text length if thumbnail is downscaled */
if (thumbnail_scale_factor < 100)
@@ -5126,28 +5121,28 @@ static int xmb_draw_item(
1.0f - ((float)thumbnail_scale_factor / 100.0f);
ticker_limit +=
(unsigned)(ticker_scale_factor * 20.0f * xmb_scale_mod[1]);
(unsigned)(ticker_scale_factor * 20.0f * xmb->scale_mod[1]);
line_ticker_width +=
(unsigned)(ticker_scale_factor * 10.0f * xmb_scale_mod[3]);
(unsigned)(ticker_scale_factor * 10.0f * xmb->scale_mod[3]);
}
}
else if (!draw_text_value || !*entry.value)
ticker_limit = ((xmb->use_ps3_layout) ? 75 : 65) * xmb_scale_mod[2];
ticker_limit = ((xmb->use_ps3_layout) ? 75 : 65) * xmb->scale_mod[2];
}
switch (entry_type)
{
case FILE_TYPE_DOWNLOAD_CORE:
/* Special margin for 'installed' tag value */
extra_margins_setting_left = ((xmb->use_ps3_layout) ? 300 : 250) * xmb->last_scale_factor * xmb_scale_mod[2];
ticker_limit = ((xmb->use_ps3_layout) ? 80 : 58) * xmb_scale_mod[2];
extra_margins_setting_left = ((xmb->use_ps3_layout) ? 300 : 250) * xmb->last_scale_factor * xmb->scale_mod[2];
ticker_limit = ((xmb->use_ps3_layout) ? 80 : 58) * xmb->scale_mod[2];
break;
default:
if (!xmb->use_ps3_layout)
break;
if (xmb->is_quick_menu || xmb->is_state_slot)
extra_margins_setting_left = -(100 * xmb->last_scale_factor * xmb_scale_mod[2]);
extra_margins_setting_left = -(100 * xmb->last_scale_factor * xmb->scale_mod[2]);
break;
}
@@ -5367,7 +5362,7 @@ static int xmb_draw_item(
if (use_smooth_ticker)
{
ticker_smooth.selected = (i == current);
ticker_smooth.field_width = xmb->font_size * 0.5f * ((xmb->use_ps3_layout) ? 40 : 26) * xmb_scale_mod[7];
ticker_smooth.field_width = xmb->font_size * 0.5f * ((xmb->use_ps3_layout) ? 40 : 26) * xmb->scale_mod[7];
ticker_smooth.src_str = entry.value;
ticker_smooth.dst_str = tmp;
ticker_smooth.dst_str_len = sizeof(tmp);
@@ -5378,7 +5373,7 @@ static int xmb_draw_item(
else
{
ticker.s = tmp;
ticker.len = ((xmb->use_ps3_layout) ? 40 : 26) * xmb_scale_mod[7];
ticker.len = ((xmb->use_ps3_layout) ? 40 : 26) * xmb->scale_mod[7];
ticker.selected = (i == current);
ticker.str = entry.value;
@@ -6277,7 +6272,7 @@ static void xmb_layout_ps3(xmb_handle_t *xmb, int width)
xmb->margins_label_left = 85.0f * scale_factor;
xmb->margins_label_top = new_font_size / 3.0f;
xmb->margins_setting_left = 660.0f * scale_factor * xmb_scale_mod[6];
xmb->margins_setting_left = 660.0f * scale_factor * xmb->scale_mod[6];
xmb->margins_dialog = new_font_size * 2.0f;
xmb->margins_slice = new_font_size / 2.0f;
@@ -6306,14 +6301,14 @@ static void xmb_layout_psp(xmb_handle_t *xmb, int width)
xmb->margins_label_left = 85.0f * scale_factor;
xmb->margins_label_top = new_font_size / 3.0f;
xmb->margins_setting_left = 520.0f * scale_factor * xmb_scale_mod[6];
xmb->margins_setting_left = 520.0f * scale_factor * xmb->scale_mod[6];
xmb->margins_dialog = new_font_size * 2.0f;
xmb->margins_slice = new_font_size / 2.0f;
xmb_layout_common(xmb, scale_factor, new_font_size);
}
static void xmb_init_scale_mod(float scale_value)
static void xmb_init_scale_mod(float *scale_mod, float scale_value)
{
uint8_t i;
@@ -6322,25 +6317,25 @@ static void xmb_init_scale_mod(float scale_value)
/* xmb_scale 75 = { 2, 1.6, 1.6, 1.4, 1.5, 2.3, 1.9, 1.3} */
{
/* text length & word wrap (base 35 apply to file browser, 1st column) */
xmb_scale_mod[0] = -0.03 * scale_value + 4.083;
scale_mod[0] = -0.03 * scale_value + 4.083;
/* playlist text length when thumbnail is ON (small, base 40) */
xmb_scale_mod[1] = -0.03 * scale_value + 3.95;
scale_mod[1] = -0.03 * scale_value + 3.95;
/* playlist text length when thumbnail is OFF (large, base 70) */
xmb_scale_mod[2] = -0.02 * scale_value + 3.033;
scale_mod[2] = -0.02 * scale_value + 3.033;
/* sub-label length & word wrap */
xmb_scale_mod[3] = -0.014 * scale_value + 2.416;
scale_mod[3] = -0.014 * scale_value + 2.416;
/* thumbnail size & vertical margin from top */
xmb_scale_mod[4] = -0.03 * scale_value + 3.916;
scale_mod[4] = -0.03 * scale_value + 3.916;
/* thumbnail horizontal left margin (horizontal positioning) */
xmb_scale_mod[5] = -0.06 * scale_value + 6.933;
scale_mod[5] = -0.06 * scale_value + 6.933;
/* margin before 2nd column start (shaders parameters, cheats...) */
xmb_scale_mod[6] = -0.024 * scale_value + 3.400;
scale_mod[6] = -0.024 * scale_value + 3.400;
/* text length & word wrap (base 35 apply to 2nd column in cheats, shaders, etc) */
xmb_scale_mod[7] = 134.179 * pow(scale_value, -1.0778);
scale_mod[7] = 134.179 * pow(scale_value, -1.0778);
for (i = 0; i < 8; i++)
if (xmb_scale_mod[i] < 1)
xmb_scale_mod[i] = 1;
if (scale_mod[i] < 1)
scale_mod[i] = 1;
}
}
@@ -6355,7 +6350,7 @@ static void xmb_layout(xmb_handle_t *xmb)
unsigned end = (unsigned)MENU_LIST_GET_SELECTION(menu_list, 0)->size;
video_driver_get_size(&width, &height);
xmb_init_scale_mod(config_get_ptr()->floats.menu_scale_factor * 100.0f);
xmb_init_scale_mod(xmb->scale_mod, config_get_ptr()->floats.menu_scale_factor * 100.0f);
if (xmb->use_ps3_layout)
xmb_layout_ps3(xmb, width);
@@ -6744,9 +6739,9 @@ static void xmb_context_reset_textures(
/* Recolor */
if ( menu_xmb_theme == XMB_ICON_THEME_MONOCHROME_INVERTED
|| menu_xmb_theme == XMB_ICON_THEME_AUTOMATIC_INVERTED)
memcpy(xmb_item_color, xmb_coord_black, sizeof(xmb_item_color));
memcpy(xmb->item_color_base, xmb_color_black, sizeof(xmb->item_color_base));
else
memcpy(xmb_item_color, xmb_coord_white, sizeof(xmb_item_color));
memcpy(xmb->item_color_base, xmb_color_white, sizeof(xmb->item_color_base));
}
@@ -7515,6 +7510,7 @@ static void xmb_draw_no_thumbnail_available(
unsigned view_height,
bool shadows_enable,
bool draw_text,
float *color,
math_matrix_4x4 *mymat)
{
gfx_display_ctx_driver_t *dispctx = p_disp->dispctx;
@@ -7531,7 +7527,7 @@ static void xmb_draw_no_thumbnail_available(
if (dispctx)
{
gfx_display_set_alpha(xmb_item_color, xmb->alpha * 0.20f);
gfx_display_set_alpha(color, xmb->alpha * 0.20f);
if (dispctx->blend_begin)
dispctx->blend_begin(userdata);
@@ -7553,7 +7549,7 @@ static void xmb_draw_no_thumbnail_available(
xmb->alpha,
0,
1,
&xmb_item_color[0],
&color[0],
xmb->shadow_offset / 2,
mymat);
if (dispctx->blend_end)
@@ -7581,6 +7577,7 @@ static void xmb_draw_fullscreen_thumbnails(
unsigned video_height,
bool shadows_enable,
unsigned xmb_color_theme,
float *color,
settings_t *settings, size_t selection)
{
static float right_thumbnail_draw_width_prev = 0.0f;
@@ -7979,6 +7976,7 @@ static void xmb_draw_fullscreen_thumbnails(
video_height,
shadows_enable,
true,
color,
NULL);
}
return;
@@ -8044,6 +8042,18 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
if (!xmb)
return;
/* Per-frame scratch color arrays — local to this stack frame
* to avoid data races with the GPU driver thread.
* coord_black: zero RGB, alpha set per use
* coord_white: one RGB, alpha set per use
* xmb_item_color: base color from theme (black or white), alpha set per use */
{
float coord_black[16] = {0};
float coord_white[16];
float xmb_item_color[16];
memcpy(coord_white, xmb_color_white, sizeof(coord_white));
memcpy(xmb_item_color, xmb->item_color_base, sizeof(xmb_item_color));
/* Async icon sync: context textures are loaded asynchronously and
* may complete across multiple frames. Continuously propagate
* finished textures into the tab node icon fields. The writes
@@ -8101,7 +8111,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
left_thumbnail_margin_width = floorf(xmb->icon_size * (xmb->use_ps3_layout ? 3.3f : 2.0f));
right_thumbnail_margin_width =
(float)video_width - (xmb->icon_size / 2.0f) -
(xmb->margins_screen_left * xmb_scale_mod[5]) -
(xmb->margins_screen_left * xmb->scale_mod[5]) -
xmb->icon_spacing_horizontal - pseudo_font_length;
thumbnail_margin_height_under = (float)video_height
- xmb->margins_screen_top - xmb->icon_size;
@@ -8142,7 +8152,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
/* Blank dummy core output */
if (!libretro_running)
{
gfx_display_set_alpha(xmb_coord_black, 1.0f);
gfx_display_set_alpha(coord_black, 1.0f);
gfx_display_draw_quad(
p_disp,
userdata,
@@ -8154,12 +8164,12 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
video_height,
video_width,
video_height,
xmb_coord_black,
coord_black,
NULL);
}
gfx_display_set_alpha(xmb_coord_black, MIN((float)alpha_factor / 100, xmb->alpha));
gfx_display_set_alpha(xmb_coord_white, xmb->alpha);
gfx_display_set_alpha(coord_black, MIN((float)alpha_factor / 100, xmb->alpha));
gfx_display_set_alpha(coord_white, xmb->alpha);
if (dispctx)
xmb_draw_bg(
@@ -8175,8 +8185,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
MIN(xmb->alpha, alpha_factor / 100),
xmb->textures.bg,
xmb->bg_file_path,
xmb_coord_black,
xmb_coord_white);
coord_black,
coord_white);
selection = menu_st->selection_ptr;
@@ -8539,6 +8549,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
scaled_thumb_height,
shadows_enable,
false,
xmb_item_color,
NULL);
}
}
@@ -9082,6 +9093,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
video_height,
shadows_enable,
color_theme,
xmb_item_color,
settings, selection);
if (input_dialog_display_kb)
@@ -9124,7 +9136,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
bool cursor_visible = menu_mouse_enable
&& (video_fullscreen || mouse_grabbed);
gfx_display_set_alpha(xmb_coord_white, MIN(xmb->alpha, 1.00f));
gfx_display_set_alpha(coord_white, MIN(xmb->alpha, 1.00f));
if (cursor_visible)
gfx_display_draw_cursor(
p_disp,
@@ -9132,7 +9144,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
video_width,
video_height,
cursor_visible,
&xmb_coord_white[0],
&coord_white[0],
xmb->cursor_size,
xmb->textures.list[XMB_TEXTURE_POINTER],
xmb->pointer.x,
@@ -9144,6 +9156,8 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
if (video_st->current_video && video_st->current_video->set_viewport)
video_st->current_video->set_viewport(
video_st->data, video_width, video_height, false, true);
} /* end of local color array scope */
}
static void xmb_ribbon_set_vertex(float *ribbon_verts,
@@ -9213,7 +9227,6 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
return NULL;
video_driver_get_size(&width, &height);
xmb_init_scale_mod(settings->floats.menu_scale_factor * 100.0f);
if (!(xmb = (xmb_handle_t*)calloc(1, sizeof(xmb_handle_t))))
{
@@ -9221,6 +9234,8 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
return NULL;
}
xmb_init_scale_mod(xmb->scale_mod, settings->floats.menu_scale_factor * 100.0f);
*userdata = xmb;
xmb->categories_active_idx = 0;