input: the video code stops reaching into the input driver's state

gfx/ took input_state_get_ptr() and worked on the input driver's
fields itself. video_driver_free_internal() freed the input driver and
destroyed the joypad drivers, cleared a flag and a pointer;
video_driver_init_internal() handed the addresses of current_driver
and current_data to the video driver's init, and read and set the
mouse-grab flag; video_driver_build_info() read two flags out of the
struct every frame; the Win32 window procedure read one, and the SDL3
common code compared the current driver.

Those are five calls into input/ now, with the statements they
replace moved as they stood:

  input_driver_free_with_video()       the teardown
  input_driver_video_slots()           the two slots an init may fill
  input_driver_get_current()           the driver in use
  input_driver_get_flags()             the flags, one read
  input_driver_grab_mouse_for_video()  grab, and note that it is

No file under gfx/ names input_state_get_ptr any more - it was
fifteen places when the input plan counted them - and a step in the
input samples workflow fails if one comes back. The video driver's
init still starts the input driver; that it does so through its own
init's parameters is the next part of this, not this one.

video_driver_build_info(), which runs every frame, makes one call for
the flags word where it made one for the struct pointer.

Nothing is meant to behave differently. The frontend-overhead harness
passes in its three poll-mode runs, a menu harness and the window
procedure's Wine test pass, and video_driver.c and input_driver.c
compile for Windows and through the Android unity build. The SDL3
line was not compiled here.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-10-03 05:01:26 +02:00
1 parent 8674c1f40b
commit 5fd9105fb5
7 files changed
+109 -40

No files matched your search

