Cocoa Port: Reduce threading overhead for framebuffer fetches and SPU_Emulate_user().

- Framebuffer fetches no longer run on a CocoaDSThread, but instead uses a pthread directly. This can be done since framebuffer fetching only serves one function and always receives the same execution message, making a full CocoaDSThread a waste.
- SPU_Emulate_user() is no longer called on a separate thread, and instead is called in the emulation thread directly. For the typical SPU use case (SPU Sound Synchronization w/ Advanced SPU Logic), SPU_Emulator_user() becomes negligible, and so the threading overhead becomes unnecessary. In the use case where Dual SPU Synch/Asynch is used, Advanced SPU Logic is almost always disabled with it, and so the penalty of calling SPU_Emulator_user() on the emulation thread will be more than compensated by the performance increase of turning off Advanced SPU Logic.
- Also do some code cleanup/refactoring here and there.
This commit is contained in:
rogerman 2017-09-16 18:08:07 -07:00
parent 8f2c85fe86
commit fda9fc2a89
9 changed files with 260 additions and 231 deletions

View File

@ -39,7 +39,7 @@ class GPUEventHandlerOSX;
typedef std::map<CGDirectDisplayID, CVDisplayLinkRef> DisplayLinksActiveMap;
typedef std::map<CGDirectDisplayID, int64_t> DisplayLinkFlushTimeLimitMap;
@interface MacClientSharedObject : CocoaDSThread
@interface MacClientSharedObject : NSObject
{
GPUClientFetchObject *GPUFetchObject;
pthread_rwlock_t *_rwlockFramebuffer[2];
@ -50,6 +50,13 @@ typedef std::map<CGDirectDisplayID, int64_t> DisplayLinkFlushTimeLimitMap;
DisplayLinksActiveMap _displayLinksActiveList;
DisplayLinkFlushTimeLimitMap _displayLinkFlushTimeList;
OSSpinLock spinlockFetchSignal;
BOOL _isFetchSignalled;
uint8_t _fetchIndex;
pthread_t _threadFetch;
pthread_cond_t _condSignalFetch;
pthread_mutex_t _mutexFetchExecute;
}
@property (assign, nonatomic) GPUClientFetchObject *GPUFetchObject;
@ -69,6 +76,9 @@ typedef std::map<CGDirectDisplayID, int64_t> DisplayLinkFlushTimeLimitMap;
- (void) displayLinkStartUsingID:(CGDirectDisplayID)displayID;
- (void) displayLinkListUpdate;
- (void) signalFetchAtIndex:(uint8_t)index;
- (void) runFetchLoop;
@end
@interface CocoaDSGPU : NSObject
@ -131,6 +141,8 @@ extern "C"
{
#endif
static void* RunFetchThread(void *arg);
CVReturn MacDisplayLinkCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,

View File

@ -887,6 +887,13 @@ public:
_displayLinkFlushTimeList.clear();
[self displayLinkListUpdate];
spinlockFetchSignal = OS_SPINLOCK_INIT;
_isFetchSignalled = NO;
_fetchIndex = 0;
pthread_cond_init(&_condSignalFetch, NULL);
pthread_create(&_threadFetch, NULL, &RunFetchThread, self);
pthread_mutex_init(&_mutexFetchExecute, NULL);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(respondToScreenChange:)
name:@"NSApplicationDidChangeScreenParametersNotification"
@ -897,6 +904,13 @@ public:
- (void)dealloc
{
pthread_cancel(_threadFetch);
pthread_join(_threadFetch, NULL);
_threadFetch = NULL;
pthread_cond_destroy(&_condSignalFetch);
pthread_mutex_destroy(&_mutexFetchExecute);
pthread_mutex_lock(&_mutexFlushVideo);
for (DisplayLinksActiveMap::iterator it = _displayLinksActiveList.begin(); it != _displayLinksActiveList.end(); ++it)
@ -914,6 +928,7 @@ public:
}
pthread_mutex_unlock(&_mutexFlushVideo);
pthread_mutex_destroy(&_mutexFlushVideo);
pthread_mutex_t *currentMutex = _mutexOutputList;
@ -931,28 +946,10 @@ public:
pthread_rwlock_destroy(_rwlockFramebuffer[0]);
pthread_rwlock_destroy(_rwlockFramebuffer[1]);
pthread_mutex_destroy(&_mutexFlushVideo);
[super dealloc];
}
- (void)handlePortMessage:(NSPortMessage *)portMessage
{
NSInteger message = (NSInteger)[portMessage msgid];
NSArray *messageComponents = [portMessage components];
switch (message)
{
case MESSAGE_FETCH_AND_PUSH_VIDEO:
[self handleFetchFromBufferIndexAndPushVideo:[messageComponents objectAtIndex:0]];
break;
default:
[super handlePortMessage:portMessage];
break;
}
}
- (void) handleFetchFromBufferIndexAndPushVideo:(NSData *)indexData
{
const NSInteger index = *(NSInteger *)[indexData bytes];
@ -1013,7 +1010,7 @@ public:
for (CocoaDSOutput *cdsOutput in _cdsOutputList)
{
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]])
{
[CocoaDSUtil messageSendOneWay:[cdsOutput receivePort] msgID:MESSAGE_RECEIVE_GPU_FRAME];
}
@ -1036,9 +1033,9 @@ public:
for (CocoaDSOutput *cdsOutput in _cdsOutputList)
{
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]])
{
ClientDisplay3DView *cdv = [(CocoaDSDisplay *)cdsOutput clientDisplayView];
ClientDisplay3DView *cdv = [(CocoaDSDisplayVideo *)cdsOutput clientDisplayView];
cdv->FinishFrameAtIndex(bufferIndex);
}
}
@ -1189,6 +1186,36 @@ public:
pthread_mutex_unlock(&_mutexFlushVideo);
}
- (void) signalFetchAtIndex:(uint8_t)index
{
pthread_mutex_lock(&_mutexFetchExecute);
_fetchIndex = index;
_isFetchSignalled = YES;
pthread_cond_signal(&_condSignalFetch);
pthread_mutex_unlock(&_mutexFetchExecute);
}
- (void) runFetchLoop
{
do
{
pthread_mutex_lock(&_mutexFetchExecute);
while (!_isFetchSignalled)
{
pthread_cond_wait(&_condSignalFetch, &_mutexFetchExecute);
}
_isFetchSignalled = NO;
GPUFetchObject->FetchFromBufferIndex(_fetchIndex);
[self pushVideoDataToAllDisplayViews];
pthread_mutex_unlock(&_mutexFetchExecute);
} while(true);
}
- (void) respondToScreenChange:(NSNotification *)aNotification
{
[self displayLinkListUpdate];
@ -1256,7 +1283,7 @@ void GPUEventHandlerOSX::DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &
#if !defined(PORT_VERSION_OPENEMU)
if (!isFrameSkipped)
{
[CocoaDSUtil messageSendOneWayWithInteger:[sharedViewObject receivePort] msgID:MESSAGE_FETCH_AND_PUSH_VIDEO integerValue:latestDisplayInfo.bufferIndex];
[sharedViewObject signalFetchAtIndex:latestDisplayInfo.bufferIndex];
}
#endif
}
@ -1317,6 +1344,14 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
CGLPBufferObj OSXOpenGLRendererPBuffer = NULL;
#pragma GCC diagnostic pop
static void* RunFetchThread(void *arg)
{
MacClientSharedObject *sharedData = (MacClientSharedObject *)arg;
[sharedData runFetchLoop];
return NULL;
}
CVReturn MacDisplayLinkCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,

