Cocoa Port: Huge refactor to ClientDisplayView, now supporting the use of shared fetch objects and shared client objects in order to lower memory usage and CPU/GPU usage when many display views are running at the same time.
- OpenGL display views now use a shared fetch object to fetch the emulated GPU framebuffers and store them in shared textures within a shared context. In conjunction with the new double-buffering support from the last commit, this eliminates the copying between the framebuffers and each display view. - OpenGL display views now use shared HQnx LUT textures, rather than having to initialize and maintain a copy of the LUT textures for each display view. - OpenGL display views no longer perform any rendering while their associated NSView is hidden, improving the performance of creating new display views. - OpenGL display views can now DMA directly from pinned-memory both custom-sized framebuffers and CPU-pixel-scaled native-sized framebuffers at the same time.
This commit is contained in:
parent
08b8a1a62c
commit
aff2d07146
|
@ -21,6 +21,8 @@
|
|||
|
||||
ClientDisplayView::ClientDisplayView()
|
||||
{
|
||||
_fetchObject = NULL;
|
||||
|
||||
ClientDisplayViewProperties defaultProperty;
|
||||
defaultProperty.normalWidth = GPU_FRAMEBUFFER_NATIVE_WIDTH;
|
||||
defaultProperty.normalHeight = GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2.0;
|
||||
|
@ -80,6 +82,7 @@ void ClientDisplayView::__InstanceInit(const ClientDisplayViewProperties &props)
|
|||
memset(&_emuFrameInfo, 0, sizeof(_emuFrameInfo));
|
||||
_hudString = "\x01"; // Char value 0x01 will represent the "text box" character, which will always be first in the string.
|
||||
_hudNeedsUpdate = true;
|
||||
_allowViewUpdates = true;
|
||||
|
||||
FT_Error error = FT_Init_FreeType(&_ftLibrary);
|
||||
if (error)
|
||||
|
@ -481,14 +484,24 @@ void ClientDisplayView::ClearHUDNeedsUpdate()
|
|||
}
|
||||
|
||||
// NDS GPU Interface
|
||||
void ClientDisplayView::_FetchNativeDisplayByID(const NDSDisplayID displayID)
|
||||
const GPUClientFetchObject& ClientDisplayView::GetFetchObject() const
|
||||
{
|
||||
// Do nothing. This is implementation dependent.
|
||||
return *this->_fetchObject;
|
||||
}
|
||||
|
||||
void ClientDisplayView::_FetchCustomDisplayByID(const NDSDisplayID displayID)
|
||||
void ClientDisplayView::SetFetchObject(GPUClientFetchObject *fetchObject)
|
||||
{
|
||||
// Do nothing. This is implementation dependent.
|
||||
this->_fetchObject = fetchObject;
|
||||
}
|
||||
|
||||
bool ClientDisplayView::GetAllowViewUpdates() const
|
||||
{
|
||||
return this->_allowViewUpdates;
|
||||
}
|
||||
|
||||
void ClientDisplayView::SetAllowViewUpdates(const bool allowUpdates)
|
||||
{
|
||||
this->_allowViewUpdates = allowUpdates;
|
||||
}
|
||||
|
||||
void ClientDisplayView::_LoadNativeDisplayByID(const NDSDisplayID displayID)
|
||||
|
@ -501,38 +514,10 @@ void ClientDisplayView::_LoadCustomDisplayByID(const NDSDisplayID displayID)
|
|||
// Do nothing. This is implementation dependent.
|
||||
}
|
||||
|
||||
void ClientDisplayView::FetchDisplays()
|
||||
{
|
||||
const bool loadMainScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && ((this->_renderProperty.mode == ClientDisplayMode_Main) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
|
||||
const bool loadTouchScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch] && ((this->_renderProperty.mode == ClientDisplayMode_Touch) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
|
||||
|
||||
if (loadMainScreen)
|
||||
{
|
||||
if (!this->_emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Main])
|
||||
{
|
||||
this->_FetchNativeDisplayByID(NDSDisplayID_Main);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_FetchCustomDisplayByID(NDSDisplayID_Main);
|
||||
}
|
||||
}
|
||||
|
||||
if (loadTouchScreen)
|
||||
{
|
||||
if (!this->_emuDisplayInfo.didPerformCustomRender[NDSDisplayID_Touch])
|
||||
{
|
||||
this->_FetchNativeDisplayByID(NDSDisplayID_Touch);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->_FetchCustomDisplayByID(NDSDisplayID_Touch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientDisplayView::LoadDisplays()
|
||||
{
|
||||
this->_emuDisplayInfo = this->_fetchObject->GetFetchDisplayInfoForBufferIndex(this->_fetchObject->GetLastFetchIndex());
|
||||
|
||||
const bool loadMainScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Main] && ((this->_renderProperty.mode == ClientDisplayMode_Main) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
|
||||
const bool loadTouchScreen = this->_emuDisplayInfo.isDisplayEnabled[NDSDisplayID_Touch] && ((this->_renderProperty.mode == ClientDisplayMode_Touch) || (this->_renderProperty.mode == ClientDisplayMode_Dual));
|
||||
|
||||
|
@ -987,16 +972,6 @@ void ClientDisplay3DView::SetSourceDeposterize(bool useDeposterize)
|
|||
this->_useDeposterize = (this->_canFilterOnGPU) ? useDeposterize : false;
|
||||
}
|
||||
|
||||
void ClientDisplay3DView::SetVideoBuffers(const uint32_t colorFormat,
|
||||
const void *videoBufferHead,
|
||||
const void *nativeBuffer0,
|
||||
const void *nativeBuffer1,
|
||||
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
|
||||
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1)
|
||||
{
|
||||
// Do nothing. This is implementation dependent.
|
||||
}
|
||||
|
||||
void ClientDisplay3DView::SetHUDVertices(float viewportWidth, float viewportHeight, float *vtxBufferPtr)
|
||||
{
|
||||
const char *cString = this->_hudString.c_str();
|
||||
|
|
|
@ -114,6 +114,7 @@ protected:
|
|||
ClientDisplayViewProperties _renderProperty;
|
||||
ClientDisplayViewProperties _stagedProperty;
|
||||
InitialTouchPressMap *_initialTouchInMajorDisplay;
|
||||
GPUClientFetchObject *_fetchObject;
|
||||
|
||||
bool _useDeposterize;
|
||||
VideoFilterTypeID _pixelScaler;
|
||||
|
@ -135,6 +136,7 @@ protected:
|
|||
NDSFrameInfo _emuFrameInfo;
|
||||
std::string _hudString;
|
||||
bool _hudNeedsUpdate;
|
||||
bool _allowViewUpdates;
|
||||
|
||||
FT_Library _ftLibrary;
|
||||
const char *_lastFontFilePath;
|
||||
|
@ -151,8 +153,6 @@ protected:
|
|||
virtual void _UpdateClientSize();
|
||||
virtual void _UpdateViewScale();
|
||||
|
||||
virtual void _FetchNativeDisplayByID(const NDSDisplayID displayID);
|
||||
virtual void _FetchCustomDisplayByID(const NDSDisplayID displayID);
|
||||
virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID);
|
||||
virtual void _LoadCustomDisplayByID(const NDSDisplayID displayID);
|
||||
|
||||
|
@ -218,11 +218,16 @@ public:
|
|||
void ClearHUDNeedsUpdate();
|
||||
|
||||
// Client view interface
|
||||
virtual void FetchDisplays();
|
||||
const GPUClientFetchObject& GetFetchObject() const;
|
||||
void SetFetchObject(GPUClientFetchObject *fetchObject);
|
||||
|
||||
bool GetAllowViewUpdates() const;
|
||||
void SetAllowViewUpdates(const bool allowUpdates);
|
||||
|
||||
virtual void LoadDisplays();
|
||||
virtual void ProcessDisplays();
|
||||
virtual void UpdateView();
|
||||
virtual void FrameFinish() = 0;
|
||||
virtual void FinishFrameAtIndex(const u8 bufferIndex) = 0;
|
||||
|
||||
// Emulator interface
|
||||
const NDSDisplayInfo& GetEmuDisplayInfo() const;
|
||||
|
@ -269,13 +274,6 @@ public:
|
|||
|
||||
virtual void SetSourceDeposterize(const bool useDeposterize);
|
||||
|
||||
virtual void SetVideoBuffers(const uint32_t colorFormat,
|
||||
const void *videoBufferHead,
|
||||
const void *nativeBuffer0,
|
||||
const void *nativeBuffer1,
|
||||
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
|
||||
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
|
||||
|
||||
void SetHUDVertices(float viewportWidth, float viewportHeight, float *vtxBufferPtr);
|
||||
void SetHUDTextureCoordinates(float *texCoordBufferPtr);
|
||||
void SetScreenVertices(float *vtxBufferPtr);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <pthread.h>
|
||||
#include "../../filter/videofilter.h"
|
||||
|
||||
#include "ClientDisplayView.h"
|
||||
|
@ -217,8 +218,6 @@ protected:
|
|||
GLint _uniformFinalOutputScalar;
|
||||
GLint _uniformFinalOutputViewSize;
|
||||
|
||||
void UploadHQnxLUTs();
|
||||
|
||||
void UploadVerticesOGL();
|
||||
void UploadTexCoordsOGL();
|
||||
void UploadTransformationOGL();
|
||||
|
@ -270,7 +269,7 @@ public:
|
|||
virtual void SetVisibility(const bool visibleState);
|
||||
|
||||
virtual void RenderOGL() = 0;
|
||||
virtual void FinishOGL() {};
|
||||
virtual void FinishOGL(const u8 bufferIndex) {};
|
||||
};
|
||||
|
||||
class OGLHUDLayer : public OGLVideoLayer
|
||||
|
@ -301,33 +300,19 @@ class OGLDisplayLayer : public OGLVideoLayer
|
|||
protected:
|
||||
bool _useShader150;
|
||||
ShaderSupportTier _shaderSupport;
|
||||
GLboolean _useClientStorage;
|
||||
|
||||
OGLShaderProgram *_finalOutputProgram;
|
||||
OGLFilter *_filterDeposterize[2];
|
||||
OGLFilter *_shaderFilter[2];
|
||||
GLint _displayTexFilter[2];
|
||||
|
||||
GLuint _texVideoInputDataNativeID[2];
|
||||
GLuint _texVideoInputDataCustomID[2];
|
||||
GLuint _texVideoOutputID[2];
|
||||
|
||||
GLenum _videoColorFormat;
|
||||
const void *_videoSrcBufferHead;
|
||||
void *_videoSrcNativeBuffer[2];
|
||||
void *_videoSrcCustomBuffer[2];
|
||||
size_t _videoSrcBufferSize;
|
||||
|
||||
uint32_t *_vfMasterDstBuffer;
|
||||
size_t _vfMasterDstBufferSize;
|
||||
VideoFilter *_vf[2];
|
||||
GLuint _texCPUFilterDstID[2];
|
||||
|
||||
GLuint _texLQ2xLUT;
|
||||
GLuint _texHQ2xLUT;
|
||||
GLuint _texHQ3xLUT;
|
||||
GLuint _texHQ4xLUT;
|
||||
|
||||
GLuint _vaoMainStatesID;
|
||||
GLuint _vboVertexID;
|
||||
GLuint _vboTexCoordID;
|
||||
|
@ -336,9 +321,6 @@ protected:
|
|||
GLint _uniformFinalOutputScalar;
|
||||
GLint _uniformFinalOutputViewSize;
|
||||
|
||||
void _UploadHQnxLUTs();
|
||||
void _DetermineTextureStorageHints(GLint &videoSrcTexStorageHint, GLint &cpuFilterTexStorageHint);
|
||||
|
||||
void _ResizeCPUPixelScalerOGL(const size_t srcWidthMain, const size_t srcHeightMain, const size_t srcWidthTouch, const size_t srcHeightTouch, const size_t scaleMultiply, const size_t scaleDivide);
|
||||
|
||||
void _UpdateRotationScaleOGL();
|
||||
|
@ -351,30 +333,60 @@ public:
|
|||
OGLDisplayLayer(OGLVideoOutput *oglVO);
|
||||
virtual ~OGLDisplayLayer();
|
||||
|
||||
void SetVideoBuffers(const uint32_t colorFormat,
|
||||
const void *videoBufferHead,
|
||||
const void *nativeBuffer0,
|
||||
const void *nativeBuffer1,
|
||||
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
|
||||
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
|
||||
|
||||
void SetNeedsUpdateRotationScale();
|
||||
void SetFiltersPreferGPUOGL();
|
||||
|
||||
bool CanUseShaderBasedFilters();
|
||||
|
||||
OutputFilterTypeID SetOutputFilterOGL(const OutputFilterTypeID filterID);
|
||||
bool SetGPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||
void SetCPUPixelScalerOGL(const VideoFilterTypeID filterID);
|
||||
|
||||
void CopyNativeDisplayByID_OGL(const NDSDisplayID displayID);
|
||||
void CopyCustomDisplayByID_OGL(const NDSDisplayID displayID);
|
||||
void LoadNativeDisplayByID_OGL(const NDSDisplayID displayID);
|
||||
void LoadCustomDisplayByID_OGL(const NDSDisplayID displayID);
|
||||
|
||||
void ProcessOGL();
|
||||
virtual void RenderOGL();
|
||||
virtual void FinishOGL();
|
||||
virtual void FinishOGL(const u8 bufferIndex);
|
||||
};
|
||||
|
||||
class OGLClientFetchObject : public GPUClientFetchObject
|
||||
{
|
||||
protected:
|
||||
OGLContextInfo *_contextInfo;
|
||||
GLenum _fetchColorFormatOGL;
|
||||
GLuint _texDisplayFetchNative[2][2];
|
||||
GLuint _texDisplayFetchCustom[2][2];
|
||||
|
||||
GLuint _texLQ2xLUT;
|
||||
GLuint _texHQ2xLUT;
|
||||
GLuint _texHQ3xLUT;
|
||||
GLuint _texHQ4xLUT;
|
||||
|
||||
bool _useCPUFilterPipeline;
|
||||
uint32_t *_srcNativeCloneMaster;
|
||||
uint32_t *_srcNativeClone[2][2];
|
||||
pthread_rwlock_t _srcCloneRWLock[2][2];
|
||||
|
||||
virtual void _FetchNativeDisplayByID(const NDSDisplayID displayID, const u8 bufferIndex);
|
||||
virtual void _FetchCustomDisplayByID(const NDSDisplayID displayID, const u8 bufferIndex);
|
||||
|
||||
public:
|
||||
OGLClientFetchObject();
|
||||
virtual ~OGLClientFetchObject();
|
||||
|
||||
OGLContextInfo* GetContextInfo() const;
|
||||
uint32_t* GetSrcClone(const NDSDisplayID displayID, const u8 bufferIndex) const;
|
||||
GLuint GetTexNative(const NDSDisplayID displayID, const u8 bufferIndex) const;
|
||||
GLuint GetTexCustom(const NDSDisplayID displayID, const u8 bufferIndex) const;
|
||||
|
||||
// For lack of a better place, we're putting the HQnx LUTs in the fetch object because
|
||||
// we know that it will be shared for all display views.
|
||||
GLuint GetTexLQ2xLUT() const;
|
||||
GLuint GetTexHQ2xLUT() const;
|
||||
GLuint GetTexHQ3xLUT() const;
|
||||
GLuint GetTexHQ4xLUT() const;
|
||||
|
||||
void CopyFromSrcClone(uint32_t *dstBufferPtr, const NDSDisplayID displayID, const u8 bufferIndex);
|
||||
|
||||
virtual void Init();
|
||||
virtual void SetFetchBuffers(const NDSDisplayInfo ¤tDisplayInfo);
|
||||
};
|
||||
|
||||
class OGLVideoOutput : public ClientDisplay3DView
|
||||
|
@ -394,10 +406,7 @@ protected:
|
|||
virtual void _UpdateClientSize();
|
||||
virtual void _UpdateViewScale();
|
||||
|
||||
virtual void _FetchNativeDisplayByID(const NDSDisplayID displayID);
|
||||
virtual void _FetchCustomDisplayByID(const NDSDisplayID displayID);
|
||||
virtual void _LoadNativeDisplayByID(const NDSDisplayID displayID);
|
||||
virtual void _LoadCustomDisplayByID(const NDSDisplayID displayID);
|
||||
|
||||
public:
|
||||
OGLVideoOutput();
|
||||
|
@ -421,17 +430,12 @@ public:
|
|||
|
||||
virtual void SetFiltersPreferGPU(const bool preferGPU);
|
||||
|
||||
virtual void SetVideoBuffers(const uint32_t colorFormat,
|
||||
const void *videoBufferHead,
|
||||
const void *nativeBuffer0,
|
||||
const void *nativeBuffer1,
|
||||
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
|
||||
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
|
||||
|
||||
// Client view interface
|
||||
virtual void ProcessDisplays();
|
||||
virtual void FrameFinish();
|
||||
virtual void FinishFrameAtIndex(const u8 bufferIndex);
|
||||
virtual void RenderViewOGL();
|
||||
virtual void LockDisplayTextures();
|
||||
virtual void UnlockDisplayTextures();
|
||||
};
|
||||
|
||||
extern void (*glBindVertexArrayDESMUME)(GLuint id);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME team
|
||||
Copyright (C) 2013-2017 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
|
||||
|
@ -19,9 +19,39 @@
|
|||
#include <pthread.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
#import "cocoa_util.h"
|
||||
#include "../../GPU.h"
|
||||
|
||||
#ifdef BOOL
|
||||
#undef BOOL
|
||||
#endif
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11)
|
||||
//#define ENABLE_APPLE_METAL
|
||||
#endif
|
||||
|
||||
class GPUEventHandlerOSX;
|
||||
|
||||
@interface MacClientSharedObject : CocoaDSThread
|
||||
{
|
||||
GPUClientFetchObject *GPUFetchObject;
|
||||
pthread_rwlock_t *_rwlockFramebuffer[2];
|
||||
pthread_mutex_t *_mutexOutputList;
|
||||
NSMutableArray *_cdsOutputList;
|
||||
}
|
||||
|
||||
@property (assign, nonatomic) GPUClientFetchObject *GPUFetchObject;
|
||||
|
||||
- (const NDSDisplayInfo &) fetchDisplayInfoForIndex:(const u8)bufferIndex;
|
||||
- (pthread_rwlock_t *) rwlockFramebufferAtIndex:(const u8)bufferIndex;
|
||||
- (void) setOutputList:(NSMutableArray *)theOutputList mutex:(pthread_mutex_t *)theMutex;
|
||||
- (BOOL) isCPUFilteringNeeded;
|
||||
- (void) handleFetchFromBufferIndexAndPushVideo:(NSData *)indexData;
|
||||
- (void) pushVideoDataToAllDisplayViews;
|
||||
- (void) finishAllDisplayViewsAtIndex:(const u8)bufferIndex;
|
||||
|
||||
@end
|
||||
|
||||
@interface CocoaDSGPU : NSObject
|
||||
{
|
||||
UInt32 gpuStateFlags;
|
||||
|
@ -32,6 +62,7 @@ class GPUEventHandlerOSX;
|
|||
|
||||
OSSpinLock spinlockGpuState;
|
||||
GPUEventHandlerOSX *gpuEvent;
|
||||
GPUClientFetchObject *fetchObject;
|
||||
}
|
||||
|
||||
@property (assign) UInt32 gpuStateFlags;
|
||||
|
@ -39,6 +70,8 @@ class GPUEventHandlerOSX;
|
|||
@property (assign) NSUInteger gpuScale;
|
||||
@property (assign) NSUInteger gpuColorFormat;
|
||||
@property (readonly) pthread_rwlock_t *gpuFrameRWLock;
|
||||
@property (readonly, nonatomic) GPUClientFetchObject *fetchObject;
|
||||
@property (readonly, nonatomic) MacClientSharedObject *sharedData;
|
||||
|
||||
@property (assign) BOOL layerMainGPU;
|
||||
@property (assign) BOOL layerMainBG0;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "utilities.h"
|
||||
|
||||
#include "../../NDSSystem.h"
|
||||
#include "../../GPU.h"
|
||||
#include "../../rasterize.h"
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_7
|
||||
|
@ -31,8 +30,12 @@
|
|||
#endif
|
||||
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include "userinterface/MacOGLDisplayView.h"
|
||||
#include "userinterface/MacMetalDisplayView.h"
|
||||
|
||||
#ifdef BOOL
|
||||
#undef BOOL
|
||||
#endif
|
||||
|
||||
GPU3DInterface *core3DList[] = {
|
||||
&gpu3DNull,
|
||||
|
@ -44,28 +47,26 @@ GPU3DInterface *core3DList[] = {
|
|||
class GPUEventHandlerOSX : public GPUEventHandlerDefault
|
||||
{
|
||||
private:
|
||||
GPUClientFetchObject *_fetchObject;
|
||||
|
||||
pthread_rwlock_t _rwlockFrame;
|
||||
pthread_mutex_t _mutex3DRender;
|
||||
pthread_mutex_t *_mutexOutputList;
|
||||
NSMutableArray *_cdsOutputList;
|
||||
bool _render3DNeedsFinish;
|
||||
|
||||
public:
|
||||
GPUEventHandlerOSX();
|
||||
~GPUEventHandlerOSX();
|
||||
|
||||
GPUClientFetchObject* GetFetchObject() const;
|
||||
void SetFetchObject(GPUClientFetchObject *fetchObject);
|
||||
|
||||
void FramebufferLockWrite();
|
||||
void FramebufferLockRead();
|
||||
void FramebufferUnlock();
|
||||
void Render3DLock();
|
||||
void Render3DUnlock();
|
||||
|
||||
void FrameFinish();
|
||||
void SetVideoBuffers();
|
||||
|
||||
pthread_rwlock_t* GetFrameRWLock();
|
||||
NSMutableArray* GetOutputList();
|
||||
void SetOutputList(NSMutableArray *outputList, pthread_mutex_t *theMutex);
|
||||
bool GetRender3DNeedsFinish();
|
||||
|
||||
virtual void DidFrameBegin(bool isFrameSkipRequested, const u8 targetBufferIndex, const size_t line);
|
||||
|
@ -81,6 +82,8 @@ public:
|
|||
@dynamic gpuScale;
|
||||
@dynamic gpuColorFormat;
|
||||
@dynamic gpuFrameRWLock;
|
||||
@synthesize fetchObject;
|
||||
@dynamic sharedData;
|
||||
|
||||
@dynamic layerMainGPU;
|
||||
@dynamic layerMainBG0;
|
||||
|
@ -147,6 +150,20 @@ public:
|
|||
GPU->SetEventHandler(gpuEvent);
|
||||
GPU->SetWillAutoResolveToCustomBuffer(false);
|
||||
|
||||
#ifdef ENABLE_APPLE_METAL
|
||||
if (IsOSXVersionSupported(10, 11, 0))
|
||||
{
|
||||
fetchObject = new MacMetalFetchObject;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fetchObject = new MacOGLClientFetchObject;
|
||||
}
|
||||
|
||||
fetchObject->Init();
|
||||
gpuEvent->SetFetchObject(fetchObject);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -154,11 +171,22 @@ public:
|
|||
{
|
||||
DestroyOpenGLRenderer();
|
||||
|
||||
delete fetchObject;
|
||||
delete gpuEvent;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (GPUClientFetchObject *) fetchObject
|
||||
{
|
||||
return fetchObject;
|
||||
}
|
||||
|
||||
- (MacClientSharedObject *) sharedData
|
||||
{
|
||||
return (MacClientSharedObject *)fetchObject->GetClientData();
|
||||
}
|
||||
|
||||
- (void) setGpuStateFlags:(UInt32)flags
|
||||
{
|
||||
OSSpinLockLock(&spinlockGpuState);
|
||||
|
@ -191,13 +219,15 @@ public:
|
|||
|
||||
- (void) setGpuDimensions:(NSSize)theDimensions
|
||||
{
|
||||
gpuEvent->FrameFinish();
|
||||
[[self sharedData] finishAllDisplayViewsAtIndex:0];
|
||||
[[self sharedData] finishAllDisplayViewsAtIndex:1];
|
||||
|
||||
gpuEvent->Render3DLock();
|
||||
gpuEvent->FramebufferLockWrite();
|
||||
|
||||
GPU->SetCustomFramebufferSize(theDimensions.width, theDimensions.height);
|
||||
fetchObject->SetFetchBuffers(GPU->GetDisplayInfo());
|
||||
|
||||
gpuEvent->SetVideoBuffers();
|
||||
gpuEvent->FramebufferUnlock();
|
||||
gpuEvent->Render3DUnlock();
|
||||
}
|
||||
|
@ -226,13 +256,15 @@ public:
|
|||
|
||||
- (void) setGpuColorFormat:(NSUInteger)colorFormat
|
||||
{
|
||||
gpuEvent->FrameFinish();
|
||||
[[self sharedData] finishAllDisplayViewsAtIndex:0];
|
||||
[[self sharedData] finishAllDisplayViewsAtIndex:1];
|
||||
|
||||
gpuEvent->Render3DLock();
|
||||
gpuEvent->FramebufferLockWrite();
|
||||
|
||||
GPU->SetColorFormat((NDSColorFormat)colorFormat);
|
||||
fetchObject->SetFetchBuffers(GPU->GetDisplayInfo());
|
||||
|
||||
gpuEvent->SetVideoBuffers();
|
||||
gpuEvent->FramebufferUnlock();
|
||||
gpuEvent->Render3DUnlock();
|
||||
}
|
||||
|
@ -255,7 +287,7 @@ public:
|
|||
|
||||
- (void) setOutputList:(NSMutableArray *)theOutputList mutexPtr:(pthread_mutex_t *)theMutex
|
||||
{
|
||||
gpuEvent->SetOutputList(theOutputList, theMutex);
|
||||
[(MacClientSharedObject *)fetchObject->GetClientData() setOutputList:theOutputList mutex:theMutex];
|
||||
}
|
||||
|
||||
- (void) setRender3DRenderingEngine:(NSInteger)methodID
|
||||
|
@ -814,10 +846,196 @@ public:
|
|||
|
||||
@end
|
||||
|
||||
@implementation MacClientSharedObject
|
||||
|
||||
@synthesize GPUFetchObject;
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
_rwlockFramebuffer[0] = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
|
||||
_rwlockFramebuffer[1] = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t));
|
||||
|
||||
pthread_rwlock_init(_rwlockFramebuffer[0], NULL);
|
||||
pthread_rwlock_init(_rwlockFramebuffer[1], NULL);
|
||||
|
||||
GPUFetchObject = nil;
|
||||
_mutexOutputList = NULL;
|
||||
_cdsOutputList = nil;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
pthread_mutex_t *currentMutex = _mutexOutputList;
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_lock(currentMutex);
|
||||
}
|
||||
|
||||
[_cdsOutputList release];
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(currentMutex);
|
||||
}
|
||||
|
||||
pthread_rwlock_destroy(_rwlockFramebuffer[0]);
|
||||
pthread_rwlock_destroy(_rwlockFramebuffer[1]);
|
||||
|
||||
[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];
|
||||
|
||||
GPUFetchObject->FetchFromBufferIndex(index);
|
||||
[self pushVideoDataToAllDisplayViews];
|
||||
}
|
||||
|
||||
- (const NDSDisplayInfo &) fetchDisplayInfoForIndex:(const u8)bufferIndex
|
||||
{
|
||||
return GPUFetchObject->GetFetchDisplayInfoForBufferIndex(bufferIndex);
|
||||
}
|
||||
|
||||
- (pthread_rwlock_t *) rwlockFramebufferAtIndex:(const u8)bufferIndex
|
||||
{
|
||||
return _rwlockFramebuffer[bufferIndex];
|
||||
}
|
||||
|
||||
- (void) setOutputList:(NSMutableArray *)theOutputList mutex:(pthread_mutex_t *)theMutex
|
||||
{
|
||||
pthread_mutex_t *currentMutex = _mutexOutputList;
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_lock(currentMutex);
|
||||
}
|
||||
|
||||
[_cdsOutputList release];
|
||||
_cdsOutputList = theOutputList;
|
||||
[_cdsOutputList retain];
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(currentMutex);
|
||||
}
|
||||
|
||||
_mutexOutputList = theMutex;
|
||||
}
|
||||
|
||||
- (BOOL) isCPUFilteringNeeded
|
||||
{
|
||||
bool useCPUFilterPipeline = NO;
|
||||
pthread_mutex_t *currentMutex = _mutexOutputList;
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_lock(currentMutex);
|
||||
}
|
||||
|
||||
for (CocoaDSOutput *cdsOutput in _cdsOutputList)
|
||||
{
|
||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
|
||||
{
|
||||
ClientDisplay3DView *cdv = [(CocoaDSDisplay *)cdsOutput clientDisplayView];
|
||||
|
||||
if (!cdv->WillFilterOnGPU() && (cdv->GetPixelScaler() != VideoFilterTypeID_None))
|
||||
{
|
||||
useCPUFilterPipeline = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(currentMutex);
|
||||
}
|
||||
|
||||
return useCPUFilterPipeline;
|
||||
}
|
||||
|
||||
- (void) pushVideoDataToAllDisplayViews
|
||||
{
|
||||
pthread_mutex_t *currentMutex = _mutexOutputList;
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_lock(currentMutex);
|
||||
}
|
||||
|
||||
for (CocoaDSOutput *cdsOutput in _cdsOutputList)
|
||||
{
|
||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
|
||||
{
|
||||
[CocoaDSUtil messageSendOneWay:[cdsOutput receivePort] msgID:MESSAGE_RECEIVE_GPU_FRAME];
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(currentMutex);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) finishAllDisplayViewsAtIndex:(const u8)bufferIndex
|
||||
{
|
||||
pthread_mutex_t *currentMutex = _mutexOutputList;
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_lock(currentMutex);
|
||||
}
|
||||
|
||||
for (CocoaDSOutput *cdsOutput in _cdsOutputList)
|
||||
{
|
||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
|
||||
{
|
||||
ClientDisplay3DView *cdv = [(CocoaDSDisplay *)cdsOutput clientDisplayView];
|
||||
cdv->FinishFrameAtIndex(bufferIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMutex != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(currentMutex);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
GPUEventHandlerOSX::GPUEventHandlerOSX()
|
||||
{
|
||||
_fetchObject = nil;
|
||||
_render3DNeedsFinish = false;
|
||||
_mutexOutputList = NULL;
|
||||
pthread_rwlock_init(&_rwlockFrame, NULL);
|
||||
pthread_mutex_init(&_mutex3DRender, NULL);
|
||||
}
|
||||
|
@ -833,37 +1051,46 @@ GPUEventHandlerOSX::~GPUEventHandlerOSX()
|
|||
pthread_mutex_destroy(&this->_mutex3DRender);
|
||||
}
|
||||
|
||||
GPUClientFetchObject* GPUEventHandlerOSX::GetFetchObject() const
|
||||
{
|
||||
return this->_fetchObject;
|
||||
}
|
||||
|
||||
void GPUEventHandlerOSX::SetFetchObject(GPUClientFetchObject *fetchObject)
|
||||
{
|
||||
this->_fetchObject = fetchObject;
|
||||
}
|
||||
|
||||
void GPUEventHandlerOSX::DidFrameBegin(bool isFrameSkipRequested, const u8 targetBufferIndex, const size_t line)
|
||||
{
|
||||
this->FramebufferLockWrite();
|
||||
|
||||
#if !defined(PORT_VERSION_OPENEMU)
|
||||
if (!isFrameSkipRequested)
|
||||
{
|
||||
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)this->_fetchObject->GetClientData();
|
||||
pthread_rwlock_wrlock([sharedViewObject rwlockFramebufferAtIndex:targetBufferIndex]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPUEventHandlerOSX::DidFrameEnd(bool isFrameSkipped, const NDSDisplayInfo &latestDisplayInfo)
|
||||
{
|
||||
#if !defined(PORT_VERSION_OPENEMU)
|
||||
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)this->_fetchObject->GetClientData();
|
||||
if (!isFrameSkipped)
|
||||
{
|
||||
this->_fetchObject->SetFetchDisplayInfo(latestDisplayInfo);
|
||||
pthread_rwlock_unlock([sharedViewObject rwlockFramebufferAtIndex:latestDisplayInfo.bufferIndex]);
|
||||
}
|
||||
#endif
|
||||
|
||||
this->FramebufferUnlock();
|
||||
|
||||
#if !defined(PORT_VERSION_OPENEMU)
|
||||
if (!isFrameSkipped)
|
||||
{
|
||||
if (this->_mutexOutputList != NULL)
|
||||
{
|
||||
pthread_mutex_lock(this->_mutexOutputList);
|
||||
}
|
||||
|
||||
NSMutableArray *outputList = this->_cdsOutputList;
|
||||
|
||||
for (CocoaDSOutput *cdsOutput in outputList)
|
||||
{
|
||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
|
||||
{
|
||||
[(CocoaDSDisplay *)cdsOutput doReceiveGPUFrame];
|
||||
}
|
||||
}
|
||||
|
||||
if (this->_mutexOutputList != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(this->_mutexOutputList);
|
||||
}
|
||||
[CocoaDSUtil messageSendOneWayWithInteger:[sharedViewObject receivePort] msgID:MESSAGE_FETCH_AND_PUSH_VIDEO integerValue:latestDisplayInfo.bufferIndex];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -905,56 +1132,6 @@ void GPUEventHandlerOSX::Render3DUnlock()
|
|||
pthread_mutex_unlock(&this->_mutex3DRender);
|
||||
}
|
||||
|
||||
void GPUEventHandlerOSX::FrameFinish()
|
||||
{
|
||||
#if !defined(PORT_VERSION_OPENEMU)
|
||||
if (this->_mutexOutputList != NULL)
|
||||
{
|
||||
pthread_mutex_lock(this->_mutexOutputList);
|
||||
}
|
||||
|
||||
NSMutableArray *outputList = this->_cdsOutputList;
|
||||
|
||||
for (CocoaDSOutput *cdsOutput in outputList)
|
||||
{
|
||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplay class]])
|
||||
{
|
||||
[(CocoaDSDisplay *)cdsOutput finishFrame];
|
||||
}
|
||||
}
|
||||
|
||||
if (this->_mutexOutputList != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(this->_mutexOutputList);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPUEventHandlerOSX::SetVideoBuffers()
|
||||
{
|
||||
#if !defined(PORT_VERSION_OPENEMU)
|
||||
if (this->_mutexOutputList != NULL)
|
||||
{
|
||||
pthread_mutex_lock(this->_mutexOutputList);
|
||||
}
|
||||
|
||||
NSMutableArray *outputList = this->_cdsOutputList;
|
||||
|
||||
for (CocoaDSOutput *cdsOutput in outputList)
|
||||
{
|
||||
if ([cdsOutput isKindOfClass:[CocoaDSDisplayVideo class]])
|
||||
{
|
||||
[(CocoaDSDisplayVideo *)cdsOutput resetVideoBuffers];
|
||||
}
|
||||
}
|
||||
|
||||
if (this->_mutexOutputList != NULL)
|
||||
{
|
||||
pthread_mutex_unlock(this->_mutexOutputList);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool GPUEventHandlerOSX::GetRender3DNeedsFinish()
|
||||
{
|
||||
return this->_render3DNeedsFinish;
|
||||
|
@ -965,16 +1142,7 @@ pthread_rwlock_t* GPUEventHandlerOSX::GetFrameRWLock()
|
|||
return &this->_rwlockFrame;
|
||||
}
|
||||
|
||||
NSMutableArray* GPUEventHandlerOSX::GetOutputList()
|
||||
{
|
||||
return this->_cdsOutputList;
|
||||
}
|
||||
|
||||
void GPUEventHandlerOSX::SetOutputList(NSMutableArray *outputList, pthread_mutex_t *theMutex)
|
||||
{
|
||||
this->_cdsOutputList = outputList;
|
||||
this->_mutexOutputList = theMutex;
|
||||
}
|
||||
#pragma mark -
|
||||
|
||||
CGLContextObj OSXOpenGLRendererContext = NULL;
|
||||
|
||||
|
|
|
@ -404,6 +404,7 @@ enum
|
|||
MESSAGE_SET_EMULATION_FLAGS,
|
||||
|
||||
// Video Messages
|
||||
MESSAGE_FETCH_AND_PUSH_VIDEO,
|
||||
MESSAGE_RECEIVE_GPU_FRAME,
|
||||
MESSAGE_CHANGE_VIEW_PROPERTIES,
|
||||
MESSAGE_REDRAW_VIEW,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2011 Roger Manuel
|
||||
Copyright (C) 2011-2016 DeSmuME team
|
||||
Copyright (C) 2011-2017 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
|
||||
|
@ -118,13 +118,11 @@ struct NDSFrameInfo;
|
|||
|
||||
- (void) commitViewProperties:(const ClientDisplayViewProperties &)viewProps;
|
||||
|
||||
- (void) doReceiveGPUFrame;
|
||||
- (void) handleReceiveGPUFrame;
|
||||
- (void) handleChangeViewProperties;
|
||||
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData;
|
||||
- (void) handleCopyToPasteboard;
|
||||
|
||||
- (void) finishFrame;
|
||||
- (void) takeFrameCount;
|
||||
- (void) setCPULoadAvgARM9:(uint32_t)loadAvgARM9 ARM7:(uint32_t)loadAvgARM7;
|
||||
- (NSImage *) image;
|
||||
|
@ -133,11 +131,7 @@ struct NDSFrameInfo;
|
|||
@end
|
||||
|
||||
@interface CocoaDSDisplayVideo : CocoaDSDisplay
|
||||
{
|
||||
void *_videoBuffer;
|
||||
void *_nativeBuffer[2];
|
||||
void *_customBuffer[2];
|
||||
|
||||
{
|
||||
OSSpinLock spinlockIsHUDVisible;
|
||||
OSSpinLock spinlockUseVerticalSync;
|
||||
OSSpinLock spinlockVideoFiltersPreferGPU;
|
||||
|
@ -165,7 +159,6 @@ struct NDSFrameInfo;
|
|||
- (void) handleReprocessRedraw;
|
||||
- (void) handleRedraw;
|
||||
|
||||
- (void) resetVideoBuffers;
|
||||
- (void) setScaleFactor:(float)theScaleFactor;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2011 Roger Manuel
|
||||
Copyright (C) 2011-2016 DeSmuME team
|
||||
Copyright (C) 2011-2017 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
|
||||
|
@ -561,11 +561,6 @@
|
|||
return size;
|
||||
}
|
||||
|
||||
- (void) doReceiveGPUFrame
|
||||
{
|
||||
[CocoaDSUtil messageSendOneWay:self.receivePort msgID:MESSAGE_RECEIVE_GPU_FRAME];
|
||||
}
|
||||
|
||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
||||
{
|
||||
NSInteger message = (NSInteger)[portMessage msgid];
|
||||
|
@ -642,11 +637,6 @@
|
|||
[pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType];
|
||||
}
|
||||
|
||||
- (void) finishFrame
|
||||
{
|
||||
_cdv->FrameFinish();
|
||||
}
|
||||
|
||||
- (void) takeFrameCount
|
||||
{
|
||||
OSSpinLockLock(&spinlockReceivedFrameIndex);
|
||||
|
@ -764,12 +754,6 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
_videoBuffer = NULL;
|
||||
_nativeBuffer[NDSDisplayID_Main] = NULL;
|
||||
_nativeBuffer[NDSDisplayID_Touch] = NULL;
|
||||
_customBuffer[NDSDisplayID_Main] = NULL;
|
||||
_customBuffer[NDSDisplayID_Touch] = NULL;
|
||||
|
||||
spinlockIsHUDVisible = OS_SPINLOCK_INIT;
|
||||
spinlockUseVerticalSync = OS_SPINLOCK_INIT;
|
||||
spinlockVideoFiltersPreferGPU = OS_SPINLOCK_INIT;
|
||||
|
@ -782,12 +766,6 @@
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
free_aligned(_videoBuffer);
|
||||
_nativeBuffer[NDSDisplayID_Main] = NULL;
|
||||
_nativeBuffer[NDSDisplayID_Touch] = NULL;
|
||||
_customBuffer[NDSDisplayID_Main] = NULL;
|
||||
_customBuffer[NDSDisplayID_Touch] = NULL;
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -1038,15 +1016,6 @@
|
|||
- (void) handleReceiveGPUFrame
|
||||
{
|
||||
[super handleReceiveGPUFrame];
|
||||
[self finishFrame];
|
||||
|
||||
pthread_rwlock_rdlock(self.rwlockProducer);
|
||||
|
||||
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
|
||||
_cdv->SetEmuDisplayInfo(dispInfo);
|
||||
_cdv->FetchDisplays();
|
||||
|
||||
pthread_rwlock_unlock(self.rwlockProducer);
|
||||
|
||||
_cdv->LoadDisplays();
|
||||
_cdv->ProcessDisplays();
|
||||
|
@ -1054,13 +1023,20 @@
|
|||
|
||||
- (void) handleReloadReprocessRedraw
|
||||
{
|
||||
[self handleReceiveGPUFrame];
|
||||
GPUClientFetchObject &fetchObjMutable = (GPUClientFetchObject &)_cdv->GetFetchObject();
|
||||
const u8 bufferIndex = fetchObjMutable.GetLastFetchIndex();
|
||||
|
||||
fetchObjMutable.FetchFromBufferIndex(bufferIndex);
|
||||
_cdv->LoadDisplays();
|
||||
_cdv->ProcessDisplays();
|
||||
|
||||
[self handleEmuFrameProcessed];
|
||||
}
|
||||
|
||||
- (void) handleReprocessRedraw
|
||||
{
|
||||
[self handleEmuFrameProcessed];
|
||||
{
|
||||
_cdv->ProcessDisplays();
|
||||
_cdv->UpdateView();
|
||||
}
|
||||
|
||||
- (void) handleRedraw
|
||||
|
@ -1068,33 +1044,6 @@
|
|||
_cdv->UpdateView();
|
||||
}
|
||||
|
||||
- (void) resetVideoBuffers
|
||||
{
|
||||
const NDSDisplayInfo &dispInfo = GPU->GetDisplayInfo();
|
||||
|
||||
void *oldVideoBuffer = _videoBuffer;
|
||||
uint8_t *newVideoBuffer = (uint8_t *)malloc_alignedCacheLine( ((GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT) + (dispInfo.customWidth * dispInfo.customHeight)) * 2 * dispInfo.pixelBytes );
|
||||
|
||||
_cdv->SetVideoBuffers(dispInfo.colorFormat,
|
||||
newVideoBuffer,
|
||||
newVideoBuffer,
|
||||
newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * dispInfo.pixelBytes),
|
||||
newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * dispInfo.pixelBytes),
|
||||
dispInfo.customWidth,
|
||||
dispInfo.customHeight,
|
||||
newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * dispInfo.pixelBytes) + (dispInfo.customWidth * dispInfo.customHeight * dispInfo.pixelBytes),
|
||||
dispInfo.customWidth,
|
||||
dispInfo.customHeight);
|
||||
|
||||
_videoBuffer = newVideoBuffer;
|
||||
_nativeBuffer[NDSDisplayID_Main] = newVideoBuffer;
|
||||
_nativeBuffer[NDSDisplayID_Touch] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * dispInfo.pixelBytes);
|
||||
_customBuffer[NDSDisplayID_Main] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * dispInfo.pixelBytes);
|
||||
_customBuffer[NDSDisplayID_Touch] = newVideoBuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * 2 * dispInfo.pixelBytes) + (dispInfo.customWidth * dispInfo.customHeight * dispInfo.pixelBytes);
|
||||
|
||||
free_aligned(oldVideoBuffer);
|
||||
}
|
||||
|
||||
- (void) setScaleFactor:(float)theScaleFactor
|
||||
{
|
||||
OSSpinLockLock(&spinlockIsHUDVisible);
|
||||
|
|
|
@ -47,6 +47,7 @@ class OGLVideoOutput;
|
|||
@property (retain) CocoaDSDisplayVideo *cdsVideoOutput;
|
||||
@property (readonly, nonatomic) ClientDisplay3DView *clientDisplay3DView;
|
||||
@property (readonly) BOOL canUseShaderBasedFilters;
|
||||
@property (assign, nonatomic) BOOL allowViewUpdates;
|
||||
@property (assign) BOOL isHUDVisible;
|
||||
@property (assign) BOOL isHUDVideoFPSVisible;
|
||||
@property (assign) BOOL isHUDRender3DFPSVisible;
|
||||
|
@ -60,7 +61,7 @@ class OGLVideoOutput;
|
|||
@property (assign) NSInteger outputFilter;
|
||||
@property (assign) NSInteger pixelScaler;
|
||||
|
||||
- (void) reassignLocalCALayer;
|
||||
- (void) setupLayer;
|
||||
|
||||
- (BOOL) handleKeyPress:(NSEvent *)theEvent keyPressed:(BOOL)keyPressed;
|
||||
- (BOOL) handleMouseButton:(NSEvent *)theEvent buttonPressed:(BOOL)buttonPressed;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#import "InputManager.h"
|
||||
|
||||
#import "cocoa_core.h"
|
||||
#import "cocoa_GPU.h"
|
||||
#import "cocoa_file.h"
|
||||
#import "cocoa_input.h"
|
||||
#import "cocoa_globals.h"
|
||||
|
@ -28,9 +29,7 @@
|
|||
|
||||
#include "MacOGLDisplayView.h"
|
||||
|
||||
//#define ENABLE_APPLE_METAL
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) && defined(ENABLE_APPLE_METAL)
|
||||
#ifdef ENABLE_APPLE_METAL
|
||||
#include "MacMetalDisplayView.h"
|
||||
#endif
|
||||
|
||||
|
@ -356,7 +355,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
- (void) setVideoOutputFilter:(NSInteger)filterID
|
||||
{
|
||||
[[self view] setOutputFilter:filterID];
|
||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REPROCESS_AND_REDRAW];
|
||||
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REDRAW_VIEW];
|
||||
}
|
||||
|
||||
- (NSInteger) videoOutputFilter
|
||||
|
@ -668,6 +667,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
// Show the full screen window.
|
||||
[self setWindow:newFullScreenWindow];
|
||||
[newFullScreenWindow makeKeyAndOrderFront:self];
|
||||
[newFullScreenWindow makeMainWindow];
|
||||
[newFullScreenWindow display];
|
||||
|
||||
[self setAssignedScreen:targetScreen];
|
||||
|
@ -697,6 +697,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
[[masterWindow contentView] addSubview:view];
|
||||
[masterWindow setInitialFirstResponder:view];
|
||||
[masterWindow makeKeyAndOrderFront:self];
|
||||
[masterWindow makeMainWindow];
|
||||
[masterWindow display];
|
||||
}
|
||||
|
||||
|
@ -1272,7 +1273,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
[[emuControl windowList] addObject:self];
|
||||
[emuControl updateAllWindowTitles];
|
||||
|
||||
[view reassignLocalCALayer];
|
||||
[view setupLayer];
|
||||
[view setInputManager:[emuControl inputManager]];
|
||||
|
||||
// Set up the scaling factor if this is a Retina window
|
||||
|
@ -1305,7 +1306,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
cdv->LoadHUDFont();
|
||||
}
|
||||
|
||||
[newDisplayOutput resetVideoBuffers];
|
||||
[self setCdsVideoOutput:newDisplayOutput];
|
||||
[view setCdsVideoOutput:newDisplayOutput];
|
||||
|
||||
|
@ -1600,6 +1600,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
@synthesize cdsVideoOutput;
|
||||
@dynamic clientDisplay3DView;
|
||||
@dynamic canUseShaderBasedFilters;
|
||||
@dynamic allowViewUpdates;
|
||||
@dynamic isHUDVisible;
|
||||
@dynamic isHUDVideoFPSVisible;
|
||||
@dynamic isHUDRender3DFPSVisible;
|
||||
|
@ -1625,45 +1626,6 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
cdsVideoOutput = nil;
|
||||
localLayer = nil;
|
||||
localOGLContext = nil;
|
||||
|
||||
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) && defined(ENABLE_APPLE_METAL)
|
||||
if (IsOSXVersionSupported(10, 11, 0))
|
||||
{
|
||||
localLayer = [[DisplayViewMetalLayer alloc] init];
|
||||
|
||||
if ([(DisplayViewMetalLayer *)localLayer device] == nil)
|
||||
{
|
||||
[localLayer release];
|
||||
localLayer = nil;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (localLayer == nil)
|
||||
{
|
||||
localLayer = [[DisplayViewOpenGLLayer alloc] init];
|
||||
MacOGLDisplayView *macOGLCDV = (MacOGLDisplayView *)[(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
|
||||
|
||||
// For macOS 10.8 Mountain Lion and later, we can use the CAOpenGLLayer directly. But for
|
||||
// earlier versions of macOS, using the CALayer directly will cause too many strange issues,
|
||||
// so we'll just keep using the old-school NSOpenGLContext for these older macOS versions.
|
||||
if (IsOSXVersionSupported(10, 8, 0))
|
||||
{
|
||||
macOGLCDV->SetRenderToCALayer(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)])
|
||||
{
|
||||
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||
}
|
||||
#endif
|
||||
localOGLContext = macOGLCDV->GetNSContext();
|
||||
[localOGLContext retain];
|
||||
macOGLCDV->SetRenderToCALayer(false);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -1697,6 +1659,16 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
return [[self cdsVideoOutput] canFilterOnGPU];
|
||||
}
|
||||
|
||||
- (BOOL) allowViewUpdates
|
||||
{
|
||||
return ([self clientDisplay3DView]->GetAllowViewUpdates()) ? YES : NO;
|
||||
}
|
||||
|
||||
- (void) setAllowViewUpdates:(BOOL)allowUpdates
|
||||
{
|
||||
[self clientDisplay3DView]->SetAllowViewUpdates((allowUpdates) ? true : false);
|
||||
}
|
||||
|
||||
- (void) setIsHUDVisible:(BOOL)theState
|
||||
{
|
||||
[[self cdsVideoOutput] setIsHUDVisible:theState];
|
||||
|
@ -1818,8 +1790,59 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
}
|
||||
|
||||
#pragma mark Class Methods
|
||||
- (void) reassignLocalCALayer
|
||||
- (void) setupLayer
|
||||
{
|
||||
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
|
||||
CocoaDSCore *cdsCore = (CocoaDSCore *)[[[windowController emuControl] cdsCoreController] content];
|
||||
CocoaDSGPU *cdsGPU = [cdsCore cdsGPU];
|
||||
|
||||
#ifdef ENABLE_APPLE_METAL
|
||||
MacClientSharedObject *macSharedData = [cdsGPU sharedData];
|
||||
if ((macSharedData != nil) && [macSharedData isKindOfClass:[MetalDisplayViewSharedData class]])
|
||||
{
|
||||
localLayer = [[DisplayViewMetalLayer alloc] init];
|
||||
[(DisplayViewMetalLayer *)localLayer setSharedData:(MetalDisplayViewSharedData *)macSharedData];
|
||||
|
||||
MacMetalDisplayView *cdv = (MacMetalDisplayView *)[(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
|
||||
cdv->SetFetchObject([cdsGPU fetchObject]);
|
||||
cdv->Init();
|
||||
|
||||
if ([(DisplayViewMetalLayer *)localLayer device] == nil)
|
||||
{
|
||||
[localLayer release];
|
||||
localLayer = nil;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (localLayer == nil)
|
||||
{
|
||||
localLayer = [[DisplayViewOpenGLLayer alloc] init];
|
||||
MacOGLDisplayView *macOGLCDV = (MacOGLDisplayView *)[(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
|
||||
macOGLCDV->SetFetchObject([cdsGPU fetchObject]);
|
||||
macOGLCDV->Init();
|
||||
|
||||
// For macOS 10.8 Mountain Lion and later, we can use the CAOpenGLLayer directly. But for
|
||||
// earlier versions of macOS, using the CALayer directly will cause too many strange issues,
|
||||
// so we'll just keep using the old-school NSOpenGLContext for these older macOS versions.
|
||||
if (IsOSXVersionSupported(10, 8, 0))
|
||||
{
|
||||
macOGLCDV->SetRenderToCALayer(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7)
|
||||
if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)])
|
||||
{
|
||||
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||
}
|
||||
#endif
|
||||
localOGLContext = macOGLCDV->GetNSContext();
|
||||
[localOGLContext retain];
|
||||
macOGLCDV->SetRenderToCALayer(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (localOGLContext != nil)
|
||||
{
|
||||
// If localOGLContext isn't nil, then we will not assign the local layer
|
||||
|
@ -1978,14 +2001,12 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
|
||||
- (void)updateLayer
|
||||
{
|
||||
ClientDisplay3DView *cdv = [(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
|
||||
cdv->UpdateView();
|
||||
[self clientDisplay3DView]->UpdateView();
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
ClientDisplay3DView *cdv = [(id<DisplayViewCALayer>)localLayer clientDisplay3DView];
|
||||
cdv->UpdateView();
|
||||
[self clientDisplay3DView]->UpdateView();
|
||||
}
|
||||
|
||||
- (void)setFrame:(NSRect)rect
|
||||
|
@ -2023,7 +2044,7 @@ static std::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; //
|
|||
{
|
||||
[localLayer setBounds:CGRectMake(0.0f, 0.0f, props.clientWidth, props.clientHeight)];
|
||||
}
|
||||
#if defined(MAC_OS_X_VERSION_10_11) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11) && defined(ENABLE_APPLE_METAL)
|
||||
#ifdef ENABLE_APPLE_METAL
|
||||
else if ([[self layer] isKindOfClass:[CAMetalLayer class]])
|
||||
{
|
||||
[(CAMetalLayer *)localLayer setDrawableSize:CGSizeMake(props.clientWidth, props.clientHeight)];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2015 DeSmuME Team
|
||||
Copyright (C) 2013-2017 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
|
||||
|
@ -347,8 +347,9 @@
|
|||
{
|
||||
DisplayWindowController *newWindowController = [[DisplayWindowController alloc] initWithWindowNibName:@"DisplayWindow" emuControlDelegate:self];
|
||||
|
||||
[CocoaDSUtil messageSendOneWay:[[newWindowController cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW];
|
||||
|
||||
[newWindowController window]; // Just reference the window to force the nib to load.
|
||||
[[newWindowController view] setAllowViewUpdates:YES];
|
||||
[[newWindowController cdsVideoOutput] handleReloadReprocessRedraw];
|
||||
[[newWindowController window] makeKeyAndOrderFront:self];
|
||||
[[newWindowController window] makeMainWindow];
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#import <OpenGL/OpenGL.h>
|
||||
|
||||
#import "DisplayViewCALayer.h"
|
||||
#import "../cocoa_GPU.h"
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_10_7
|
||||
#include "../OGLDisplayOutput_3_2.h"
|
||||
|
@ -29,7 +30,9 @@
|
|||
#include "../OGLDisplayOutput.h"
|
||||
#endif
|
||||
|
||||
#ifdef BOOL
|
||||
#undef BOOL
|
||||
#endif
|
||||
|
||||
class MacOGLDisplayView;
|
||||
|
||||
|
@ -39,6 +42,24 @@ class MacOGLDisplayView;
|
|||
}
|
||||
@end
|
||||
|
||||
class MacOGLClientFetchObject : public OGLClientFetchObject
|
||||
{
|
||||
protected:
|
||||
NSOpenGLContext *_nsContext;
|
||||
CGLContextObj _context;
|
||||
|
||||
public:
|
||||
void operator delete(void *ptr);
|
||||
MacOGLClientFetchObject();
|
||||
|
||||
NSOpenGLContext* GetNSContext() const;
|
||||
CGLContextObj GetContext() const;
|
||||
|
||||
virtual void Init();
|
||||
virtual void SetFetchBuffers(const NDSDisplayInfo ¤tDisplayInfo);
|
||||
virtual void FetchFromBufferIndex(const u8 index);
|
||||
};
|
||||
|
||||
class MacOGLDisplayView : public OGLVideoOutput, public DisplayViewCALayerInterface
|
||||
{
|
||||
protected:
|
||||
|
@ -64,13 +85,6 @@ public:
|
|||
|
||||
virtual void LoadHUDFont();
|
||||
|
||||
virtual void SetVideoBuffers(const uint32_t colorFormat,
|
||||
const void *videoBufferHead,
|
||||
const void *nativeBuffer0,
|
||||
const void *nativeBuffer1,
|
||||
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
|
||||
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1);
|
||||
|
||||
virtual void SetUseVerticalSync(const bool useVerticalSync);
|
||||
virtual void SetScaleFactor(const double scaleFactor);
|
||||
|
||||
|
@ -83,7 +97,9 @@ public:
|
|||
virtual void LoadDisplays();
|
||||
virtual void ProcessDisplays();
|
||||
virtual void UpdateView();
|
||||
virtual void FrameFinish();
|
||||
virtual void FinishFrameAtIndex(const u8 bufferIndex);
|
||||
virtual void LockDisplayTextures();
|
||||
virtual void UnlockDisplayTextures();
|
||||
};
|
||||
|
||||
#endif // _MAC_OGLDISPLAYOUTPUT_H_
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "MacOGLDisplayView.h"
|
||||
#include "../utilities.h"
|
||||
|
||||
|
||||
@implementation DisplayViewOpenGLLayer
|
||||
|
||||
- (id)init
|
||||
|
@ -30,7 +31,6 @@
|
|||
|
||||
_cdv = new MacOGLDisplayView();
|
||||
_cdv->SetFrontendLayer(self);
|
||||
_cdv->Init();
|
||||
|
||||
[self setBounds:CGRectMake(0.0f, 0.0f, (float)GPU_FRAMEBUFFER_NATIVE_WIDTH, (float)GPU_FRAMEBUFFER_NATIVE_HEIGHT)];
|
||||
[self setAsynchronous:NO];
|
||||
|
@ -82,6 +82,137 @@
|
|||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void MacOGLClientFetchObject::operator delete(void *ptr)
|
||||
{
|
||||
MacOGLClientFetchObject *fetchObjectPtr = (MacOGLClientFetchObject *)ptr;
|
||||
[(MacClientSharedObject *)(fetchObjectPtr->GetClientData()) release];
|
||||
|
||||
CGLContextObj context = fetchObjectPtr->GetContext();
|
||||
OGLContextInfo *contextInfo = fetchObjectPtr->GetContextInfo();
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
CGLSetCurrentContext(context);
|
||||
::operator delete(ptr);
|
||||
CGLSetCurrentContext(prevContext);
|
||||
|
||||
delete contextInfo;
|
||||
[fetchObjectPtr->GetNSContext() release];
|
||||
}
|
||||
}
|
||||
|
||||
MacOGLClientFetchObject::MacOGLClientFetchObject()
|
||||
{
|
||||
// Initialize the OpenGL context.
|
||||
//
|
||||
// We create an NSOpenGLContext and extract the CGLContextObj from it because
|
||||
// [NSOpenGLContext CGLContextObj] is available on macOS 10.5 Leopard, but
|
||||
// [NSOpenGLContext initWithCGLContextObj:] is only available on macOS 10.6
|
||||
// Snow Leopard.
|
||||
bool useContext_3_2 = false;
|
||||
NSOpenGLPixelFormatAttribute attributes[] = {
|
||||
NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24,
|
||||
NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
|
||||
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)0,
|
||||
NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)0,
|
||||
(NSOpenGLPixelFormatAttribute)0, (NSOpenGLPixelFormatAttribute)0,
|
||||
(NSOpenGLPixelFormatAttribute)0
|
||||
};
|
||||
|
||||
#ifdef _OGLDISPLAYOUTPUT_3_2_H_
|
||||
// If we can support a 3.2 Core Profile context, then request that in our
|
||||
// pixel format attributes.
|
||||
useContext_3_2 = IsOSXVersionSupported(10, 7, 0);
|
||||
if (useContext_3_2)
|
||||
{
|
||||
attributes[8] = NSOpenGLPFAOpenGLProfile;
|
||||
attributes[9] = (NSOpenGLPixelFormatAttribute)NSOpenGLProfileVersion3_2Core;
|
||||
}
|
||||
#endif
|
||||
|
||||
NSOpenGLPixelFormat *nsPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||
if (nsPixelFormat == nil)
|
||||
{
|
||||
// If we can't get a 3.2 Core Profile context, then switch to using a
|
||||
// legacy context instead.
|
||||
useContext_3_2 = false;
|
||||
attributes[9] = (NSOpenGLPixelFormatAttribute)0;
|
||||
attributes[10] = (NSOpenGLPixelFormatAttribute)0;
|
||||
nsPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||
}
|
||||
|
||||
_nsContext = [[NSOpenGLContext alloc] initWithFormat:nsPixelFormat shareContext:nil];
|
||||
_context = (CGLContextObj)[_nsContext CGLContextObj];
|
||||
|
||||
[nsPixelFormat release];
|
||||
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
CGLSetCurrentContext(_context);
|
||||
|
||||
#ifdef _OGLDISPLAYOUTPUT_3_2_H_
|
||||
if (useContext_3_2)
|
||||
{
|
||||
_contextInfo = new OGLContextInfo_3_2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_contextInfo = new OGLContextInfo_Legacy;
|
||||
}
|
||||
|
||||
CGLSetCurrentContext(prevContext);
|
||||
|
||||
_clientData = [[MacClientSharedObject alloc] init];
|
||||
}
|
||||
|
||||
NSOpenGLContext* MacOGLClientFetchObject::GetNSContext() const
|
||||
{
|
||||
return this->_nsContext;
|
||||
}
|
||||
|
||||
CGLContextObj MacOGLClientFetchObject::GetContext() const
|
||||
{
|
||||
return this->_context;
|
||||
}
|
||||
|
||||
void MacOGLClientFetchObject::Init()
|
||||
{
|
||||
[(MacClientSharedObject *)this->_clientData setGPUFetchObject:this];
|
||||
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
CGLSetCurrentContext(_context);
|
||||
this->OGLClientFetchObject::Init();
|
||||
CGLSetCurrentContext(prevContext);
|
||||
}
|
||||
|
||||
void MacOGLClientFetchObject::SetFetchBuffers(const NDSDisplayInfo ¤tDisplayInfo)
|
||||
{
|
||||
CGLLockContext(this->_context);
|
||||
CGLSetCurrentContext(this->_context);
|
||||
this->OGLClientFetchObject::SetFetchBuffers(currentDisplayInfo);
|
||||
CGLUnlockContext(this->_context);
|
||||
}
|
||||
|
||||
void MacOGLClientFetchObject::FetchFromBufferIndex(const u8 index)
|
||||
{
|
||||
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)this->_clientData;
|
||||
this->_useCPUFilterPipeline = ([sharedViewObject isCPUFilteringNeeded]) ? true : false;
|
||||
|
||||
pthread_rwlock_rdlock([sharedViewObject rwlockFramebufferAtIndex:index]);
|
||||
|
||||
CGLLockContext(this->_context);
|
||||
CGLSetCurrentContext(this->_context);
|
||||
this->GPUClientFetchObject::FetchFromBufferIndex(index);
|
||||
CGLUnlockContext(this->_context);
|
||||
|
||||
pthread_rwlock_unlock([sharedViewObject rwlockFramebufferAtIndex:index]);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
void MacOGLDisplayView::operator delete(void *ptr)
|
||||
{
|
||||
CGLContextObj context = ((MacOGLDisplayView *)ptr)->GetContext();
|
||||
|
@ -141,33 +272,37 @@ MacOGLDisplayView::MacOGLDisplayView()
|
|||
_nsPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||
}
|
||||
|
||||
_nsContext = [[NSOpenGLContext alloc] initWithFormat:_nsPixelFormat shareContext:nil];
|
||||
_context = (CGLContextObj)[_nsContext CGLContextObj];
|
||||
_pixelFormat = (CGLPixelFormatObj)[_nsPixelFormat CGLPixelFormatObj];
|
||||
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
CGLSetCurrentContext(_context);
|
||||
|
||||
#ifdef _OGLDISPLAYOUTPUT_3_2_H_
|
||||
if (useContext_3_2)
|
||||
{
|
||||
_contextInfo = new OGLContextInfo_3_2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
_contextInfo = new OGLContextInfo_Legacy;
|
||||
}
|
||||
|
||||
CGLSetCurrentContext(prevContext);
|
||||
|
||||
_nsContext = nil;
|
||||
_context = nil;
|
||||
_willRenderToCALayer = false;
|
||||
_allowViewUpdates = false;
|
||||
}
|
||||
|
||||
void MacOGLDisplayView::Init()
|
||||
{
|
||||
this->_nsContext = [[NSOpenGLContext alloc] initWithFormat:this->_nsPixelFormat
|
||||
shareContext:((MacOGLClientFetchObject *)this->_fetchObject)->GetNSContext()];
|
||||
this->_context = (CGLContextObj)[this->_nsContext CGLContextObj];
|
||||
|
||||
CGLContextObj prevContext = CGLGetCurrentContext();
|
||||
CGLSetCurrentContext(this->_context);
|
||||
|
||||
#ifdef _OGLDISPLAYOUTPUT_3_2_H_
|
||||
GLint profileVersion = 0;
|
||||
CGLDescribePixelFormat(this->_pixelFormat, 0, kCGLPFAOpenGLProfile, &profileVersion);
|
||||
|
||||
if (profileVersion == kCGLOGLPVersion_3_2_Core)
|
||||
{
|
||||
this->_contextInfo = new OGLContextInfo_3_2;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
this->_contextInfo = new OGLContextInfo_Legacy;
|
||||
}
|
||||
|
||||
this->OGLVideoOutput::Init();
|
||||
CGLSetCurrentContext(prevContext);
|
||||
}
|
||||
|
@ -210,26 +345,6 @@ void MacOGLDisplayView::LoadHUDFont()
|
|||
CGLUnlockContext(this->_context);
|
||||
}
|
||||
|
||||
void MacOGLDisplayView::SetVideoBuffers(const uint32_t colorFormat,
|
||||
const void *videoBufferHead,
|
||||
const void *nativeBuffer0,
|
||||
const void *nativeBuffer1,
|
||||
const void *customBuffer0, const size_t customWidth0, const size_t customHeight0,
|
||||
const void *customBuffer1, const size_t customWidth1, const size_t customHeight1)
|
||||
{
|
||||
CGLLockContext(this->_context);
|
||||
CGLSetCurrentContext(this->_context);
|
||||
|
||||
this->OGLVideoOutput::SetVideoBuffers(colorFormat,
|
||||
videoBufferHead,
|
||||
nativeBuffer0,
|
||||
nativeBuffer1,
|
||||
customBuffer0, customWidth0, customHeight0,
|
||||
customBuffer1, customWidth1, customHeight1);
|
||||
|
||||
CGLUnlockContext(this->_context);
|
||||
}
|
||||
|
||||
void MacOGLDisplayView::SetUseVerticalSync(const bool useVerticalSync)
|
||||
{
|
||||
const GLint swapInt = (useVerticalSync) ? 1 : 0;
|
||||
|
@ -292,6 +407,11 @@ void MacOGLDisplayView::ProcessDisplays()
|
|||
|
||||
void MacOGLDisplayView::UpdateView()
|
||||
{
|
||||
if (!this->_allowViewUpdates)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->_willRenderToCALayer)
|
||||
{
|
||||
this->CALayerDisplay();
|
||||
|
@ -306,10 +426,28 @@ void MacOGLDisplayView::UpdateView()
|
|||
}
|
||||
}
|
||||
|
||||
void MacOGLDisplayView::FrameFinish()
|
||||
void MacOGLDisplayView::FinishFrameAtIndex(const u8 bufferIndex)
|
||||
{
|
||||
CGLLockContext(this->_context);
|
||||
CGLSetCurrentContext(this->_context);
|
||||
this->OGLVideoOutput::FrameFinish();
|
||||
this->OGLVideoOutput::FinishFrameAtIndex(bufferIndex);
|
||||
CGLUnlockContext(this->_context);
|
||||
}
|
||||
|
||||
void MacOGLDisplayView::LockDisplayTextures()
|
||||
{
|
||||
const GPUClientFetchObject &fetchObj = this->GetFetchObject();
|
||||
const u8 bufferIndex = this->_emuDisplayInfo.bufferIndex;
|
||||
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)fetchObj.GetClientData();
|
||||
|
||||
pthread_rwlock_rdlock([sharedViewObject rwlockFramebufferAtIndex:bufferIndex]);
|
||||
}
|
||||
|
||||
void MacOGLDisplayView::UnlockDisplayTextures()
|
||||
{
|
||||
const GPUClientFetchObject &fetchObj = this->GetFetchObject();
|
||||
const u8 bufferIndex = this->_emuDisplayInfo.bufferIndex;
|
||||
MacClientSharedObject *sharedViewObject = (MacClientSharedObject *)fetchObj.GetClientData();
|
||||
|
||||
pthread_rwlock_unlock([sharedViewObject rwlockFramebufferAtIndex:bufferIndex]);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#import "inputPrefsView.h"
|
||||
|
||||
#import "cocoa_core.h"
|
||||
#import "cocoa_GPU.h"
|
||||
#import "cocoa_file.h"
|
||||
#import "cocoa_firmware.h"
|
||||
#import "cocoa_globals.h"
|
||||
|
@ -178,6 +179,14 @@
|
|||
|
||||
// Init the DS emulation core.
|
||||
CocoaDSCore *newCore = [[[CocoaDSCore alloc] init] autorelease];
|
||||
MacClientSharedObject *sharedViewObject = [[newCore cdsGPU] sharedData];
|
||||
[NSThread detachNewThreadSelector:@selector(runThread:) toTarget:sharedViewObject withObject:nil];
|
||||
|
||||
// Wait until the SPU is finished starting up.
|
||||
while ([sharedViewObject thread] == nil)
|
||||
{
|
||||
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
|
||||
}
|
||||
|
||||
// Init the DS controller.
|
||||
CocoaDSController *newController = [[[CocoaDSController alloc] init] autorelease];
|
||||
|
@ -683,6 +692,9 @@
|
|||
// If this is the last window in the list, make this window key and main.
|
||||
// Otherwise, just order the window to the front so that the windows will
|
||||
// stack in a deterministic order.
|
||||
[[windowController view] setAllowViewUpdates:YES];
|
||||
[[windowController cdsVideoOutput] handleReloadReprocessRedraw];
|
||||
|
||||
if (windowProperties == [windowPropertiesList lastObject])
|
||||
{
|
||||
[[windowController window] makeKeyAndOrderFront:self];
|
||||
|
@ -693,9 +705,6 @@
|
|||
[[windowController window] orderFront:self];
|
||||
}
|
||||
|
||||
// Draw the display view now so that we guarantee that its drawn at least once.
|
||||
[CocoaDSUtil messageSendOneWay:[[windowController cdsVideoOutput] receivePort] msgID:MESSAGE_RELOAD_REPROCESS_REDRAW];
|
||||
|
||||
// If this window is set to full screen mode, its associated screen index must
|
||||
// exist. If not, this window will not enter full screen mode. This is necessary,
|
||||
// since the user's screen configuration could change in between app launches,
|
||||
|
@ -704,8 +713,6 @@
|
|||
([[NSScreen screens] indexOfObject:[[windowController window] screen]] == screenIndex))
|
||||
{
|
||||
[windowController toggleFullScreenDisplay:self];
|
||||
[[windowController window] makeKeyAndOrderFront:self];
|
||||
[[windowController window] makeMainWindow];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue