@@ -499,6 +499,12 @@ typedef struct xmb_handle
499499 bool is_state_slot ;
500500 bool libretro_running ;
501501
502+ /* True from xmb_init() until the first xmb_frame() completes.
503+ * Used to skip the toggle-fade-in that would otherwise render
504+ * the very first frame at alpha=0 (a black screen) before the
505+ * fade-in animation starts. */
506+ bool is_first_frame ;
507+
502508 /* Whether to show entry index for current list */
503509 bool entry_idx_enabled ;
504510
@@ -9265,6 +9271,11 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
92659271 if (ctx_gen != xmb -> context_generation )
92669272 goto ctx_destroyed ;
92679273
9274+ /* First-frame init done — subsequent frames are normal.
9275+ * Cleared after the last ctx-destroyed guard so that a context
9276+ * death mid-frame leaves the flag set for the retry. */
9277+ xmb -> is_first_frame = false;
9278+
92689279 if (xmb -> font && xmb -> font -> renderer && xmb -> font -> renderer -> flush )
92699280 xmb -> font -> renderer -> flush (video_width ,
92709281 video_height , xmb -> font -> renderer_data );
@@ -9458,6 +9469,7 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
94589469 xmb -> old_depth = 1 ;
94599470 xmb -> alpha = 0.0f ;
94609471 xmb -> alpha_list = 1.0f ;
9472+ xmb -> is_first_frame = true;
94619473
94629474 xmb_refresh_system_tabs_list (xmb );
94639475
@@ -9941,7 +9953,20 @@ static void xmb_toggle(void *userdata, bool menu_on)
99419953 menu_st -> flags |= MENU_ST_FLAG_PREVENT_POPULATE ;
99429954
99439955 xmb_toggle_horizontal_list (xmb );
9944- xmb_fade_in (xmb );
9956+
9957+ /* Skip the fade-in on the very first frame after init: at
9958+ * startup xmb_toggle(true) fires from retroarch_menu_running()
9959+ * before the first xmb_frame, and xmb_fade_in animates xmb->alpha
9960+ * from its init value of 0 up to items_active_alpha over ~200ms.
9961+ * xmb->alpha gates the entire menu including the wallpaper, so
9962+ * the first ~12 frames render as a fully black screen before the
9963+ * menu appears. The menu has no prior state to fade in from at
9964+ * startup, so jump straight to full opacity instead. Subsequent
9965+ * toggles (menu hotkey from gameplay) are unaffected. */
9966+ if (xmb -> is_first_frame )
9967+ xmb -> alpha = xmb -> items_active_alpha ;
9968+ else
9969+ xmb_fade_in (xmb );
99459970}
99469971
99479972static int xmb_deferred_push_content_actions (menu_displaylist_info_t * info )
0 commit comments