+18
View File
@@ -64,6 +64,24 @@ jobs:
- name: Checkout
uses: actions/checkout@v5
- name: gfx/ does not reach into input state
shell: bash
run: |
set -eu
# The video code used to take input_state_get_ptr() and work
# on the input driver's fields itself - freeing the driver
# and the joypads, handing out the addresses of its slots,
# reading and setting its flags. It goes through calls into
# input/ now (input_driver_free_with_video() and the rest).
# This keeps it that way: no file under gfx/ may name
# input_state_get_ptr.
if grep -rn "input_state_get_ptr" --include=*.c --include=*.h \
--include=*.m --include=*.cpp gfx/; then
echo "FAIL: gfx/ takes the input driver's state directly" >&2
exit 1
fi
echo "[pass] gfx/ does not name input_state_get_ptr"
- name: Restore ccache
uses: actions/cache@v4
with:
+1 -1
View File
@@ -128,7 +128,7 @@ void sdl3_pump_window_events(bool *quit, bool *resize)
/* Clear out the input queue if we're not using the
* SDL driver. */
if (input_state_get_ptr()->current_driver != &input_sdl3)
if (input_driver_get_current() != &input_sdl3)
{
SDL_FlushEvents(SDL_EVENT_KEY_DOWN, SDL_EVENT_MOUSE_REMOVED);
SDL_FlushEvents(SDL_EVENT_FINGER_DOWN, SDL_EVENT_FINGER_CANCELED);
+1 -1
View File
@@ -1328,7 +1328,7 @@ static LRESULT win32_wnd_proc_route(HWND hwnd,
#ifdef HAVE_CLIP_WINDOW
if ( (route & (WIN32_ROUTE_CLIP_ON | WIN32_ROUTE_CLIP_OFF))
&& (input_state_get_ptr()->flags & INP_FLAG_GRAB_MOUSE_STATE))
&& (input_driver_get_flags() & INP_FLAG_GRAB_MOUSE_STATE))
win32_clip_window((route & WIN32_ROUTE_CLIP_ON) != 0);
#endif
+15 -37
View File
@@ -2571,7 +2571,6 @@ void video_driver_hw_request_restore(const struct video_hw_request *req)
void video_driver_free_internal(void)
{
input_driver_state_t *input_st = input_state_get_ptr();
video_driver_state_t *video_st = &video_driver_st;
const video_driver_t *vid = video_st->current_video;
bool had_data = (video_st->data != NULL);
@@ -2592,28 +2591,7 @@ void video_driver_free_internal(void)
if (!((uint32_t)retro_atomic_load_relaxed_int(&video_st->flags) & VIDEO_FLAG_CACHE_CONTEXT))
video_driver_free_hw_context();
if (!(input_st->current_data == video_st->data))
{
if (input_st->current_driver)
if (input_st->current_driver->free)
input_st->current_driver->free(input_st->current_data);
if (input_st->primary_joypad)
{
const input_device_driver_t *tmp = input_st->primary_joypad;
input_st->primary_joypad = NULL;
tmp->destroy();
}
#ifdef HAVE_MFI
if (input_st->secondary_joypad)
{
const input_device_driver_t *tmp = input_st->secondary_joypad;
input_st->secondary_joypad = NULL;
tmp->destroy();
}
#endif
input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED;
input_st->current_data = NULL;
}
input_driver_free_with_video(video_st->data);
/* Cancel any in-progress deferred shader load before
* freeing the driver — the deferred state holds pointers
@@ -4936,7 +4914,7 @@ void video_driver_build_info(video_frame_info_t *video_info)
runloop_state_t *runloop_st = runloop_state_get_ptr();
settings_t *settings = config_get_ptr();
video_driver_state_t *video_st = &video_driver_st;
input_driver_state_t *input_st = input_state_get_ptr();
uint32_t input_flags = input_driver_get_flags();
#ifdef HAVE_MENU
struct menu_state *menu_st = menu_state_get_ptr();
#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL)
@@ -5250,8 +5228,8 @@ void video_driver_build_info(video_frame_info_t *video_info)
#endif
#endif
video_info->input_driver_nonblock_state = (input_st->flags & INP_FLAG_NONBLOCKING) ? true : false;
video_info->input_driver_grab_mouse_state = (input_st->flags & INP_FLAG_GRAB_MOUSE_STATE) ? true : false;
video_info->input_driver_nonblock_state = (input_flags & INP_FLAG_NONBLOCKING) ? true : false;
video_info->input_driver_grab_mouse_state = (input_flags & INP_FLAG_GRAB_MOUSE_STATE) ? true : false;
video_info->disp_userdata = disp_get_ptr();
#ifdef HAVE_THREADS
@@ -5917,11 +5895,12 @@ bool video_driver_init_internal(bool *video_is_threaded, bool verbosity_enabled)
unsigned max_dim, scale, width, height;
video_viewport_settings_t *custom_vp = NULL;
input_driver_t *tmp = NULL;
input_driver_t **input_slot = NULL;
void **input_data_slot = NULL;
static uint16_t dummy_pixels[32] = {0};
runloop_state_t *runloop_st = runloop_state_get_ptr();
settings_t *settings = config_get_ptr();
input_driver_state_t *input_st = input_state_get_ptr();
video_driver_state_t *video_st = &video_driver_st;
struct retro_game_geometry *geom = &video_st->av_info.geometry;
const enum retro_pixel_format
@@ -6116,7 +6095,8 @@ bool video_driver_init_internal(bool *video_is_threaded, bool verbosity_enabled)
video_st->frame_count = 0;
video_st->frame_drop_count = 0;
tmp = input_state_get_ptr()->current_driver;
tmp = input_driver_get_current();
input_slot = input_driver_video_slots(&input_data_slot);
/* Need to grab the "real" video driver interface on a reinit. */
video_driver_find_driver(settings, "video driver", verbosity_enabled);
@@ -6150,8 +6130,8 @@ bool video_driver_init_internal(bool *video_is_threaded, bool verbosity_enabled)
ret = video_init_thread(
(const video_driver_t**)&video_st->current_video,
&video_st->data,
&input_state_get_ptr()->current_driver,
(void**)&input_state_get_ptr()->current_data,
input_slot,
input_data_slot,
video_st->current_video,
video);
if (!ret)
@@ -6167,8 +6147,8 @@ bool video_driver_init_internal(bool *video_is_threaded, bool verbosity_enabled)
#endif
video_st->data = video_st->current_video->init(
&video,
&input_state_get_ptr()->current_driver,
(void**)&input_state_get_ptr()->current_data);
input_slot,
input_data_slot);
#ifdef HAVE_WAYLAND
/* A Wayland window kept across the reinit that this driver did not
@@ -6289,13 +6269,12 @@ bool video_driver_init_internal(bool *video_is_threaded, bool verbosity_enabled)
/* Ensure that we preserve the 'grab mouse'
* state if it was enabled prior to driver
* (re-)initialisation */
if (input_st->flags & INP_FLAG_GRAB_MOUSE_STATE)
if (input_driver_get_flags() & INP_FLAG_GRAB_MOUSE_STATE)
{
if ( video_st->poke
&& video_st->poke->show_mouse)
video_st->poke->show_mouse(video_st->data, false);
if (input_driver_grab_mouse())
input_st->flags |= INP_FLAG_GRAB_MOUSE_STATE;
input_driver_grab_mouse_for_video();
}
else if (video.fullscreen)
{
@@ -6303,8 +6282,7 @@ bool video_driver_init_internal(bool *video_is_threaded, bool verbosity_enabled)
&& video_st->poke->show_mouse)
video_st->poke->show_mouse(video_st->data, false);
if (!settings->bools.video_windowed_fullscreen)
if (input_driver_grab_mouse())
input_st->flags |= INP_FLAG_GRAB_MOUSE_STATE;
input_driver_grab_mouse_for_video();
}
#ifdef HAVE_OVERLAY
+66
View File
@@ -6519,6 +6519,72 @@ bool input_key_pressed(int key, bool keyboard_pressed)
return true;
}
/* What the video driver needs of the input driver, as calls into here.
* gfx/ used to take input_state_get_ptr() and work on the fields
* itself: free the driver and the joypads from its own teardown, hand
* out the addresses of current_driver and current_data, read and set
* flags. It still starts the input driver - a video driver's init is
* handed the two slots below and may fill them - but through these. */
uint32_t input_driver_get_flags(void)
{
return input_driver_st.flags;
}
input_driver_t *input_driver_get_current(void)
{
return input_driver_st.current_driver;
}
/* The slots a video driver's init fills in when it brings its own
* input driver. */
input_driver_t **input_driver_video_slots(void ***data_slot)
{
*data_slot = (void**)&input_driver_st.current_data;
return &input_driver_st.current_driver;
}
/* The video driver is going away. Unless the input driver's data is
* the video driver's own (@video_data), the input driver and the
* joypad drivers go with it. */
void input_driver_free_with_video(const void *video_data)
{
input_driver_state_t *input_st = &input_driver_st;
if (input_st->current_data == video_data)
return;
if (input_st->current_driver)
if (input_st->current_driver->free)
input_st->current_driver->free(input_st->current_data);
if (input_st->primary_joypad)
{
const input_device_driver_t *tmp = input_st->primary_joypad;
input_st->primary_joypad = NULL;
tmp->destroy();
}
#ifdef HAVE_MFI
if (input_st->secondary_joypad)
{
const input_device_driver_t *tmp = input_st->secondary_joypad;
input_st->secondary_joypad = NULL;
tmp->destroy();
}
#endif
input_st->flags &= ~INP_FLAG_KB_MAPPING_BLOCKED;
input_st->current_data = NULL;
}
/* Grabs the mouse again for a video driver that has just started, and
* notes it. False if the driver cannot. */
bool input_driver_grab_mouse_for_video(void)
{
if (!input_driver_grab_mouse())
return false;
input_driver_st.flags |= INP_FLAG_GRAB_MOUSE_STATE;
return true;
}
bool video_driver_init_input(
input_driver_t *tmp,
settings_t *settings,
+7
View File
@@ -858,6 +858,13 @@ float input_driver_get_sensor(
uint64_t input_driver_get_capabilities(void);
/* For the video driver: see input_driver.c. */
uint32_t input_driver_get_flags(void);
input_driver_t *input_driver_get_current(void);
input_driver_t **input_driver_video_slots(void ***data_slot);
void input_driver_free_with_video(const void *video_data);
bool input_driver_grab_mouse_for_video(void);
bool video_driver_init_input(
input_driver_t *tmp,
settings_t *settings,
@@ -58,7 +58,7 @@ static unsigned stub_language;
settings_t *config_get_ptr(void) { return &stub_settings; }
video_driver_state_t *video_state_get_ptr(void) { return &stub_video_st; }
input_driver_state_t *input_state_get_ptr(void) { return &stub_input_st; }
uint32_t input_driver_get_flags(void) { return stub_input_st.flags; }
struct menu_state *menu_state_get_ptr(void) { return &stub_menu_st; }
runloop_state_t *runloop_state_get_ptr(void) { return &stub_runloop_st; }
frontend_ctx_driver_t *frontend_get_ptr(void) { return NULL; }