View File

@ -35,6 +35,7 @@
#include "../../gdbstub.h"
#include "../../slot1.h"
#include "../../slot2.h"
#include "../../SPU.h"
#undef BOOL
// Need to include assert.h this way so that GDB stub will work
@ -1031,6 +1032,7 @@ static void* RunCoreThread(void *arg)
// Execute the frame and increment the frame counter.
pthread_rwlock_wrlock(&param->rwlockCoreExecute);
NDS_exec<false>();
SPU_Emulate_user();
execControl->FetchOutputPostNDSExec();
pthread_rwlock_unlock(&param->rwlockCoreExecute);
@ -1069,7 +1071,7 @@ static void* RunCoreThread(void *arg)
[(CocoaDSDisplay *)cdsOutput setNDSFrameInfo:ndsFrameInfo];
}
if ( ![cdsOutput isKindOfClass:[CocoaDSDisplay class]] || (framesToSkip == 0) )
if ( ![cdsOutput isKindOfClass:[CocoaDSSpeaker class]] && (![cdsOutput isKindOfClass:[CocoaDSDisplay class]] || (framesToSkip == 0)) )
{
[cdsOutput doCoreEmuFrame];
}

View File

@ -96,10 +96,6 @@
@interface CocoaDSDisplay : CocoaDSOutput
{
ClientDisplay3DView *_cdv;
ClientDisplayViewProperties _intermediateViewProps;
NSSize displaySize;
uint32_t _receivedFrameIndex;
uint32_t _currentReceivedFrameIndex;
uint32_t _receivedFrameCount;
@ -108,28 +104,21 @@
OSSpinLock spinlockReceivedFrameIndex;
OSSpinLock spinlockNDSFrameInfo;
OSSpinLock spinlockViewProperties;
}
@property (assign, nonatomic) ClientDisplay3DView *clientDisplayView;
@property (readonly) NSSize displaySize;
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps;
- (void) handleReceiveGPUFrame;
- (void) handleChangeViewProperties;
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData;
- (void) handleCopyToPasteboard;
- (void) takeFrameCount;
- (void) setNDSFrameInfo:(const NDSFrameInfo &)ndsFrameInfo;
- (NSImage *) image;
- (NSBitmapImageRep *) bitmapImageRep;
@end
@interface CocoaDSDisplayVideo : CocoaDSDisplay
{
ClientDisplay3DView *_cdv;
ClientDisplayViewProperties _intermediateViewProps;
OSSpinLock spinlockViewProperties;
OSSpinLock spinlockIsHUDVisible;
OSSpinLock spinlockUseVerticalSync;
OSSpinLock spinlockVideoFiltersPreferGPU;
@ -140,6 +129,7 @@
OSSpinLock spinlockDisplayID;
}
@property (assign, nonatomic) ClientDisplay3DView *clientDisplayView;
@property (readonly, nonatomic) BOOL canFilterOnGPU;
@property (readonly, nonatomic) BOOL willFilterOnGPU;
@property (assign) BOOL isHUDVisible;
@ -168,12 +158,19 @@
@property (assign) NSInteger outputFilter;
@property (assign) NSInteger pixelScaler;
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps;
- (void) handleChangeViewProperties;
- (void) handleReceiveGPUFrame;
- (void) handleReloadReprocessRedraw;
- (void) handleReprocessRedraw;
- (void) handleRedraw;
- (void) handleCopyToPasteboard;
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData;
- (void) setScaleFactor:(float)theScaleFactor;
- (void) hudUpdate;
- (NSImage *) image;
- (NSBitmapImageRep *) bitmapImageRep;
@end

