Skip to content

Commit b4d4fc8

Browse files
zeuxelmindreda
authored andcommitted
Optimize _glfwInitJoysticks on OS X.
This function used to enumerate all devices and capture all properties of every device into a dictionary. This takes 180 ms on a MacBook Pro without external devices and 280 ms with an external keyboard/mouse attached. Since we're only interested in a few properties, we can just get them one by one - this reduces the time to <1 ms. Note that we still use the dictionary to get the joystick elements. For unknown reason this is required to get all axes/buttons - without doing this we don't get any joystick elements in addJoystickElement. Closes glfw#332.
1 parent 3b7d34a commit b4d4fc8

File tree

2 files changed

+33
-26
lines changed

2 files changed

+33
-26
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
8181
found for a given `CGDisplay`
8282
- [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier
8383
bit field was unchanged
84+
- [Cocoa] Bugfix: Joystick enumeration took hundreds of ms on some systems
8485
- [Win32] Enabled generation of pkg-config file for MinGW
8586
- [Win32] Bugfix: Failure to load winmm or its functions was not reported to
8687
the error callback
@@ -160,6 +161,7 @@ skills.
160161
- heromyth
161162
- Paul Holden
162163
- Toni Jovanoski
164+
- Arseny Kapoulkine
163165
- Osman Keskin
164166
- Cameron King
165167
- Peter Knut

src/iokit_joystick.m

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -324,43 +324,48 @@ void _glfwInitJoysticks(void)
324324
HRESULT plugInResult = S_OK;
325325
SInt32 score = 0;
326326

327-
long usagePage, usage;
327+
long usagePage = 0;
328+
long usage = 0;
328329

329-
// Check device type
330-
result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject,
331-
&propsRef,
332-
kCFAllocatorDefault,
333-
kNilOptions);
334-
335-
if (result != kIOReturnSuccess)
336-
continue;
337-
338-
valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDPrimaryUsagePageKey));
330+
valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
331+
CFSTR(kIOHIDPrimaryUsagePageKey),
332+
kCFAllocatorDefault, kNilOptions);
339333
if (valueRef)
340334
{
341335
CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage);
342-
if (usagePage != kHIDPage_GenericDesktop)
343-
{
344-
// This device is not relevant to GLFW
345-
CFRelease(propsRef);
346-
continue;
347-
}
336+
CFRelease(valueRef);
348337
}
349338

350-
valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDPrimaryUsageKey));
339+
valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
340+
CFSTR(kIOHIDPrimaryUsageKey),
341+
kCFAllocatorDefault, kNilOptions);
351342
if (valueRef)
352343
{
353344
CFNumberGetValue(valueRef, kCFNumberLongType, &usage);
345+
CFRelease(valueRef);
346+
}
354347

355-
if ((usage != kHIDUsage_GD_Joystick &&
356-
usage != kHIDUsage_GD_GamePad &&
357-
usage != kHIDUsage_GD_MultiAxisController))
358-
{
359-
// This device is not relevant to GLFW
360-
CFRelease(propsRef);
361-
continue;
362-
}
348+
if (usagePage != kHIDPage_GenericDesktop)
349+
{
350+
// This device is not relevant to GLFW
351+
continue;
352+
}
353+
354+
if ((usage != kHIDUsage_GD_Joystick &&
355+
usage != kHIDUsage_GD_GamePad &&
356+
usage != kHIDUsage_GD_MultiAxisController))
357+
{
358+
// This device is not relevant to GLFW
359+
continue;
363360
}
361+
362+
result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject,
363+
&propsRef,
364+
kCFAllocatorDefault,
365+
kNilOptions);
366+
367+
if (result != kIOReturnSuccess)
368+
continue;
364369

365370
_GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy;
366371
joystick->present = GL_TRUE;

0 commit comments

Comments
 (0)