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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
diff --git a/src/joystick/windows/SDL_rawinputjoystick.c b/src/joystick/windows/SDL_rawinputjoystick.c
index 746f409..1e61098 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 c1c306b..daf9bfe 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);