View File

@ -501,9 +501,6 @@
@implementation CocoaDSDisplay
@dynamic clientDisplayView;
@dynamic displaySize;
- (id)init
{
self = [super init];
@ -514,9 +511,7 @@
spinlockReceivedFrameIndex = OS_SPINLOCK_INIT;
spinlockNDSFrameInfo = OS_SPINLOCK_INIT;
spinlockViewProperties = OS_SPINLOCK_INIT;
_cdv = NULL;
_ndsFrameInfo.clear();
_receivedFrameIndex = 0;
@ -531,38 +526,9 @@
[super dealloc];
}
- (void) setClientDisplayView:(ClientDisplay3DView *)clientDisplayView
{
_cdv = clientDisplayView;
}
- (ClientDisplay3DView *) clientDisplayView
{
return _cdv;
}
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps
{
OSSpinLockLock(&spinlockViewProperties);
_intermediateViewProps = viewProps;
OSSpinLockUnlock(&spinlockViewProperties);
[self handleChangeViewProperties];
}
- (NSSize) displaySize
{
pthread_rwlock_rdlock(self.rwlockProducer);
NSSize size = NSMakeSize((CGFloat)GPU->GetCustomFramebufferWidth(), (_cdv->GetMode() == ClientDisplayMode_Dual) ? (CGFloat)(GPU->GetCustomFramebufferHeight() * 2): (CGFloat)GPU->GetCustomFramebufferHeight());
pthread_rwlock_unlock(self.rwlockProducer);
return size;
}
- (void)handlePortMessage:(NSPortMessage *)portMessage
{
NSInteger message = (NSInteger)[portMessage msgid];
NSArray *messageComponents = [portMessage components];
switch (message)
{
@ -570,18 +536,6 @@
[self handleReceiveGPUFrame];
break;
case MESSAGE_CHANGE_VIEW_PROPERTIES:
[self handleChangeViewProperties];
break;
case MESSAGE_REQUEST_SCREENSHOT:
[self handleRequestScreenshot:[messageComponents objectAtIndex:0] fileTypeData:[messageComponents objectAtIndex:1]];
break;
case MESSAGE_COPY_TO_PASTEBOARD:
[self handleCopyToPasteboard];
break;
default:
[super handlePortMessage:portMessage];
break;
@ -595,46 +549,6 @@
OSSpinLockUnlock(&spinlockReceivedFrameIndex);
}
- (void) handleChangeViewProperties
{
OSSpinLockLock(&spinlockViewProperties);
_cdv->CommitViewProperties(_intermediateViewProps);
OSSpinLockUnlock(&spinlockViewProperties);
_cdv->SetupViewProperties();
}
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData
{
NSString *fileURLString = [[NSString alloc] initWithData:fileURLStringData encoding:NSUTF8StringEncoding];
NSURL *fileURL = [NSURL URLWithString:fileURLString];
NSBitmapImageFileType fileType = *(NSBitmapImageFileType *)[fileTypeData bytes];
NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
fileURL, @"fileURL",
[NSNumber numberWithInteger:(NSInteger)fileType], @"fileType",
[self image], @"screenshotImage",
nil];
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"org.desmume.DeSmuME.requestScreenshotDidFinish" object:self userInfo:userInfo];
[userInfo release];
[fileURLString release];
}
- (void) handleCopyToPasteboard
{
NSImage *screenshot = [self image];
if (screenshot == nil)
{
return;
}
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard declareTypes:[NSArray arrayWithObjects:NSTIFFPboardType, nil] owner:self];
[pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType];
}
- (void) takeFrameCount
{
OSSpinLockLock(&spinlockReceivedFrameIndex);
@ -650,88 +564,11 @@
OSSpinLockUnlock(&spinlockNDSFrameInfo);
}
- (NSImage *) image
{
NSImage *newImage = [[NSImage alloc] initWithSize:[self displaySize]];
if (newImage == nil)
{
return newImage;
}
// Render the frame in an NSBitmapImageRep
NSBitmapImageRep *newImageRep = [self bitmapImageRep];
if (newImageRep == nil)
{
[newImage release];
newImage = nil;
return newImage;
}
// Attach the rendered frame to the NSImageRep
[newImage addRepresentation:newImageRep];
return [newImage autorelease];
}
- (NSBitmapImageRep *) bitmapImageRep
{
GPUClientFetchObject &fetchObjMutable = (GPUClientFetchObject &)_cdv->GetFetchObject();
NDSDisplayInfo &displayInfoMutable = (NDSDisplayInfo &)fetchObjMutable.GetFetchDisplayInfoForBufferIndex(fetchObjMutable.GetLastFetchIndex());
NSUInteger w = (NSUInteger)displayInfoMutable.customWidth;
NSUInteger h = (_cdv->GetMode() == ClientDisplayMode_Dual) ? (NSUInteger)(displayInfoMutable.customHeight * 2) : (NSUInteger)displayInfoMutable.customHeight;
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:w
pixelsHigh:h
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:w * 4
bitsPerPixel:32];
if(imageRep == nil)
{
return imageRep;
}
void *displayBuffer = displayInfoMutable.masterCustomBuffer;
uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData];
pthread_rwlock_wrlock(self.rwlockProducer);
GPU->PostprocessDisplay(NDSDisplayID_Main, displayInfoMutable);
GPU->PostprocessDisplay(NDSDisplayID_Touch, displayInfoMutable);
GPU->ResolveDisplayToCustomFramebuffer(NDSDisplayID_Main, displayInfoMutable);
GPU->ResolveDisplayToCustomFramebuffer(NDSDisplayID_Touch, displayInfoMutable);
if (displayInfoMutable.pixelBytes == 2)
{
ColorspaceConvertBuffer555To8888Opaque<false, true>((u16 *)displayBuffer, bitmapData, (w * h));
}
else if (displayInfoMutable.pixelBytes == 4)
{
memcpy(bitmapData, displayBuffer, w * h * sizeof(uint32_t));
}
pthread_rwlock_unlock(self.rwlockProducer);
#ifdef MSB_FIRST
for (size_t i = 0; i < w * h; i++)
{
bitmapData[i] = LE_TO_LOCAL_32(bitmapData[i]);
}
#endif
return [imageRep autorelease];
}
@end
@implementation CocoaDSDisplayVideo
@dynamic clientDisplayView;
@dynamic canFilterOnGPU;
@dynamic willFilterOnGPU;
@dynamic isHUDVisible;
@ -768,6 +605,9 @@
return self;
}
_cdv = NULL;
spinlockViewProperties = OS_SPINLOCK_INIT;
spinlockIsHUDVisible = OS_SPINLOCK_INIT;
spinlockUseVerticalSync = OS_SPINLOCK_INIT;
spinlockVideoFiltersPreferGPU = OS_SPINLOCK_INIT;
@ -785,6 +625,25 @@
[super dealloc];
}
- (void) setClientDisplayView:(ClientDisplay3DView *)clientDisplayView
{
_cdv = clientDisplayView;
}
- (ClientDisplay3DView *) clientDisplayView
{
return _cdv;
}
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps
{
OSSpinLockLock(&spinlockViewProperties);
_intermediateViewProps = viewProps;
OSSpinLockUnlock(&spinlockViewProperties);
[self handleChangeViewProperties];
}
- (BOOL) canFilterOnGPU
{
return (_cdv->CanFilterOnGPU()) ? YES : NO;
@ -1198,9 +1057,14 @@
- (void)handlePortMessage:(NSPortMessage *)portMessage
{
NSInteger message = (NSInteger)[portMessage msgid];
NSArray *messageComponents = [portMessage components];
switch (message)
{
case MESSAGE_CHANGE_VIEW_PROPERTIES:
[self handleChangeViewProperties];
break;
case MESSAGE_RELOAD_REPROCESS_REDRAW:
[self handleReloadReprocessRedraw];
break;
@ -1213,6 +1077,14 @@
[self handleRedraw];
break;
case MESSAGE_COPY_TO_PASTEBOARD:
[self handleCopyToPasteboard];
break;
case MESSAGE_REQUEST_SCREENSHOT:
[self handleRequestScreenshot:[messageComponents objectAtIndex:0] fileTypeData:[messageComponents objectAtIndex:1]];
break;
default:
[super handlePortMessage:portMessage];
break;
@ -1226,6 +1098,15 @@
_cdv->HandleEmulatorFrameEndEvent();
}
- (void) handleChangeViewProperties
{
OSSpinLockLock(&spinlockViewProperties);
_cdv->CommitViewProperties(_intermediateViewProps);
OSSpinLockUnlock(&spinlockViewProperties);
_cdv->SetupViewProperties();
}
- (void) handleReceiveGPUFrame
{
[super handleReceiveGPUFrame];
@ -1257,6 +1138,37 @@
_cdv->UpdateView();
}
- (void) handleCopyToPasteboard
{
NSImage *screenshot = [self image];
if (screenshot == nil)
{
return;
}
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
[pboard declareTypes:[NSArray arrayWithObjects:NSTIFFPboardType, nil] owner:self];
[pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType];
}
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData
{
NSString *fileURLString = [[NSString alloc] initWithData:fileURLStringData encoding:NSUTF8StringEncoding];
NSURL *fileURL = [NSURL URLWithString:fileURLString];
NSBitmapImageFileType fileType = *(NSBitmapImageFileType *)[fileTypeData bytes];
NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
fileURL, @"fileURL",
[NSNumber numberWithInteger:(NSInteger)fileType], @"fileType",
[self image], @"screenshotImage",
nil];
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"org.desmume.DeSmuME.requestScreenshotDidFinish" object:self userInfo:userInfo];
[userInfo release];
[fileURLString release];
}
- (void) setScaleFactor:(float)theScaleFactor
{
OSSpinLockLock(&spinlockIsHUDVisible);
@ -1276,4 +1188,86 @@
OSSpinLockUnlock(&spinlockNDSFrameInfo);
}
- (NSImage *) image
{
pthread_rwlock_rdlock(self.rwlockProducer);
NSSize displaySize = NSMakeSize((CGFloat)GPU->GetCustomFramebufferWidth(), (_cdv->GetMode() == ClientDisplayMode_Dual) ? (CGFloat)(GPU->GetCustomFramebufferHeight() * 2): (CGFloat)GPU->GetCustomFramebufferHeight());
pthread_rwlock_unlock(self.rwlockProducer);
NSImage *newImage = [[NSImage alloc] initWithSize:displaySize];
if (newImage == nil)
{
return newImage;
}
// Render the frame in an NSBitmapImageRep
NSBitmapImageRep *newImageRep = [self bitmapImageRep];
if (newImageRep == nil)
{
[newImage release];
newImage = nil;
return newImage;
}
// Attach the rendered frame to the NSImageRep
[newImage addRepresentation:newImageRep];
return [newImage autorelease];
}
- (NSBitmapImageRep *) bitmapImageRep
{
GPUClientFetchObject &fetchObjMutable = (GPUClientFetchObject &)_cdv->GetFetchObject();
NDSDisplayInfo &displayInfoMutable = (NDSDisplayInfo &)fetchObjMutable.GetFetchDisplayInfoForBufferIndex(fetchObjMutable.GetLastFetchIndex());
NSUInteger w = (NSUInteger)displayInfoMutable.customWidth;
NSUInteger h = (_cdv->GetMode() == ClientDisplayMode_Dual) ? (NSUInteger)(displayInfoMutable.customHeight * 2) : (NSUInteger)displayInfoMutable.customHeight;
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:w
pixelsHigh:h
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:w * 4
bitsPerPixel:32];
if (imageRep == nil)
{
return imageRep;
}
void *displayBuffer = displayInfoMutable.masterCustomBuffer;
uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData];
pthread_rwlock_wrlock(self.rwlockProducer);
GPU->PostprocessDisplay(NDSDisplayID_Main, displayInfoMutable);
GPU->PostprocessDisplay(NDSDisplayID_Touch, displayInfoMutable);
GPU->ResolveDisplayToCustomFramebuffer(NDSDisplayID_Main, displayInfoMutable);
GPU->ResolveDisplayToCustomFramebuffer(NDSDisplayID_Touch, displayInfoMutable);
if (displayInfoMutable.pixelBytes == 2)
{
ColorspaceConvertBuffer555To8888Opaque<false, true>((u16 *)displayBuffer, bitmapData, (w * h));
}
else if (displayInfoMutable.pixelBytes == 4)
{
memcpy(bitmapData, displayBuffer, w * h * sizeof(uint32_t));
}
pthread_rwlock_unlock(self.rwlockProducer);
#ifdef MSB_FIRST
for (size_t i = 0; i < w * h; i++)
{
bitmapData[i] = LE_TO_LOCAL_32(bitmapData[i]);
}
#endif
return [imageRep autorelease];
}
@end

