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).
This commit is contained in:
parent
f9c32c9e79
commit
01c508f93a
|
@ -1199,7 +1199,7 @@ public:
|
||||||
{
|
{
|
||||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]])
|
if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]])
|
||||||
{
|
{
|
||||||
[CocoaDSUtil messageSendOneWay:[cdsOutput receivePort] msgID:MESSAGE_RECEIVE_GPU_FRAME];
|
[(CocoaDSDisplayVideo *)cdsOutput signalMessage:MESSAGE_RECEIVE_GPU_FRAME];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Roger Manuel
|
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
|
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
|
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_LINE_HACK,
|
||||||
MESSAGE_SET_RENDER3D_MULTISAMPLE,
|
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
|
MESSAGE_COPY_TO_PASTEBOARD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Roger Manuel
|
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,18 +28,31 @@
|
||||||
@class NSImage;
|
@class NSImage;
|
||||||
@class NSBitmapImageRep;
|
@class NSBitmapImageRep;
|
||||||
|
|
||||||
@interface CocoaDSOutput : CocoaDSThread
|
@interface CocoaDSOutput : NSObject
|
||||||
{
|
{
|
||||||
|
uint32_t _threadMessageID;
|
||||||
|
pthread_mutex_t _mutexMessageLoop;
|
||||||
|
pthread_cond_t _condSignalMessage;
|
||||||
|
pthread_t _pthread;
|
||||||
|
|
||||||
NSMutableDictionary *property;
|
NSMutableDictionary *property;
|
||||||
|
|
||||||
pthread_mutex_t *mutexConsume;
|
|
||||||
pthread_rwlock_t *rwlockProducer;
|
pthread_rwlock_t *rwlockProducer;
|
||||||
|
|
||||||
|
BOOL _idleState;
|
||||||
|
OSSpinLock spinlockIdle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@property (readonly) NSMutableDictionary *property;
|
@property (readonly) NSMutableDictionary *property;
|
||||||
@property (assign) pthread_rwlock_t *rwlockProducer;
|
@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) doCoreEmuFrame;
|
||||||
- (void) handleEmuFrameProcessed;
|
- (void) handleEmuFrameProcessed;
|
||||||
|
|
||||||
|
@ -83,12 +96,6 @@
|
||||||
- (NSString *) audioOutputEngineString;
|
- (NSString *) audioOutputEngineString;
|
||||||
- (NSString *) spuInterpolationModeString;
|
- (NSString *) spuInterpolationModeString;
|
||||||
- (NSString *) spuSyncMethodString;
|
- (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
|
@end
|
||||||
|
|
||||||
|
@ -174,3 +181,14 @@
|
||||||
- (NSImage *) image;
|
- (NSImage *) image;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void* RunOutputThread(void *arg);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Roger Manuel
|
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -40,12 +40,11 @@
|
||||||
@implementation CocoaDSOutput
|
@implementation CocoaDSOutput
|
||||||
|
|
||||||
@synthesize property;
|
@synthesize property;
|
||||||
@synthesize mutexConsume;
|
|
||||||
@synthesize rwlockProducer;
|
@synthesize rwlockProducer;
|
||||||
|
|
||||||
- (id)init
|
- (id)init
|
||||||
{
|
{
|
||||||
self = [super initWithAutoreleaseInterval:0.1];
|
self = [super init];
|
||||||
if (self == nil)
|
if (self == nil)
|
||||||
{
|
{
|
||||||
return self;
|
return self;
|
||||||
|
@ -54,45 +53,107 @@
|
||||||
property = [[NSMutableDictionary alloc] init];
|
property = [[NSMutableDictionary alloc] init];
|
||||||
[property setValue:[NSDate date] forKey:@"outputTime"];
|
[property setValue:[NSDate date] forKey:@"outputTime"];
|
||||||
|
|
||||||
mutexConsume = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
|
||||||
pthread_mutex_init(mutexConsume, NULL);
|
|
||||||
|
|
||||||
rwlockProducer = NULL;
|
rwlockProducer = NULL;
|
||||||
|
|
||||||
|
_threadMessageID = MESSAGE_NONE;
|
||||||
|
_pthread = NULL;
|
||||||
|
|
||||||
|
_idleState = NO;
|
||||||
|
spinlockIdle = OS_SPINLOCK_INIT;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
// Force the thread to exit now so that we can safely release other resources.
|
[self exitThread];
|
||||||
[self forceThreadExit];
|
|
||||||
|
|
||||||
[property release];
|
[property release];
|
||||||
|
|
||||||
pthread_mutex_destroy(mutexConsume);
|
|
||||||
free(mutexConsume);
|
|
||||||
mutexConsume = NULL;
|
|
||||||
|
|
||||||
[super dealloc];
|
[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:
|
case MESSAGE_EMU_FRAME_PROCESSED:
|
||||||
[self handleEmuFrameProcessed];
|
[self handleEmuFrameProcessed];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
[super handlePortMessage:portMessage];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,6 +163,11 @@
|
||||||
// The base method does nothing.
|
// The base method does nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) doCoreEmuFrame
|
||||||
|
{
|
||||||
|
[self signalMessage:MESSAGE_EMU_FRAME_PROCESSED];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation CocoaDSSpeaker
|
@implementation CocoaDSSpeaker
|
||||||
|
@ -417,79 +483,6 @@
|
||||||
return theString;
|
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
|
@end
|
||||||
|
|
||||||
@implementation CocoaDSDisplay
|
@implementation CocoaDSDisplay
|
||||||
|
@ -511,6 +504,8 @@
|
||||||
_currentReceivedFrameIndex = 0;
|
_currentReceivedFrameIndex = 0;
|
||||||
_receivedFrameCount = 0;
|
_receivedFrameCount = 0;
|
||||||
|
|
||||||
|
[self createThread];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -519,18 +514,16 @@
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
- (void) handleSignalMessageID:(int32_t)messageID
|
||||||
{
|
{
|
||||||
NSInteger message = (NSInteger)[portMessage msgid];
|
switch (messageID)
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
{
|
||||||
case MESSAGE_RECEIVE_GPU_FRAME:
|
case MESSAGE_RECEIVE_GPU_FRAME:
|
||||||
[self handleReceiveGPUFrame];
|
[self handleReceiveGPUFrame];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
[super handlePortMessage:portMessage];
|
[super handleSignalMessageID:messageID];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1109,11 +1102,9 @@
|
||||||
return filterID;
|
return filterID;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
- (void) handleSignalMessageID:(int32_t)messageID
|
||||||
{
|
{
|
||||||
NSInteger message = (NSInteger)[portMessage msgid];
|
switch (messageID)
|
||||||
|
|
||||||
switch (message)
|
|
||||||
{
|
{
|
||||||
case MESSAGE_CHANGE_VIEW_PROPERTIES:
|
case MESSAGE_CHANGE_VIEW_PROPERTIES:
|
||||||
[self handleChangeViewProperties];
|
[self handleChangeViewProperties];
|
||||||
|
@ -1136,7 +1127,7 @@
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
[super handlePortMessage:portMessage];
|
[super handleSignalMessageID:messageID];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1256,3 +1247,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
static void* RunOutputThread(void *arg)
|
||||||
|
{
|
||||||
|
CocoaDSOutput *cdsDisplayOutput = (CocoaDSOutput *)arg;
|
||||||
|
[cdsDisplayOutput runMessageLoop];
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Roger Manuel
|
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
|
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
|
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;
|
+ (NSInteger) getIBActionSenderTag:(id)sender;
|
||||||
+ (BOOL) getIBActionSenderButtonStateBool:(id)sender;
|
+ (BOOL) getIBActionSenderButtonStateBool:(id)sender;
|
||||||
|
|
||||||
|
@ -54,39 +47,6 @@
|
||||||
|
|
||||||
@end
|
@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 <NSPortDelegate>
|
|
||||||
#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 <NSObject>
|
@protocol DirectoryURLDragDestTextFieldProtocol <NSObject>
|
||||||
|
|
||||||
@required
|
@required
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2011 Roger Manuel
|
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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -30,94 +30,6 @@
|
||||||
|
|
||||||
@implementation CocoaDSUtil
|
@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) getIBActionSenderTag:(id)sender
|
||||||
{
|
{
|
||||||
NSInteger senderTag = 0;
|
NSInteger senderTag = 0;
|
||||||
|
@ -253,129 +165,6 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain];
|
||||||
|
|
||||||
@end
|
@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
|
@implementation DirectoryURLDragDestTextField
|
||||||
|
|
||||||
- (id)initWithCoder:(NSCoder *)coder
|
- (id)initWithCoder:(NSCoder *)coder
|
||||||
|
|
|
@ -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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -698,7 +698,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
|
|
||||||
- (IBAction) copy:(id)sender
|
- (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
|
- (IBAction) changeHardwareMicGain:(id)sender
|
||||||
|
@ -1311,12 +1311,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
// Add the video thread to the output list.
|
// Add the video thread to the output list.
|
||||||
[emuControl addOutputToCore:newDisplayOutput];
|
[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.
|
// Setup default values per user preferences.
|
||||||
[self setupUserDefaults];
|
[self setupUserDefaults];
|
||||||
}
|
}
|
||||||
|
@ -1449,7 +1443,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
- (void)windowWillClose:(NSNotification *)notification
|
- (void)windowWillClose:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
[emuControl removeOutputFromCore:[[self view] cdsVideoOutput]];
|
[emuControl removeOutputFromCore:[[self view] cdsVideoOutput]];
|
||||||
[[[self view] cdsVideoOutput] forceThreadExit];
|
|
||||||
|
|
||||||
[[emuControl windowList] removeObject:self];
|
[[emuControl windowList] removeObject:self];
|
||||||
|
|
||||||
|
@ -1946,7 +1939,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
- (void) setDisplayMainVideoSource:(NSInteger)displaySourceID
|
- (void) setDisplayMainVideoSource:(NSInteger)displaySourceID
|
||||||
{
|
{
|
||||||
[[self cdsVideoOutput] setDisplayMainVideoSource:displaySourceID];
|
[[self cdsVideoOutput] setDisplayMainVideoSource:displaySourceID];
|
||||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW];
|
[[self cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger) displayMainVideoSource
|
- (NSInteger) displayMainVideoSource
|
||||||
|
@ -1957,7 +1950,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
- (void) setDisplayTouchVideoSource:(NSInteger)displaySourceID
|
- (void) setDisplayTouchVideoSource:(NSInteger)displaySourceID
|
||||||
{
|
{
|
||||||
[[self cdsVideoOutput] setDisplayTouchVideoSource:displaySourceID];
|
[[self cdsVideoOutput] setDisplayTouchVideoSource:displaySourceID];
|
||||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW];
|
[[self cdsVideoOutput] signalMessage:MESSAGE_RELOAD_REPROCESS_REDRAW];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger) displayTouchVideoSource
|
- (NSInteger) displayTouchVideoSource
|
||||||
|
@ -1997,7 +1990,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
[macSharedData decrementViewsUsingDirectToCPUFiltering];
|
[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<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW];
|
[[self cdsVideoOutput] signalMessage:MESSAGE_REPROCESS_AND_REDRAW];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) sourceDeposterize
|
- (BOOL) sourceDeposterize
|
||||||
|
@ -2040,7 +2033,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
- (void) setOutputFilter:(NSInteger)filterID
|
- (void) setOutputFilter:(NSInteger)filterID
|
||||||
{
|
{
|
||||||
[[self cdsVideoOutput] setOutputFilter:filterID];
|
[[self cdsVideoOutput] setOutputFilter:filterID];
|
||||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REDRAW_VIEW];
|
[[self cdsVideoOutput] signalMessage:MESSAGE_REDRAW_VIEW];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger) outputFilter
|
- (NSInteger) outputFilter
|
||||||
|
@ -2071,7 +2064,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW];
|
[[self cdsVideoOutput] signalMessage:MESSAGE_REPROCESS_AND_REDRAW];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger) pixelScaler
|
- (NSInteger) pixelScaler
|
||||||
|
|
|
@ -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
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
|
@ -1464,7 +1464,7 @@
|
||||||
|
|
||||||
for (DisplayWindowController *windowController in windowList)
|
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];
|
[self setStatusText:NSSTRING_STATUS_EMULATOR_RESET];
|
||||||
|
@ -1762,7 +1762,7 @@
|
||||||
|
|
||||||
for (DisplayWindowController *windowController in windowList)
|
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];
|
[self setStatusText:NSSTRING_STATUS_ROM_LOADED];
|
||||||
|
@ -1845,7 +1845,7 @@
|
||||||
[[cdsCore cdsGPU] clearWithColor:0x8000];
|
[[cdsCore cdsGPU] clearWithColor:0x8000];
|
||||||
for (DisplayWindowController *windowController in windowList)
|
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];
|
[self setStatusText:NSSTRING_STATUS_ROM_UNLOADED];
|
||||||
|
|
|
@ -505,6 +505,7 @@ void MacOGLDisplayView::SetViewNeedsFlush()
|
||||||
if (this->GetRenderToCALayer())
|
if (this->GetRenderToCALayer())
|
||||||
{
|
{
|
||||||
[this->_caLayer setNeedsDisplay];
|
[this->_caLayer setNeedsDisplay];
|
||||||
|
[CATransaction flush];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue