From 01c508f93a88ec2d14e7b69a2950f1da6bc7b23e Mon Sep 17 00:00:00 2001 From: rogerman Date: Sat, 3 Feb 2018 11:31:41 -0800 Subject: [PATCH] Cocoa Port: Remove and replace the high-overhead NSThread with the lower-overhead pthread_t. Improves video display performance when the frame rate is very high (greater than 600 FPS). --- desmume/src/frontend/cocoa/cocoa_GPU.mm | 2 +- desmume/src/frontend/cocoa/cocoa_globals.h | 9 +- desmume/src/frontend/cocoa/cocoa_output.h | 38 +++- desmume/src/frontend/cocoa/cocoa_output.mm | 203 +++++++++-------- desmume/src/frontend/cocoa/cocoa_util.h | 42 +--- desmume/src/frontend/cocoa/cocoa_util.mm | 213 +----------------- .../userinterface/DisplayWindowController.mm | 23 +- .../userinterface/EmuControllerDelegate.mm | 8 +- .../cocoa/userinterface/MacOGLDisplayView.mm | 1 + 9 files changed, 146 insertions(+), 393 deletions(-) diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.mm b/desmume/src/frontend/cocoa/cocoa_GPU.mm index 8770eea64..25fb50338 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.mm +++ b/desmume/src/frontend/cocoa/cocoa_GPU.mm @@ -1199,7 +1199,7 @@ public: { if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]]) { - [CocoaDSUtil messageSendOneWay:[cdsOutput receivePort] msgID:MESSAGE_RECEIVE_GPU_FRAME]; + [(CocoaDSDisplayVideo *)cdsOutput signalMessage:MESSAGE_RECEIVE_GPU_FRAME]; } } diff --git a/desmume/src/frontend/cocoa/cocoa_globals.h b/desmume/src/frontend/cocoa/cocoa_globals.h index ceea51afd..bd4620822 100644 --- a/desmume/src/frontend/cocoa/cocoa_globals.h +++ b/desmume/src/frontend/cocoa/cocoa_globals.h @@ -1,6 +1,6 @@ /* Copyright (C) 2011 Roger Manuel - Copyright (C) 2012-2017 DeSmuME Team + Copyright (C) 2012-2018 DeSmuME Team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -362,13 +362,6 @@ enum MESSAGE_SET_RENDER3D_LINE_HACK, MESSAGE_SET_RENDER3D_MULTISAMPLE, - MESSAGE_SET_AUDIO_PROCESS_METHOD, - MESSAGE_SET_SPU_ADVANCED_LOGIC, - MESSAGE_SET_SPU_SYNC_MODE, - MESSAGE_SET_SPU_SYNC_METHOD, - MESSAGE_SET_SPU_INTERPOLATION_MODE, - MESSAGE_SET_VOLUME, - MESSAGE_COPY_TO_PASTEBOARD }; diff --git a/desmume/src/frontend/cocoa/cocoa_output.h b/desmume/src/frontend/cocoa/cocoa_output.h index 897db98aa..600552e90 100644 --- a/desmume/src/frontend/cocoa/cocoa_output.h +++ b/desmume/src/frontend/cocoa/cocoa_output.h @@ -1,6 +1,6 @@ /* Copyright (C) 2011 Roger Manuel - Copyright (C) 2011-2017 DeSmuME team + Copyright (C) 2011-2018 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,18 +28,31 @@ @class NSImage; @class NSBitmapImageRep; -@interface CocoaDSOutput : CocoaDSThread +@interface CocoaDSOutput : NSObject { + uint32_t _threadMessageID; + pthread_mutex_t _mutexMessageLoop; + pthread_cond_t _condSignalMessage; + pthread_t _pthread; + NSMutableDictionary *property; - pthread_mutex_t *mutexConsume; pthread_rwlock_t *rwlockProducer; + + BOOL _idleState; + OSSpinLock spinlockIdle; } @property (readonly) NSMutableDictionary *property; @property (assign) pthread_rwlock_t *rwlockProducer; -@property (readonly) pthread_mutex_t *mutexConsume; +@property (assign) BOOL idle; +- (void) createThread; +- (void) exitThread; + +- (void) runMessageLoop; +- (void) signalMessage:(int32_t)messageID; +- (void) handleSignalMessageID:(int32_t)messageID; - (void) doCoreEmuFrame; - (void) handleEmuFrameProcessed; @@ -83,12 +96,6 @@ - (NSString *) audioOutputEngineString; - (NSString *) spuInterpolationModeString; - (NSString *) spuSyncMethodString; -- (void) handleSetVolume:(NSData *)volumeData; -- (void) handleSetAudioOutputEngine:(NSData *)methodIdData; -- (void) handleSetSpuAdvancedLogic:(NSData *)stateData; -- (void) handleSetSpuSyncMode:(NSData *)modeIdData; -- (void) handleSetSpuSyncMethod:(NSData *)methodIdData; -- (void) handleSetSpuInterpolationMode:(NSData *)modeIdData; @end @@ -174,3 +181,14 @@ - (NSImage *) image; @end + +#ifdef __cplusplus +extern "C" +{ +#endif + +static void* RunOutputThread(void *arg); + +#ifdef __cplusplus +} +#endif diff --git a/desmume/src/frontend/cocoa/cocoa_output.mm b/desmume/src/frontend/cocoa/cocoa_output.mm index baf2cc1fa..cfa5ba0d3 100644 --- a/desmume/src/frontend/cocoa/cocoa_output.mm +++ b/desmume/src/frontend/cocoa/cocoa_output.mm @@ -1,6 +1,6 @@ /* Copyright (C) 2011 Roger Manuel - Copyright (C) 2011-2017 DeSmuME team + Copyright (C) 2011-2018 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,12 +40,11 @@ @implementation CocoaDSOutput @synthesize property; -@synthesize mutexConsume; @synthesize rwlockProducer; - (id)init { - self = [super initWithAutoreleaseInterval:0.1]; + self = [super init]; if (self == nil) { return self; @@ -54,45 +53,107 @@ property = [[NSMutableDictionary alloc] init]; [property setValue:[NSDate date] forKey:@"outputTime"]; - mutexConsume = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); - pthread_mutex_init(mutexConsume, NULL); - rwlockProducer = NULL; + _threadMessageID = MESSAGE_NONE; + _pthread = NULL; + + _idleState = NO; + spinlockIdle = OS_SPINLOCK_INIT; + return self; } - (void)dealloc { - // Force the thread to exit now so that we can safely release other resources. - [self forceThreadExit]; + [self exitThread]; [property release]; - pthread_mutex_destroy(mutexConsume); - free(mutexConsume); - mutexConsume = NULL; - [super dealloc]; } -- (void) doCoreEmuFrame +- (void) setIdle:(BOOL)theState { - [CocoaDSUtil messageSendOneWay:self.receivePort msgID:MESSAGE_EMU_FRAME_PROCESSED]; + OSSpinLockLock(&spinlockIdle); + _idleState = theState; + OSSpinLockUnlock(&spinlockIdle); } -- (void)handlePortMessage:(NSPortMessage *)portMessage +- (BOOL) idle { - NSInteger message = (NSInteger)[portMessage msgid]; + OSSpinLockLock(&spinlockIdle); + const BOOL theState = _idleState; + OSSpinLockUnlock(&spinlockIdle); - switch (message) + return theState; +} + +- (void) createThread +{ + pthread_mutex_init(&_mutexMessageLoop, NULL); + pthread_cond_init(&_condSignalMessage, NULL); + pthread_create(&_pthread, NULL, &RunOutputThread, self); +} + +- (void) exitThread +{ + pthread_mutex_lock(&_mutexMessageLoop); + + if (_pthread != NULL) + { + _threadMessageID = MESSAGE_NONE; + pthread_mutex_unlock(&_mutexMessageLoop); + + pthread_cancel(_pthread); + pthread_join(_pthread, NULL); + _pthread = NULL; + + pthread_cond_destroy(&_condSignalMessage); + pthread_mutex_destroy(&_mutexMessageLoop); + } + else + { + pthread_mutex_unlock(&_mutexMessageLoop); + } +} + +- (void) runMessageLoop +{ + pthread_mutex_lock(&_mutexMessageLoop); + + do + { + while (_threadMessageID == MESSAGE_NONE) + { + pthread_cond_wait(&_condSignalMessage, &_mutexMessageLoop); + } + + [self handleSignalMessageID:_threadMessageID]; + _threadMessageID = MESSAGE_NONE; + + } while(true); +} + +- (void) signalMessage:(int32_t)messageID +{ + pthread_mutex_lock(&_mutexMessageLoop); + + _threadMessageID = messageID; + pthread_cond_signal(&_condSignalMessage); + + pthread_mutex_unlock(&_mutexMessageLoop); +} + +- (void) handleSignalMessageID:(int32_t)messageID +{ + switch (messageID) { case MESSAGE_EMU_FRAME_PROCESSED: [self handleEmuFrameProcessed]; break; default: - [super handlePortMessage:portMessage]; break; } } @@ -102,6 +163,11 @@ // The base method does nothing. } +- (void) doCoreEmuFrame +{ + [self signalMessage:MESSAGE_EMU_FRAME_PROCESSED]; +} + @end @implementation CocoaDSSpeaker @@ -417,79 +483,6 @@ return theString; } -- (void)handlePortMessage:(NSPortMessage*)portMessage -{ - NSInteger message = (NSInteger)[portMessage msgid]; - NSArray *messageComponents = [portMessage components]; - - switch (message) - { - case MESSAGE_SET_AUDIO_PROCESS_METHOD: - [self handleSetAudioOutputEngine:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_SET_SPU_ADVANCED_LOGIC: - [self handleSetSpuAdvancedLogic:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_SET_SPU_SYNC_MODE: - [self handleSetSpuSyncMode:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_SET_SPU_SYNC_METHOD: - [self handleSetSpuSyncMethod:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_SET_SPU_INTERPOLATION_MODE: - [self handleSetSpuInterpolationMode:[messageComponents objectAtIndex:0]]; - break; - - case MESSAGE_SET_VOLUME: - [self handleSetVolume:[messageComponents objectAtIndex:0]]; - break; - - default: - [super handlePortMessage:portMessage]; - break; - } -} - -- (void) handleSetVolume:(NSData *)volumeData -{ - const float vol = *(float *)[volumeData bytes]; - [self setVolume:vol]; -} - -- (void) handleSetAudioOutputEngine:(NSData *)methodIdData -{ - const NSInteger methodID = *(NSInteger *)[methodIdData bytes]; - [self setAudioOutputEngine:methodID]; -} - -- (void) handleSetSpuAdvancedLogic:(NSData *)stateData -{ - const BOOL theState = *(BOOL *)[stateData bytes]; - [self setSpuAdvancedLogic:theState]; -} - -- (void) handleSetSpuSyncMode:(NSData *)modeIdData -{ - const NSInteger modeID = *(NSInteger *)[modeIdData bytes]; - [self setSpuSyncMode:modeID]; -} - -- (void) handleSetSpuSyncMethod:(NSData *)methodIdData -{ - const NSInteger methodID = *(NSInteger *)[methodIdData bytes]; - [self setSpuSyncMethod:methodID]; -} - -- (void) handleSetSpuInterpolationMode:(NSData *)modeIdData -{ - const NSInteger modeID = *(NSInteger *)[modeIdData bytes]; - [self setSpuInterpolationMode:modeID]; -} - @end @implementation CocoaDSDisplay @@ -511,6 +504,8 @@ _currentReceivedFrameIndex = 0; _receivedFrameCount = 0; + [self createThread]; + return self; } @@ -519,18 +514,16 @@ [super dealloc]; } -- (void)handlePortMessage:(NSPortMessage *)portMessage +- (void) handleSignalMessageID:(int32_t)messageID { - NSInteger message = (NSInteger)[portMessage msgid]; - - switch (message) + switch (messageID) { case MESSAGE_RECEIVE_GPU_FRAME: [self handleReceiveGPUFrame]; break; - + default: - [super handlePortMessage:portMessage]; + [super handleSignalMessageID:messageID]; break; } } @@ -1109,11 +1102,9 @@ return filterID; } -- (void)handlePortMessage:(NSPortMessage *)portMessage +- (void) handleSignalMessageID:(int32_t)messageID { - NSInteger message = (NSInteger)[portMessage msgid]; - - switch (message) + switch (messageID) { case MESSAGE_CHANGE_VIEW_PROPERTIES: [self handleChangeViewProperties]; @@ -1136,7 +1127,7 @@ break; default: - [super handlePortMessage:portMessage]; + [super handleSignalMessageID:messageID]; break; } } @@ -1256,3 +1247,11 @@ } @end + +static void* RunOutputThread(void *arg) +{ + CocoaDSOutput *cdsDisplayOutput = (CocoaDSOutput *)arg; + [cdsDisplayOutput runMessageLoop]; + + return NULL; +} diff --git a/desmume/src/frontend/cocoa/cocoa_util.h b/desmume/src/frontend/cocoa/cocoa_util.h index 4cdc77c65..bf7e130af 100644 --- a/desmume/src/frontend/cocoa/cocoa_util.h +++ b/desmume/src/frontend/cocoa/cocoa_util.h @@ -1,6 +1,6 @@ /* Copyright (C) 2011 Roger Manuel - Copyright (C) 2012-2017 DeSmuME team + Copyright (C) 2012-2018 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,13 +31,6 @@ } -+ (void) messageSendOneWay:(NSPort *)sendPort msgID:(NSInteger)msgID; -+ (void) messageSendOneWayWithMessageComponents:(NSPort *)sendPort msgID:(NSInteger)msgID array:(NSArray *)msgDataArray; -+ (void) messageSendOneWayWithData:(NSPort *)sendPort msgID:(NSInteger)msgID data:(NSData *)msgData; -+ (void) messageSendOneWayWithInteger:(NSPort *)sendPort msgID:(NSInteger)msgID integerValue:(NSInteger)integerValue; -+ (void) messageSendOneWayWithFloat:(NSPort *)sendPort msgID:(NSInteger)msgID floatValue:(float)floatValue; -+ (void) messageSendOneWayWithBool:(NSPort *)sendPort msgID:(NSInteger)msgID boolValue:(BOOL)boolValue; -+ (void) messageSendOneWayWithRect:(NSPort *)sendPort msgID:(NSInteger)msgID rect:(NSRect)rect; + (NSInteger) getIBActionSenderTag:(id)sender; + (BOOL) getIBActionSenderButtonStateBool:(id)sender; @@ -54,39 +47,6 @@ @end -#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 - -#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 -@interface CocoaDSThread : NSObject -#else -@interface CocoaDSThread : NSObject -#endif -{ - NSThread *thread; - BOOL threadExit; - BOOL _idleState; - NSTimeInterval autoreleaseInterval; - NSPort *sendPort; - NSPort *receivePort; - - OSSpinLock spinlockIdle; -} - -@property (assign) NSThread *thread; -@property (assign) BOOL threadExit; -@property (assign) BOOL idle; -@property (assign) NSTimeInterval autoreleaseInterval; -@property (assign) NSPort *sendPort; -@property (assign) NSPort *receivePort; - -- (id) initWithAutoreleaseInterval:(NSTimeInterval)interval; -- (void) runThread:(id)object; -- (void) forceThreadExit; - -@end - -#endif - @protocol DirectoryURLDragDestTextFieldProtocol @required diff --git a/desmume/src/frontend/cocoa/cocoa_util.mm b/desmume/src/frontend/cocoa/cocoa_util.mm index d9069f265..9fed13e4b 100644 --- a/desmume/src/frontend/cocoa/cocoa_util.mm +++ b/desmume/src/frontend/cocoa/cocoa_util.mm @@ -1,6 +1,6 @@ /* Copyright (C) 2011 Roger Manuel - Copyright (C) 2012-2017 DeSmuME team + Copyright (C) 2012-2018 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,94 +30,6 @@ @implementation CocoaDSUtil -static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; - -+ (void) messageSendOneWay:(NSPort *)sendPort msgID:(NSInteger)msgID -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSPortMessage *message = [[NSPortMessage alloc] initWithSendPort:sendPort receivePort:nil components:nil]; - [message setMsgid:msgID]; - [message sendBeforeDate:distantFutureDate]; - [message release]; -} - -+ (void) messageSendOneWayWithMessageComponents:(NSPort *)sendPort msgID:(NSInteger)msgID array:(NSArray *)msgDataArray -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSPortMessage *message = [[NSPortMessage alloc] initWithSendPort:sendPort receivePort:nil components:msgDataArray]; - [message setMsgid:msgID]; - [message sendBeforeDate:distantFutureDate]; - [message release]; -} - -+ (void) messageSendOneWayWithData:(NSPort *)sendPort msgID:(NSInteger)msgID data:(NSData *)msgData -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSArray *messageComponents = [[NSArray alloc] initWithObjects:msgData, nil]; - [CocoaDSUtil messageSendOneWayWithMessageComponents:sendPort msgID:msgID array:messageComponents]; - [messageComponents release]; -} - -+ (void) messageSendOneWayWithInteger:(NSPort *)sendPort msgID:(NSInteger)msgID integerValue:(NSInteger)integerValue -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSData *messageData = [[NSData alloc] initWithBytes:&integerValue length:sizeof(NSInteger)]; - [CocoaDSUtil messageSendOneWayWithData:sendPort msgID:msgID data:messageData]; - [messageData release]; -} - -+ (void) messageSendOneWayWithFloat:(NSPort *)sendPort msgID:(NSInteger)msgID floatValue:(float)floatValue -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSData *messageData = [[NSData alloc] initWithBytes:&floatValue length:sizeof(float)]; - [CocoaDSUtil messageSendOneWayWithData:sendPort msgID:msgID data:messageData]; - [messageData release]; -} - -+ (void) messageSendOneWayWithBool:(NSPort *)sendPort msgID:(NSInteger)msgID boolValue:(BOOL)boolValue -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSData *messageData = [[NSData alloc] initWithBytes:&boolValue length:sizeof(BOOL)]; - [CocoaDSUtil messageSendOneWayWithData:sendPort msgID:msgID data:messageData]; - [messageData release]; -} - -+ (void) messageSendOneWayWithRect:(NSPort *)sendPort msgID:(NSInteger)msgID rect:(NSRect)rect -{ - if (sendPort == nil || ![sendPort isValid]) - { - return; - } - - NSData *messageData = [[NSData alloc] initWithBytes:&rect length:sizeof(NSRect)]; - [CocoaDSUtil messageSendOneWayWithData:sendPort msgID:msgID data:messageData]; - [messageData release]; -} - + (NSInteger) getIBActionSenderTag:(id)sender { NSInteger senderTag = 0; @@ -253,129 +165,6 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain]; @end -#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4 -@implementation CocoaDSThread - -@synthesize thread; -@synthesize threadExit; -@dynamic idle; -@synthesize autoreleaseInterval; -@synthesize sendPort; -@synthesize receivePort; - -- (id)init -{ - return [self initWithAutoreleaseInterval:15.0]; -} - -- (id) initWithAutoreleaseInterval:(NSTimeInterval)interval -{ - // Set up thread info. - thread = nil; - threadExit = NO; - _idleState = NO; - autoreleaseInterval = interval; - - spinlockIdle = OS_SPINLOCK_INIT; - - // Set up thread ports. - sendPort = [[NSPort port] retain]; - [sendPort setDelegate:self]; - receivePort = [[NSPort port] retain]; - [receivePort setDelegate:self]; - - return self; -} - -- (void)dealloc -{ - [self forceThreadExit]; - - [super dealloc]; -} - -- (void) setIdle:(BOOL)theState -{ - OSSpinLockLock(&spinlockIdle); - _idleState = theState; - OSSpinLockUnlock(&spinlockIdle); -} - -- (BOOL) idle -{ - OSSpinLockLock(&spinlockIdle); - const BOOL theState = _idleState; - OSSpinLockUnlock(&spinlockIdle); - - return theState; -} - -- (void) runThread:(id)object -{ - NSAutoreleasePool *threadPool = [[NSAutoreleasePool alloc] init]; - NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; - - [runLoop addPort:[self receivePort] forMode:NSDefaultRunLoopMode]; - [self setThread:[NSThread currentThread]]; - - do - { - NSAutoreleasePool *runLoopPool = [[NSAutoreleasePool alloc] init]; - NSDate *runDate = [[NSDate alloc] initWithTimeIntervalSinceNow:[self autoreleaseInterval]]; - [runLoop runUntilDate:runDate]; - [runDate release]; - [runLoopPool release]; - } while (![self threadExit]); - - NSPort *tempSendPort = [self sendPort]; - [self setSendPort:nil]; - [tempSendPort invalidate]; - [tempSendPort release]; - - NSPort *tempReceivePort = [self receivePort]; - [self setReceivePort:nil]; - [tempReceivePort invalidate]; - [tempReceivePort release]; - - [threadPool release]; - [self setThread:nil]; -} - -- (void) forceThreadExit -{ - if ([self thread] == nil) - { - return; - } - - [self setThreadExit:YES]; - [self setIdle:NO]; - - // Wait until the thread has shut down. - while ([self thread] != nil) - { - [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; - } -} - -- (void)handlePortMessage:(NSPortMessage *)portMessage -{ - NSInteger message = (NSInteger)[portMessage msgid]; - - switch (message) - { - case MESSAGE_EXIT_THREAD: - [self setThreadExit:YES]; - break; - - default: - break; - } -} - -@end -#endif - @implementation DirectoryURLDragDestTextField - (id)initWithCoder:(NSCoder *)coder diff --git a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm index 46fc134e8..c0d226927 100644 --- a/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm +++ b/desmume/src/frontend/cocoa/userinterface/DisplayWindowController.mm @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2017 DeSmuME team + Copyright (C) 2013-2018 DeSmuME team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -698,7 +698,7 @@ static std::unordered_map _screenMap; // - (IBAction) copy:(id)sender { - [CocoaDSUtil messageSendOneWay:[[[self view] cdsVideoOutput] receivePort] msgID:MESSAGE_COPY_TO_PASTEBOARD]; + [[[self view] cdsVideoOutput] signalMessage:MESSAGE_COPY_TO_PASTEBOARD]; } - (IBAction) changeHardwareMicGain:(id)sender @@ -1311,12 +1311,6 @@ static std::unordered_map _screenMap; // // Add the video thread to the output list. [emuControl addOutputToCore:newDisplayOutput]; - [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newDisplayOutput withObject:nil]; - while ([newDisplayOutput thread] == nil) - { - [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; - } - // Setup default values per user preferences. [self setupUserDefaults]; } @@ -1449,7 +1443,6 @@ static std::unordered_map _screenMap; // - (void)windowWillClose:(NSNotification *)notification { [emuControl removeOutputFromCore:[[self view] cdsVideoOutput]]; - [[[self view] cdsVideoOutput] forceThreadExit]; [[emuControl windowList] removeObject:self]; @@ -1946,7 +1939,7 @@ static std::unordered_map _screenMap; // - (void) setDisplayMainVideoSource:(NSInteger)displaySourceID { [[self cdsVideoOutput] setDisplayMainVideoSource:displaySourceID]; - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; + [[self cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW]; } - (NSInteger) displayMainVideoSource @@ -1957,7 +1950,7 @@ static std::unordered_map _screenMap; // - (void) setDisplayTouchVideoSource:(NSInteger)displaySourceID { [[self cdsVideoOutput] setDisplayTouchVideoSource:displaySourceID]; - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; + [[self cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW]; } - (NSInteger) displayTouchVideoSource @@ -1997,7 +1990,7 @@ static std::unordered_map _screenMap; // [macSharedData decrementViewsUsingDirectToCPUFiltering]; } - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; + [[self cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW]; } } @@ -2029,7 +2022,7 @@ static std::unordered_map _screenMap; // } } - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW]; + [[self cdsVideoOutput] signalMessage:MESSAGE_REPROCESS_AND_REDRAW]; } - (BOOL) sourceDeposterize @@ -2040,7 +2033,7 @@ static std::unordered_map _screenMap; // - (void) setOutputFilter:(NSInteger)filterID { [[self cdsVideoOutput] setOutputFilter:filterID]; - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REDRAW_VIEW]; + [[self cdsVideoOutput] signalMessage:MESSAGE_REDRAW_VIEW]; } - (NSInteger) outputFilter @@ -2071,7 +2064,7 @@ static std::unordered_map _screenMap; // } } - [CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW]; + [[self cdsVideoOutput] signalMessage:MESSAGE_REPROCESS_AND_REDRAW]; } - (NSInteger) pixelScaler diff --git a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm index bd2b262b6..b56287bc0 100644 --- a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2017 DeSmuME Team + Copyright (C) 2013-2018 DeSmuME Team This file is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1464,7 +1464,7 @@ for (DisplayWindowController *windowController in windowList) { - [CocoaDSUtil messageSendOneWay:[[[windowController view] cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; + [[[windowController view] cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW]; } [self setStatusText:NSSTRING_STATUS_EMULATOR_RESET]; @@ -1762,7 +1762,7 @@ for (DisplayWindowController *windowController in windowList) { - [CocoaDSUtil messageSendOneWay:[[[windowController view] cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; + [[[windowController view] cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW]; } [self setStatusText:NSSTRING_STATUS_ROM_LOADED]; @@ -1845,7 +1845,7 @@ [[cdsCore cdsGPU] clearWithColor:0x8000]; for (DisplayWindowController *windowController in windowList) { - [CocoaDSUtil messageSendOneWay:[[[windowController view] cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW]; + [[[windowController view] cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW]; } [self setStatusText:NSSTRING_STATUS_ROM_UNLOADED]; diff --git a/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm b/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm index e43a78786..e489444c6 100644 --- a/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm +++ b/desmume/src/frontend/cocoa/userinterface/MacOGLDisplayView.mm @@ -505,6 +505,7 @@ void MacOGLDisplayView::SetViewNeedsFlush() if (this->GetRenderToCALayer()) { [this->_caLayer setNeedsDisplay]; + [CATransaction flush]; } else {