View File

@ -1323,7 +1323,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
// Set up the video output thread.
CocoaDSDisplayVideo *newDisplayOutput = [[[CocoaDSDisplayVideo alloc] init] autorelease];
[newDisplayOutput setClientDisplayView:[view clientDisplay3DView]];
[newDisplayOutput setClientDisplayView:[newView clientDisplay3DView]];
ClientDisplayView *cdv = [newDisplayOutput clientDisplayView];
NSString *fontPath = [[NSBundle mainBundle] pathForResource:@"SourceSansPro-Bold" ofType:@"otf"];

View File

@ -810,32 +810,32 @@
{
const float vol = [self currentVolumeValue];
[self setCurrentVolumeValue:vol];
[CocoaDSUtil messageSendOneWayWithFloat:[cdsSpeaker receivePort] msgID:MESSAGE_SET_VOLUME floatValue:vol];
[[self cdsSpeaker] setVolume:vol];
}
- (IBAction) changeAudioEngine:(id)sender
{
[CocoaDSUtil messageSendOneWayWithInteger:[cdsSpeaker receivePort] msgID:MESSAGE_SET_AUDIO_PROCESS_METHOD integerValue:[CocoaDSUtil getIBActionSenderTag:sender]];
[[self cdsSpeaker] setAudioOutputEngine:[CocoaDSUtil getIBActionSenderTag:sender]];
}
- (IBAction) changeSpuAdvancedLogic:(id)sender
{
[CocoaDSUtil messageSendOneWayWithBool:[cdsSpeaker receivePort] msgID:MESSAGE_SET_SPU_ADVANCED_LOGIC boolValue:[CocoaDSUtil getIBActionSenderButtonStateBool:sender]];
[[self cdsSpeaker] setSpuAdvancedLogic:[CocoaDSUtil getIBActionSenderButtonStateBool:sender]];
}
- (IBAction) changeSpuInterpolationMode:(id)sender
{
[CocoaDSUtil messageSendOneWayWithInteger:[cdsSpeaker receivePort] msgID:MESSAGE_SET_SPU_INTERPOLATION_MODE integerValue:[CocoaDSUtil getIBActionSenderTag:sender]];
[[self cdsSpeaker] setSpuInterpolationMode:[CocoaDSUtil getIBActionSenderTag:sender]];
}
- (IBAction) changeSpuSyncMode:(id)sender
{
[CocoaDSUtil messageSendOneWayWithInteger:[cdsSpeaker receivePort] msgID:MESSAGE_SET_SPU_SYNC_MODE integerValue:[CocoaDSUtil getIBActionSenderTag:sender]];
[[self cdsSpeaker] setSpuSyncMode:[CocoaDSUtil getIBActionSenderTag:sender]];
}
- (IBAction) changeSpuSyncMethod:(id)sender
{
[CocoaDSUtil messageSendOneWayWithInteger:[cdsSpeaker receivePort] msgID:MESSAGE_SET_SPU_SYNC_METHOD integerValue:[CocoaDSUtil getIBActionSenderTag:sender]];
[[self cdsSpeaker] setSpuSyncMethod:[CocoaDSUtil getIBActionSenderTag:sender]];
}
- (IBAction) toggleAllDisplays:(id)sender
@ -1533,7 +1533,7 @@
}
[self setCurrentVolumeValue:vol];
[CocoaDSUtil messageSendOneWayWithFloat:[cdsSpeaker receivePort] msgID:MESSAGE_SET_VOLUME floatValue:vol];
[[self cdsSpeaker] setVolume:vol];
}
- (void) cmdToggleGPUState:(NSValue *)cmdAttrValue

