From 8bc745fb55c55623d8ada90198db8cdc8b6be8e0 Mon Sep 17 00:00:00 2001 From: Vincent Bénony Date: Wed, 27 Sep 2017 19:06:42 +0200 Subject: IOS: Improve iOS 11 compatibility --- backends/platform/ios7/ios7_app_delegate.mm | 15 ++++------ backends/platform/ios7/ios7_common.h | 1 + backends/platform/ios7/ios7_osys_main.cpp | 4 +++ backends/platform/ios7/ios7_osys_video.mm | 45 ++++++++++++++++++++++------- backends/platform/ios7/ios7_video.mm | 19 ++++++++++-- 5 files changed, 63 insertions(+), 21 deletions(-) diff --git a/backends/platform/ios7/ios7_app_delegate.mm b/backends/platform/ios7/ios7_app_delegate.mm index 88d0a8925e..014275d116 100644 --- a/backends/platform/ios7/ios7_app_delegate.mm +++ b/backends/platform/ios7/ios7_app_delegate.mm @@ -39,14 +39,6 @@ return self; } -- (void)mainLoop:(id)param { - @autoreleasepool { - iOS7_main(iOS7_argc, iOS7_argv); - } - - exit(0); -} - - (void)applicationDidFinishLaunching:(UIApplication *)application { CGRect rect = [[UIScreen mainScreen] bounds]; @@ -78,7 +70,12 @@ name:@"UIDeviceOrientationDidChangeNotification" object:nil]; - [NSThread detachNewThreadSelector:@selector(mainLoop:) toTarget:self withObject:nil]; + // Force creation of the shared instance on the main thread + iOS7_buildSharedOSystemInstance(); + + dispatch_async(dispatch_get_global_queue(0, 0), ^{ + iOS7_main(iOS7_argc, iOS7_argv); + }); } - (void)applicationWillResignActive:(UIApplication *)application { diff --git a/backends/platform/ios7/ios7_common.h b/backends/platform/ios7/ios7_common.h index 3609387efd..d5c1135564 100644 --- a/backends/platform/ios7/ios7_common.h +++ b/backends/platform/ios7/ios7_common.h @@ -122,6 +122,7 @@ void iOS7_updateScreen(); bool iOS7_fetchEvent(InternalEvent *event); bool iOS7_isBigDevice(); +void iOS7_buildSharedOSystemInstance(); void iOS7_main(int argc, char **argv); const char *iOS7_getDocumentsDir(); bool iOS7_touchpadModeEnabled(); diff --git a/backends/platform/ios7/ios7_osys_main.cpp b/backends/platform/ios7/ios7_osys_main.cpp index 3a627478f9..90c294a7d5 100644 --- a/backends/platform/ios7/ios7_osys_main.cpp +++ b/backends/platform/ios7/ios7_osys_main.cpp @@ -365,6 +365,10 @@ bool iOS7_touchpadModeEnabled() { return sys && sys->touchpadModeEnabled(); } +void iOS7_buildSharedOSystemInstance() { + OSystem_iOS7::sharedInstance(); +} + void iOS7_main(int argc, char **argv) { //OSystem_iOS7::migrateApp(); diff --git a/backends/platform/ios7/ios7_osys_video.mm b/backends/platform/ios7/ios7_osys_video.mm index 1ec0defd7e..f0af1f92ee 100644 --- a/backends/platform/ios7/ios7_osys_video.mm +++ b/backends/platform/ios7/ios7_osys_video.mm @@ -120,6 +120,15 @@ Common::List OSystem_iOS7::getSupportedFormats() const { } #endif +static inline void execute_on_main_thread(void (^block)(void)) { + if ([NSThread currentThread] == [NSThread mainThread]) { + block(); + } + else { + dispatch_sync(dispatch_get_main_queue(), block); + } +} + void OSystem_iOS7::initSize(uint width, uint height, const Graphics::PixelFormat *format) { //printf("initSize(%u, %u, %p)\n", width, height, (const void *)format); @@ -135,7 +144,9 @@ void OSystem_iOS7::initSize(uint width, uint height, const Graphics::PixelFormat // Create the screen texture right here. We need to do this here, since // when a game requests hi-color mode, we actually set the framebuffer // to the texture buffer to avoid an additional copy step. - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(createScreenTexture) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] createScreenTexture]; + }); // In case the client code tries to set up a non supported mode, we will // fall back to CLUT8 and set the transaction error accordingly. @@ -172,13 +183,17 @@ void OSystem_iOS7::beginGFXTransaction() { OSystem::TransactionError OSystem_iOS7::endGFXTransaction() { _screenChangeCount++; updateOutputSurface(); - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(setGraphicsMode) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] setGraphicsMode]; + }); return _gfxTransactionError; } void OSystem_iOS7::updateOutputSurface() { - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(initSurface) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] initSurface]; + }); } int16 OSystem_iOS7::getHeight() { @@ -338,7 +353,9 @@ void OSystem_iOS7::unlockScreen() { void OSystem_iOS7::setShakePos(int shakeOffset) { //printf("setShakePos(%i)\n", shakeOffset); _videoContext->shakeOffsetY = shakeOffset; - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(setViewTransformation) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] setViewTransformation]; + }); // HACK: We use this to force a redraw. _mouseDirty = true; } @@ -348,8 +365,10 @@ void OSystem_iOS7::showOverlay() { _videoContext->overlayVisible = true; dirtyFullOverlayScreen(); updateScreen(); - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES]; - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] updateMouseCursorScaling]; + [[iOS7AppDelegate iPhoneView] clearColorBuffer]; + }); } void OSystem_iOS7::hideOverlay() { @@ -357,8 +376,10 @@ void OSystem_iOS7::hideOverlay() { _videoContext->overlayVisible = false; _dirtyOverlayRects.clear(); dirtyFullScreen(); - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(updateMouseCursorScaling) withObject:nil waitUntilDone: YES]; - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(clearColorBuffer) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] updateMouseCursorScaling]; + [[iOS7AppDelegate iPhoneView] clearColorBuffer]; + }); } void OSystem_iOS7::clearOverlay() { @@ -439,7 +460,9 @@ void OSystem_iOS7::warpMouse(int x, int y) { //printf("warpMouse(%d, %d)\n", x, y); _videoContext->mouseX = x; _videoContext->mouseY = y; - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(notifyMouseMove) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] notifyMouseMove]; + }); _mouseDirty = true; } @@ -552,5 +575,7 @@ void OSystem_iOS7::updateMouseTexture() { } } - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(updateMouseCursor) withObject:nil waitUntilDone: YES]; + execute_on_main_thread(^ { + [[iOS7AppDelegate iPhoneView] updateMouseCursor]; + }); } diff --git a/backends/platform/ios7/ios7_video.mm b/backends/platform/ios7/ios7_video.mm index 5baa83e8e8..85a4dc91d8 100644 --- a/backends/platform/ios7/ios7_video.mm +++ b/backends/platform/ios7/ios7_video.mm @@ -55,16 +55,31 @@ bool iOS7_isBigDevice() { return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; } +static inline void execute_on_main_thread(void (^block)(void)) { + if ([NSThread currentThread] == [NSThread mainThread]) { + block(); + } + else { + dispatch_sync(dispatch_get_main_queue(), block); + } +} + void iOS7_updateScreen() { //printf("Mouse: (%i, %i)\n", mouseX, mouseY); if (!g_needsScreenUpdate) { g_needsScreenUpdate = 1; - [[iOS7AppDelegate iPhoneView] performSelectorOnMainThread:@selector(updateSurface) withObject:nil waitUntilDone: NO]; + execute_on_main_thread(^{ + [[iOS7AppDelegate iPhoneView] updateSurface]; + }); } } bool iOS7_fetchEvent(InternalEvent *event) { - return [[iOS7AppDelegate iPhoneView] fetchEvent:event]; + __block bool fetched; + execute_on_main_thread(^{ + fetched = [[iOS7AppDelegate iPhoneView] fetchEvent:event]; + }); + return fetched; } uint getSizeNextPOT(uint size) { -- cgit v1.2.3