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.
This commit is contained in:
Sam Lantinga 2020-12-09 06:24:40 -08:00
parent 42c5b4acde
commit f2fff21762
2 changed files with 14 additions and 21 deletions

View File

@ -542,21 +542,19 @@ RAWINPUT_InitWindowsGamingInput(RAWINPUT_DeviceContext *ctx)
HRESULT hr; HRESULT hr;
HMODULE hModule = LoadLibraryA("combase.dll"); HMODULE hModule = LoadLibraryA("combase.dll");
if (hModule != NULL) { 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); typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
WindowsCreateString_t WindowsCreateStringFunc = (WindowsCreateString_t)GetProcAddress(hModule, "WindowsCreateString"); WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
if (WindowsCreateStringFunc && WindowsDeleteStringFunc && RoGetActivationFactoryFunc) { if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
LPTSTR pNamespace = L"Windows.Gaming.Input.Gamepad"; LPTSTR pNamespace = L"Windows.Gaming.Input.Gamepad";
HSTRING_HEADER hNamespaceStringHeader;
HSTRING hNamespaceString; HSTRING hNamespaceString;
hr = WindowsCreateStringFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceString); hr = WindowsCreateStringReferenceFunc(pNamespace, (UINT32)SDL_wcslen(pNamespace), &hNamespaceStringHeader, &hNamespaceString);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &wgi_state.gamepad_statics); RoGetActivationFactoryFunc(hNamespaceString, &SDL_IID_IGamepadStatics, &wgi_state.gamepad_statics);
WindowsDeleteStringFunc(hNamespaceString);
} }
} }
FreeLibrary(hModule); FreeLibrary(hModule);

View File

@ -363,29 +363,28 @@ WGI_JoystickInit(void)
HRESULT hr; HRESULT hr;
HMODULE hModule = LoadLibraryA("combase.dll"); HMODULE hModule = LoadLibraryA("combase.dll");
if (hModule != NULL) { 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 *WindowsDeleteString_t)(HSTRING string);
typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory); typedef HRESULT (WINAPI *RoGetActivationFactory_t)(HSTRING activatableClassId, REFIID iid, void** factory);
WindowsCreateString_t WindowsCreateStringFunc = (WindowsCreateString_t)GetProcAddress(hModule, "WindowsCreateString"); WindowsCreateStringReference_t WindowsCreateStringReferenceFunc = (WindowsCreateStringReference_t)GetProcAddress(hModule, "WindowsCreateStringReference");
WindowsDeleteString_t WindowsDeleteStringFunc = (WindowsDeleteString_t)GetProcAddress(hModule, "WindowsDeleteString");
RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory"); RoGetActivationFactory_t RoGetActivationFactoryFunc = (RoGetActivationFactory_t)GetProcAddress(hModule, "RoGetActivationFactory");
if (WindowsCreateStringFunc && WindowsDeleteStringFunc && RoGetActivationFactoryFunc) { if (WindowsCreateStringReferenceFunc && RoGetActivationFactoryFunc) {
LPTSTR pNamespace; LPTSTR pNamespace;
HSTRING_HEADER hNamespaceStringHeader;
HSTRING hNamespaceString; HSTRING hNamespaceString;
pNamespace = L"Windows.Gaming.Input.RawGameController"; 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)) { if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, &wgi.statics); hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRawGameControllerStatics, &wgi.statics);
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%x", hr); SDL_SetError("Couldn't find IRawGameControllerStatics: 0x%x", hr);
} }
WindowsDeleteStringFunc(hNamespaceString);
} }
pNamespace = L"Windows.Gaming.Input.ArcadeStick"; 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)) { if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, &wgi.arcade_stick_statics); hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IArcadeStickStatics, &wgi.arcade_stick_statics);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
@ -393,21 +392,19 @@ WGI_JoystickInit(void)
} else { } else {
SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%x", hr); SDL_SetError("Couldn't find IID_IArcadeStickStatics: 0x%x", hr);
} }
WindowsDeleteStringFunc(hNamespaceString);
} }
pNamespace = L"Windows.Gaming.Input.FlightStick"; 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)) { if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, &wgi.flight_stick_statics); hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IFlightStickStatics, &wgi.flight_stick_statics);
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%x", hr); SDL_SetError("Couldn't find IID_IFlightStickStatics: 0x%x", hr);
} }
WindowsDeleteStringFunc(hNamespaceString);
} }
pNamespace = L"Windows.Gaming.Input.Gamepad"; 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)) { if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, &wgi.gamepad_statics); hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IGamepadStatics, &wgi.gamepad_statics);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
@ -415,11 +412,10 @@ WGI_JoystickInit(void)
} else { } else {
SDL_SetError("Couldn't find IGamepadStatics: 0x%x", hr); SDL_SetError("Couldn't find IGamepadStatics: 0x%x", hr);
} }
WindowsDeleteStringFunc(hNamespaceString);
} }
pNamespace = L"Windows.Gaming.Input.RacingWheel"; 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)) { if (SUCCEEDED(hr)) {
hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, &wgi.racing_wheel_statics); hr = RoGetActivationFactoryFunc(hNamespaceString, &IID_IRacingWheelStatics, &wgi.racing_wheel_statics);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
@ -427,7 +423,6 @@ WGI_JoystickInit(void)
} else { } else {
SDL_SetError("Couldn't find IRacingWheelStatics: 0x%x", hr); SDL_SetError("Couldn't find IRacingWheelStatics: 0x%x", hr);
} }
WindowsDeleteStringFunc(hNamespaceString);
} }
} }
FreeLibrary(hModule); FreeLibrary(hModule);