joystick: linux: Avoid checking for gamepad mapping each frame

The information whether a specific joystick can be used as a gamepad is
not going to change every frame, so we can cache the result into a
variable.

This dramatically reduces the performance impact of SDL2 on small
embedded devices, since the code path that is now avoided was quite
heavy.

Fixes #4229.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
This commit is contained in:
Paul Cercueil 2021-03-24 22:37:08 +00:00 committed by Sam Lantinga
parent 401f485490
commit 1542300a89
1 changed files with 22 additions and 0 deletions

View File

@ -113,6 +113,9 @@ typedef struct SDL_joylist_item
/* Steam Controller support */ /* Steam Controller support */
SDL_bool m_bSteamController; SDL_bool m_bSteamController;
SDL_GamepadMapping *mapping;
SDL_bool has_gamepad_mapping;
} SDL_joylist_item; } SDL_joylist_item;
static SDL_joylist_item *SDL_joylist = NULL; static SDL_joylist_item *SDL_joylist = NULL;
@ -376,6 +379,7 @@ MaybeRemoveDevice(const char *path)
SDL_PrivateJoystickRemoved(item->device_instance); SDL_PrivateJoystickRemoved(item->device_instance);
SDL_free(item->mapping);
SDL_free(item->path); SDL_free(item->path);
SDL_free(item->name); SDL_free(item->name);
SDL_free(item); SDL_free(item);
@ -1403,6 +1407,21 @@ static SDL_bool
LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{ {
SDL_Joystick *joystick; SDL_Joystick *joystick;
SDL_joylist_item *item = JoystickByDevIndex(device_index);
if (item->has_gamepad_mapping) {
SDL_memcpy(out, item->mapping, sizeof(*out));
return SDL_TRUE;
}
if (item->mapping)
return SDL_FALSE;
item->mapping = (SDL_GamepadMapping *) SDL_calloc(sizeof(*item->mapping), 1);
if (item->mapping == NULL) {
SDL_OutOfMemory();
return SDL_FALSE;
}
joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1); joystick = (SDL_Joystick *) SDL_calloc(sizeof(*joystick), 1);
if (joystick == NULL) { if (joystick == NULL) {
@ -1566,6 +1585,9 @@ LINUX_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
LINUX_JoystickClose(joystick); LINUX_JoystickClose(joystick);
SDL_free(joystick); SDL_free(joystick);
SDL_memcpy(item->mapping, out, sizeof(*out));
item->has_gamepad_mapping = SDL_TRUE;
return SDL_TRUE; return SDL_TRUE;
} }