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 #332.
master
Arseny Kapoulkine ago%!(EXTRA string=11 years) committed by Camilla Berglund
parent 3b7d34a1d5
commit b4d4fc8f79
  1. 2
      README.md
  2. 57
      src/iokit_joystick.m

@ -81,6 +81,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
found for a given `CGDisplay` found for a given `CGDisplay`
- [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier - [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier
bit field was unchanged bit field was unchanged
- [Cocoa] Bugfix: Joystick enumeration took hundreds of ms on some systems
- [Win32] Enabled generation of pkg-config file for MinGW - [Win32] Enabled generation of pkg-config file for MinGW
- [Win32] Bugfix: Failure to load winmm or its functions was not reported to - [Win32] Bugfix: Failure to load winmm or its functions was not reported to
the error callback the error callback
@ -160,6 +161,7 @@ skills.
- heromyth - heromyth
- Paul Holden - Paul Holden
- Toni Jovanoski - Toni Jovanoski
- Arseny Kapoulkine
- Osman Keskin - Osman Keskin
- Cameron King - Cameron King
- Peter Knut - Peter Knut

@ -324,43 +324,48 @@ void _glfwInitJoysticks(void)
HRESULT plugInResult = S_OK; HRESULT plugInResult = S_OK;
SInt32 score = 0; SInt32 score = 0;
long usagePage, usage; long usagePage = 0;
long usage = 0;
// Check device type valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, CFSTR(kIOHIDPrimaryUsagePageKey),
&propsRef, kCFAllocatorDefault, kNilOptions);
kCFAllocatorDefault,
kNilOptions);
if (result != kIOReturnSuccess)
continue;
valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDPrimaryUsagePageKey));
if (valueRef) if (valueRef)
{ {
CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage); CFNumberGetValue(valueRef, kCFNumberLongType, &usagePage);
if (usagePage != kHIDPage_GenericDesktop) CFRelease(valueRef);
{
// This device is not relevant to GLFW
CFRelease(propsRef);
continue;
}
} }
valueRef = CFDictionaryGetValue(propsRef, CFSTR(kIOHIDPrimaryUsageKey)); valueRef = IORegistryEntryCreateCFProperty(ioHIDDeviceObject,
CFSTR(kIOHIDPrimaryUsageKey),
kCFAllocatorDefault, kNilOptions);
if (valueRef) if (valueRef)
{ {
CFNumberGetValue(valueRef, kCFNumberLongType, &usage); CFNumberGetValue(valueRef, kCFNumberLongType, &usage);
CFRelease(valueRef);
}
if ((usage != kHIDUsage_GD_Joystick && if (usagePage != kHIDPage_GenericDesktop)
usage != kHIDUsage_GD_GamePad && {
usage != kHIDUsage_GD_MultiAxisController)) // This device is not relevant to GLFW
{ continue;
// This device is not relevant to GLFW }
CFRelease(propsRef);
continue; if ((usage != kHIDUsage_GD_Joystick &&
} usage != kHIDUsage_GD_GamePad &&
usage != kHIDUsage_GD_MultiAxisController))
{
// This device is not relevant to GLFW
continue;
} }
result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject,
&propsRef,
kCFAllocatorDefault,
kNilOptions);
if (result != kIOReturnSuccess)
continue;
_GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy; _GLFWjoystickIOKit* joystick = _glfw.iokit_js + joy;
joystick->present = GL_TRUE; joystick->present = GL_TRUE;

Loading…
Cancel
Save