From e7de2bbc9ef89fbd9635c6f0355f27a99b502530 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 1 May 2014 22:39:21 -0700 Subject: [PATCH] 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. --- src/iokit_joystick.m | 65 ++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/src/iokit_joystick.m b/src/iokit_joystick.m index a09fbcf3e..5ff67dd8e 100644 --- a/src/iokit_joystick.m +++ b/src/iokit_joystick.m @@ -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;