View File

@ -1127,7 +1127,7 @@
{
const VideoFilterAttributes vfAttr = VideoFilter::GetAttributesByID(filterID);
id<MTLCommandBuffer> cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
id<MTLCommandBuffer> cb = [self newCommandBuffer];
id<MTLBlitCommandEncoder> dummyEncoder = [cb blitCommandEncoder];
[dummyEncoder endEncoding];
[cb commit];
@ -1145,7 +1145,7 @@
options:MTLResourceStorageModeManaged
deallocator:nil]];
cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
cb = [self newCommandBuffer];
dummyEncoder = [cb blitCommandEncoder];
[dummyEncoder endEncoding];
[cb commit];
@ -1285,7 +1285,7 @@
VideoFilter *vfMain = _cdv->GetPixelScalerObject(NDSDisplayID_Main);
VideoFilter *vfTouch = _cdv->GetPixelScalerObject(NDSDisplayID_Touch);
id<MTLCommandBuffer> cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
id<MTLCommandBuffer> cb = [self newCommandBuffer];
id<MTLComputeCommandEncoder> cce = [cb computeCommandEncoder];
// Run the video source filters and the pixel scalers
@ -1591,7 +1591,7 @@
// Now that everything is set up, go ahead and draw everything.
id<CAMetalDrawable> layerDrawable = [self nextDrawable];
[colorAttachment0Desc setTexture:[layerDrawable texture]];
id<MTLCommandBuffer> cb = [[sharedData commandQueue] commandBufferWithUnretainedReferences];
id<MTLCommandBuffer> cb = [self newCommandBuffer];
id<MTLRenderCommandEncoder> ce = [cb renderCommandEncoderWithDescriptor:_outputRenderPassDesc];
if (_needEncodeViewport)
@ -1804,8 +1804,11 @@ void MacMetalFetchObject::FetchFromBufferIndex(const u8 index)
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)this->_clientData;
this->_useDirectToCPUFilterPipeline = ([sharedViewObject numberViewsUsingDirectToCPUFiltering] > 0);
@autoreleasepool
{
[(MetalDisplayViewSharedData *)this->_clientData fetchFromBufferIndex:index];
}
}
void MacMetalFetchObject::_FetchNativeDisplayByID(const NDSDisplayID displayID, const u8 bufferIndex)
{

View File

@ -183,13 +183,6 @@
// Init the DS emulation core.
CocoaDSCore *newCore = [[[CocoaDSCore alloc] init] autorelease];
MacClientSharedObject *sharedViewObject = [[newCore cdsGPU] sharedData];
[NSThread detachNewThreadSelector:@selector(runThread:) toTarget:sharedViewObject withObject:nil];
while ([sharedViewObject thread] == nil)
{
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
// Init the DS controller.
[[newCore cdsController] setDelegate:emuControl];
@ -205,13 +198,6 @@
[slot2WindowDelegate setHidManager:[inputManager hidManager]];
[slot2WindowDelegate setAutoSelectedDeviceText:[[slot2WindowDelegate deviceManager] autoSelectedDeviceName]];
// Start up the threads for our outputs.
[NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newSpeaker withObject:nil];
while ([newSpeaker thread] == nil)
{
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
// Set up all the object controllers.
[cdsCoreController setContent:newCore];
[romInfoPanelController setContent:[CocoaDSRom romNotLoadedBindings]];