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.
This commit is contained in:
Arseny Kapoulkine 2014-05-01 22:39:21 -07:00 committed by Camilla Berglund
parent 3b7d34a1d5
commit b4d4fc8f79
2 changed files with 37 additions and 30 deletions

View File

@ -81,6 +81,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
found for a given `CGDisplay`
- [Cocoa] Bugfix: Modifier key events were lost if the corresponding modifier
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] Bugfix: Failure to load winmm or its functions was not reported to
the error callback
@ -160,6 +161,7 @@ skills.
- heromyth
- Paul Holden
- Toni Jovanoski
- Arseny Kapoulkine
- Osman Keskin
- Cameron King
- Peter Knut

View File

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