From e2ffb51c2ddf85ffa536cfdf734209af0b7782e9 Mon Sep 17 00:00:00 2001 From: meancoot Date: Sun, 5 Jan 2014 20:12:04 -0500 Subject: [PATCH] (iOS) Fix brutal BTstack lag --- apple/common/setting_data.c | 6 ++++ apple/common/setting_data.h | 4 ++- apple/iOS/bluetooth/btdynamic.c | 59 ++++++++++++++++++++++++--------- apple/iOS/bluetooth/btdynamic.h | 1 + apple/iOS/bluetooth/btpad.c | 31 +++++++++-------- apple/iOS/menu.m | 4 ++- apple/iOS/platform.m | 9 +++-- 7 files changed, 82 insertions(+), 32 deletions(-) diff --git a/apple/common/setting_data.c b/apple/common/setting_data.c index 6866b44a28..1a1c07a095 100644 --- a/apple/common/setting_data.c +++ b/apple/common/setting_data.c @@ -120,6 +120,9 @@ void setting_data_reset_setting(const rarch_setting_t* setting) default: break; } + + if (setting->change_handler) + setting->change_handler(setting); } void setting_data_reset(const rarch_setting_t* settings) @@ -284,6 +287,9 @@ void setting_data_set_with_string_representation(const rarch_setting_t* setting, default: return; } + + if (setting->change_handler) + setting->change_handler(setting); } const char* setting_data_get_string_representation(const rarch_setting_t* setting, char* buffer, size_t length) diff --git a/apple/common/setting_data.h b/apple/common/setting_data.h index 3364693f28..cd2dfc3a84 100644 --- a/apple/common/setting_data.h +++ b/apple/common/setting_data.h @@ -41,7 +41,7 @@ enum setting_flags SD_FLAG_HAS_RANGE = 16 }; -typedef struct +typedef struct rarch_setting_t { enum setting_type type; @@ -58,6 +58,8 @@ typedef struct const char* values; uint64_t flags; + void (*change_handler)(const struct rarch_setting_t* setting); + union { bool boolean; diff --git a/apple/iOS/bluetooth/btdynamic.c b/apple/iOS/bluetooth/btdynamic.c index 3dd455543b..8ac9c78888 100644 --- a/apple/iOS/bluetooth/btdynamic.c +++ b/apple/iOS/bluetooth/btdynamic.c @@ -12,6 +12,7 @@ * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ +#include #include #include #include @@ -30,6 +31,7 @@ static struct } grabbers[] = { GRAB(bt_open), + GRAB(bt_close), GRAB(bt_flip_addr), GRAB(bd_addr_to_str), GRAB(bt_register_packet_handler), @@ -61,8 +63,9 @@ extern void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t static bool btstack_tested; static bool btstack_loaded; -static bool btstack_open; -static bool btstack_poweron; + +static pthread_t btstack_thread; +static CFRunLoopSourceRef btstack_quit_source; bool btstack_try_load() { @@ -108,28 +111,54 @@ bool btstack_try_load() return true; } +void btstack_thread_stop() +{ + bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_OFF); +} + +static void* btstack_thread_func(void* data) +{ + RARCH_LOG("BTstack: Thread started"); + + if (bt_open_ptr()) + { + RARCH_LOG("BTstack: bt_open() failed\n"); + return 0; + } + + CFRunLoopSourceContext ctx = { 0, 0, 0, 0, 0, 0, 0, 0, 0, btstack_thread_stop }; + btstack_quit_source = CFRunLoopSourceCreate(0, 0, &ctx); + CFRunLoopAddSource(CFRunLoopGetCurrent(), btstack_quit_source, kCFRunLoopCommonModes); + + RARCH_LOG("BTstack: Turning on\n"); + bt_send_cmd_ptr(btstack_set_power_mode_ptr, HCI_POWER_ON); + + RARCH_LOG("BTstack: Running\n"); + CFRunLoopRun(); + + RARCH_LOG("BTstack: Done\n"); + + CFRunLoopSourceInvalidate(btstack_quit_source); + CFRelease(btstack_quit_source); + return 0; +} + void btstack_set_poweron(bool on) { if (!btstack_try_load()) return; - if (!btstack_open && bt_open_ptr()) + if (on && !btstack_thread) + pthread_create(&btstack_thread, 0, btstack_thread_func, 0); + else if (!on && btstack_thread && btstack_quit_source) { - RARCH_LOG("BTstack: bt_open failed\n"); - btstack_loaded = false; - return; + CFRunLoopSourceSignal(btstack_quit_source); + pthread_join(btstack_thread, 0); + btstack_thread = 0; } - - btstack_open = true; - if (on != btstack_poweron) - { - btstack_poweron = on; - RARCH_LOG("BTstack: Turning %s\n", on ? "on" : "off"); - bt_send_cmd_ptr(btstack_set_power_mode_ptr, on ? HCI_POWER_ON : HCI_POWER_OFF); - } } bool btstack_is_running() { - return btstack_poweron; + return btstack_thread; } diff --git a/apple/iOS/bluetooth/btdynamic.h b/apple/iOS/bluetooth/btdynamic.h index 324c90976a..7a24cbffe1 100644 --- a/apple/iOS/bluetooth/btdynamic.h +++ b/apple/iOS/bluetooth/btdynamic.h @@ -31,6 +31,7 @@ bool btstack_is_running(); #endif BTDIMPORT int (*bt_open_ptr)(void); +BTDIMPORT void (*bt_close_ptr)(void); BTDIMPORT void (*bt_flip_addr_ptr)(bd_addr_t dest, bd_addr_t src); BTDIMPORT char* (*bd_addr_to_str_ptr)(bd_addr_t addr); BTDIMPORT btstack_packet_handler_t (*bt_register_packet_handler_ptr)(btstack_packet_handler_t handler); diff --git a/apple/iOS/bluetooth/btpad.c b/apple/iOS/bluetooth/btpad.c index c2ac281e55..b1fc84a14c 100644 --- a/apple/iOS/bluetooth/btpad.c +++ b/apple/iOS/bluetooth/btpad.c @@ -114,20 +114,25 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet { case BTSTACK_EVENT_STATE: { - if (packet[2] == HCI_STATE_WORKING) - { - btpad_queue_reset(); + RARCH_LOG("BTstack: HCI State %d\n", packet[2]); + + switch (packet[2]) + { + case HCI_STATE_WORKING: + btpad_queue_reset(); - btpad_queue_hci_read_bd_addr(); - bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); // TODO: Where did I get 672 for mtu? - bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672); - btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1); + btpad_queue_hci_read_bd_addr(); + bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_CONTROL, 672); // TODO: Where did I get 672 for mtu? + bt_send_cmd_ptr(l2cap_register_service_ptr, PSM_HID_INTERRUPT, 672); + btpad_queue_hci_inquiry(HCI_INQUIRY_LAP, 3, 1); - btpad_queue_run(1); - } - else if(packet[2] > HCI_STATE_WORKING) - { - btpad_close_all_connections(); + btpad_queue_run(1); + break; + + case HCI_STATE_HALTING: + btpad_close_all_connections(); + CFRunLoopStop(CFRunLoopGetCurrent()); + break; } } break; @@ -303,7 +308,7 @@ void btpad_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t *packet case L2CAP_EVENT_SERVICE_REGISTERED: { - if (!packet[2]) + if (packet[2]) RARCH_LOG("BTpad: Got failed 'Service Registered' event (PSM: %02X, Status: %02X)\n", READ_BT_16(packet, 3), packet[2]); } break; diff --git a/apple/iOS/menu.m b/apple/iOS/menu.m index c04cb7718f..a48c423186 100644 --- a/apple/iOS/menu.m +++ b/apple/iOS/menu.m @@ -391,6 +391,8 @@ static void RunActionSheet(const char* title, const struct string_list* items, U - (void)wasSelectedOnTableView:(UITableView*)tableView ofController:(UIViewController*)controller { + RAMenuItemEnumSetting __weak* weakSelf = self; + struct string_list* items = string_split(self.setting->values, "|"); RunActionSheet(self.setting->short_description, items, self.parentTable, ^(UIActionSheet* actionSheet, NSInteger buttonIndex) @@ -398,7 +400,7 @@ static void RunActionSheet(const char* title, const struct string_list* items, U if (buttonIndex != actionSheet.cancelButtonIndex) { setting_data_set_with_string_representation(self.setting, [[actionSheet buttonTitleAtIndex:buttonIndex] UTF8String]); - [self.parentTable reloadData]; + [weakSelf.parentTable reloadData]; } }); string_list_free(items); diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index ee9ef28ab7..1a6ecdf744 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -32,7 +32,6 @@ apple_frontend_settings_t apple_frontend_settings; -#ifdef IOS int get_ios_version_major(void) { static int version = -1; @@ -48,7 +47,11 @@ void ios_set_bluetooth_mode(NSString* mode) apple_input_enable_icade([mode isEqualToString:@"icade"]); btstack_set_poweron([mode isEqualToString:@"btstack"]); } -#endif + +static void apple_refresh_frontend_config(const rarch_setting_t* setting) +{ + [[RetroArch_iOS get] refreshSystemConfig]; +} const void* apple_get_frontend_settings(void) { @@ -60,9 +63,11 @@ const void* apple_get_frontend_settings(void) settings[1] = setting_data_group_setting(ST_SUB_GROUP, "Frontend"); settings[2] = setting_data_bool_setting("ios_use_file_log", "Enable File Logging", &apple_frontend_settings.logging_enabled, false); + settings[2].change_handler = apple_refresh_frontend_config; settings[3] = setting_data_bool_setting("ios_tv_mode", "TV Mode", &apple_use_tv_mode, false); settings[4] = setting_data_string_setting(ST_STRING, "ios_btmode", "Bluetooth Input Type", apple_frontend_settings.bluetooth_mode, sizeof(apple_frontend_settings.bluetooth_mode), "none"); + settings[4].change_handler = apple_refresh_frontend_config; // Set ios_btmode options based on runtime environment if (btstack_try_load())