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:
rogerman 2018-02-03 11:31:41 -08:00
parent f9c32c9e79
commit 01c508f93a
9 changed files with 146 additions and 393 deletions

View File

@ -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];
}
}

View File

@ -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
};

View File

@ -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

View File

@ -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;
}

View File

@ -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 <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>
@required

View File

@ -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

View File

@ -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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _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<NSScreen *, DisplayWindowController *> _screenMap; //
}
}
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW];
[[self cdsVideoOutput] signalMessage:MESSAGE_REPROCESS_AND_REDRAW];
}
- (NSInteger) pixelScaler

View File

@ -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];

View File

@ -505,6 +505,7 @@ void MacOGLDisplayView::SetViewNeedsFlush()
if (this->GetRenderToCALayer())
{
[this->_caLayer setNeedsDisplay];
[CATransaction flush];
}
else
{