From f2fff21762203db2a1b902f9f322b8e25edf7b99 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 9 Dec 2020 06:24:40 -0800 Subject: [PATCH] Fixed bug 5374 - WGI: Use fast-pass strings. Joel Linn Eliminate additional heap allocation for short-lived HSTRINGs. Uses `WindowsCreateStringReference()` to disable reference counting and memory management by the Window Runtime. --- src/joystick/windows/SDL_rawinputjoystick.c | 12 ++++------ .../windows/SDL_windows_gaming_input.c | 23 ++++++++----------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c index 746f409c7..1e61098c5 100644 --- a/src/joystick/windows/SDL_rawinputjoystick.c +++ b/src/joystick/windows/SDL_rawinputjoystick.c @@ -542,21 +542,19 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx) HRESULT hr; HMODULE hModule = LoadLibraryA("combase.dll"); if (hModule != NULL) { - typedef HRESULT (WINAPI *WindowsCreateString_t)(PCNZWCH sourceString, UINT32 length, HSTRING* string); - typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string); + typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string); typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); - WindowsCreateString_t WindowsCreateStringFunc = (WindowsCreateString_t)GetProcAddress(hModule, "WindowsCreateString"); - WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString"); + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); - if (WindowsCreateStringFunc && WindowsDeleteStringFunc && RoGetActivationFactoryFunc) { + if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { LPTSTR pNamespace = L"Windows.Gaming.Input.Gamepad"; + HSTRING_HEADER hNamespaceStringHeader; HSTRING hNamespaceString; - hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &wgi_state.gamepad_statics); - WindowsDeleteStringFunc(hNamespaceString); } } FreeLibrary(hModule); diff --git a/src/joystick/windows/SDL_windows_gaming_input.c b/src/joystick/windows/SDL_windows_gaming_input.c index c1c306b72..daf9bfe20 100644 --- a/src/joystick/windows/SDL_windows_gaming_input.c +++ b/src/joystick/windows/SDL_windows_gaming_input.c @@ -363,29 +363,28 @@ WGI_JoystickInit(void) HRESULT hr; HMODULE hModule = LoadLibraryA("combase.dll"); if (hModule != NULL) { - typedef HRESULT (WINAPI *WindowsCreateString_t)(PCNZWCH sourceString, UINT32 length, HSTRING* string); + typedef HRESULT (WINAPI *WindowsCreateStringReference_t)(PCWSTR sourceString, UINT32 length, HSTRING_HEADER *hstringHeader, HSTRING* string); typedef HRESULT (WINAPI *WindowsDeleteString_t)(HSTRING string); typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); - WindowsCreateString_t WindowsCreateStringFunc = (WindowsCreateString_t)GetProcAddress(hModule, "WindowsCreateString"); - WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString"); + WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference"); RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); - if (WindowsCreateStringFunc && WindowsDeleteStringFunc && RoGetActivationFactoryFunc) { + if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) { LPTSTR pNamespace; + HSTRING_HEADER hNamespaceStringHeader; HSTRING hNamespaceString; pNamespace = L"Windows.Gaming.Input.RawGameController"; - hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, &wgi.statics); if (!SUCCEEDED(hr)) { SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%x", hr); } - WindowsDeleteStringFunc(hNamespaceString); } pNamespace = L"Windows.Gaming.Input.ArcadeStick"; - hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, &wgi.arcade_stick_statics); if (SUCCEEDED(hr)) { @@ -393,21 +392,19 @@ WGI_JoystickInit(void) } else { SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%x", hr); } - WindowsDeleteStringFunc(hNamespaceString); } pNamespace = L"Windows.Gaming.Input.FlightStick"; - hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, &wgi.flight_stick_statics); if (!SUCCEEDED(hr)) { SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%x", hr); } - WindowsDeleteStringFunc(hNamespaceString); } pNamespace = L"Windows.Gaming.Input.Gamepad"; - hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, &wgi.gamepad_statics); if (SUCCEEDED(hr)) { @@ -415,11 +412,10 @@ WGI_JoystickInit(void) } else { SDL_SetError("Couldn't find IGamepadStatics: 0x%x", hr); } - WindowsDeleteStringFunc(hNamespaceString); } pNamespace = L"Windows.Gaming.Input.RacingWheel"; - hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); + hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString); if (SUCCEEDED(hr)) { hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, &wgi.racing_wheel_statics); if (SUCCEEDED(hr)) { @@ -427,7 +423,6 @@ WGI_JoystickInit(void) } else { SDL_SetError("Couldn't find IRacingWheelStatics: 0x%x", hr); } - WindowsDeleteStringFunc(hNamespaceString); } } FreeLibrary(hModule);