Cocoa Port: Update OpenGL renderer integration code to reflect current design patterns.

This commit is contained in:
rogerman 2024-07-26 14:56:36 -07:00
parent 4c90c2d9ee
commit 2f177d19a2
3 changed files with 193 additions and 127 deletions

View File

@ -272,18 +272,14 @@ extern "C"
{ {
#endif #endif
bool OSXOpenGLRendererInit(); bool cgl_initOpenGL_StandardAuto();
bool OSXOpenGLRendererBegin(); bool cgl_initOpenGL_LegacyAuto();
void OSXOpenGLRendererEnd(); bool cgl_initOpenGL_3_2_CoreProfile();
bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h);
bool CreateOpenGLRenderer(); void cgl_deinitOpenGL();
void DestroyOpenGLRenderer(); bool cgl_beginOpenGL();
void RequestOpenGLRenderer_3_2(bool request_3_2); void cgl_endOpenGL();
void SetOpenGLRendererFunctions(bool (*initFunction)(), bool cgl_framebufferDidResizeCallback(const bool isFBOSupported, size_t w, size_t h);
bool (*beginOGLFunction)(),
void (*endOGLFunction)(),
bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h));
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -118,11 +118,17 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
isCPUCoreCountAuto = NO; isCPUCoreCountAuto = NO;
_needRestoreRender3DLock = NO; _needRestoreRender3DLock = NO;
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit, oglrender_init = &cgl_initOpenGL_StandardAuto;
&OSXOpenGLRendererBegin, oglrender_deinit = &cgl_deinitOpenGL;
&OSXOpenGLRendererEnd, oglrender_beginOpenGL = &cgl_beginOpenGL;
&OSXOpenGLRendererFramebufferDidResize); oglrender_endOpenGL = &cgl_endOpenGL;
oglrender_framebufferDidResizeCallback = &cgl_framebufferDidResizeCallback;
#ifdef OGLRENDER_3_2_H
OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
#endif
#ifdef PORT_VERSION_OS_X_APP #ifdef PORT_VERSION_OS_X_APP
gpuEvent = new GPUEventHandlerAsync; gpuEvent = new GPUEventHandlerAsync;
@ -169,10 +175,10 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
openglDeviceMaxMultisamples = 0; openglDeviceMaxMultisamples = 0;
render3DMultisampleSizeString = @"Off"; render3DMultisampleSizeString = @"Off";
bool isTempContextCreated = OSXOpenGLRendererInit(); bool isTempContextCreated = cgl_initOpenGL_StandardAuto();
if (isTempContextCreated) if (isTempContextCreated)
{ {
OSXOpenGLRendererBegin(); cgl_beginOpenGL();
GLint maxSamplesOGL = 0; GLint maxSamplesOGL = 0;
@ -184,8 +190,8 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
openglDeviceMaxMultisamples = maxSamplesOGL; openglDeviceMaxMultisamples = maxSamplesOGL;
OSXOpenGLRendererEnd(); cgl_endOpenGL();
DestroyOpenGLRenderer(); cgl_deinitOpenGL();
} }
return self; return self;
@ -371,6 +377,10 @@ GPU3DInterface *core3DList[GPU_3D_RENDERER_COUNT+1] = {
puts("DeSmuME: Invalid 3D renderer chosen; falling back to SoftRasterizer."); puts("DeSmuME: Invalid 3D renderer chosen; falling back to SoftRasterizer.");
rendererID = CORE3DLIST_SWRASTERIZE; rendererID = CORE3DLIST_SWRASTERIZE;
} }
else if (rendererID == CORE3DLIST_OPENGL)
{
oglrender_init = &cgl_initOpenGL_StandardAuto;
}
gpuEvent->ApplyRender3DSettingsLock(); gpuEvent->ApplyRender3DSettingsLock();
GPU->Set3DRendererByID((int)rendererID); GPU->Set3DRendererByID((int)rendererID);
@ -1811,22 +1821,183 @@ bool GPUEventHandlerAsync::GetRender3DNeedsFinish()
#pragma mark - #pragma mark -
#if !defined(MAC_OS_X_VERSION_10_7)
#define kCGLOGLPVersion_Legacy 0x1000
#define kCGLOGLPVersion_3_2_Core 0x3200
#define kCGLOGLPVersion_GL3_Core 0x3200
#endif
#if !defined(MAC_OS_X_VERSION_10_9)
#define kCGLOGLPVersion_GL4_Core 0x4100
#endif
CGLContextObj OSXOpenGLRendererContext = NULL; CGLContextObj OSXOpenGLRendererContext = NULL;
CGLContextObj OSXOpenGLRendererContextPrev = NULL; CGLContextObj OSXOpenGLRendererContextPrev = NULL;
SILENCE_DEPRECATION_MACOS_10_7( CGLPBufferObj OSXOpenGLRendererPBuffer = NULL ); SILENCE_DEPRECATION_MACOS_10_7( CGLPBufferObj OSXOpenGLRendererPBuffer = NULL );
bool OSXOpenGLRendererInit() static bool __cgl_initOpenGL(const int requestedProfile)
{ {
bool isContextCreated = (OSXOpenGLRendererContext != NULL); bool result = false;
CACHE_ALIGN char ctxString[16] = {0};
if (requestedProfile == kCGLOGLPVersion_GL4_Core)
{
strncpy(ctxString, "CGL 4.1", sizeof(ctxString));
}
else if (requestedProfile == kCGLOGLPVersion_3_2_Core)
{
strncpy(ctxString, "CGL 3.2", sizeof(ctxString));
}
else
{
strncpy(ctxString, "CGL Legacy", sizeof(ctxString));
}
if (OSXOpenGLRendererContext != NULL)
{
result = true;
return result;
}
CGLPixelFormatAttribute attrs[] = {
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)0,
kCGLPFAStencilSize, (CGLPixelFormatAttribute)0,
kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)0,
kCGLPFAAccelerated,
(CGLPixelFormatAttribute)0
};
if (requestedProfile == kCGLOGLPVersion_GL4_Core)
{
if (IsOSXVersionSupported(10, 9, 0))
{
attrs[9] = (CGLPixelFormatAttribute)requestedProfile;
}
else
{
fprintf(stderr, "%s: Your version of OS X is too old to support this profile.\n", ctxString);
return result;
}
}
else if (requestedProfile == kCGLOGLPVersion_3_2_Core)
{
// As of 2021/09/03, testing has shown that macOS v10.7's OpenGL 3.2 shader
// compiler isn't very reliable, and so we're going to require macOS v10.8
// instead, which at least has a working shader compiler for OpenGL 3.2.
if (IsOSXVersionSupported(10, 8, 0))
{
attrs[9] = (CGLPixelFormatAttribute)requestedProfile;
}
else
{
fprintf(stderr, "%s: Your version of OS X is too old to support this profile.\n", ctxString);
return result;
}
}
else
{
if (IsOSXVersionSupported(10, 7, 0))
{
attrs[9] = (CGLPixelFormatAttribute)kCGLOGLPVersion_Legacy;
}
else
{
attrs[5] = (CGLPixelFormatAttribute)24; // Since the default framebuffer may be needed, depth bits are also needed.
attrs[7] = (CGLPixelFormatAttribute)8; // Since the default framebuffer may be needed, stencil bits are also needed.
attrs[8] = (CGLPixelFormatAttribute)kCGLPFAAccelerated;
attrs[10] = (CGLPixelFormatAttribute)0;
}
}
CGLError error = kCGLNoError;
CGLPixelFormatObj cglPixFormat = NULL;
CGLContextObj newContext = NULL;
GLint virtualScreenCount = 0;
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
// Remove the HW rendering requirement and try again. Note that this will
// result in SW rendering, which will cause a substantial speed hit.
if (attrs[8] == kCGLPFAAccelerated)
{
attrs[8] = (CGLPixelFormatAttribute)0;
}
else
{
attrs[10] = (CGLPixelFormatAttribute)0;
}
error = CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (error != kCGLNoError)
{
fprintf(stderr, "%s: Failed to create the pixel format structure: %i\n", ctxString, (int)error);
return result;
}
}
error = CGLCreateContext(cglPixFormat, NULL, &newContext);
if (error != kCGLNoError)
{
CGLReleasePixelFormat(cglPixFormat);
fprintf(stderr, "%s: Failed to create an OpenGL context: %i\n", ctxString, (int)error);
return result;
}
CGLReleasePixelFormat(cglPixFormat);
OSXOpenGLRendererContext = newContext;
printf("%s: OpenGL context creation successful.\n", ctxString);
result = true;
return result;
}
bool cgl_initOpenGL_StandardAuto()
{
bool isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_GL4_Core);
if (!isContextCreated) if (!isContextCreated)
{ {
isContextCreated = CreateOpenGLRenderer(); isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_3_2_Core);
}
if (!isContextCreated)
{
isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_Legacy);
} }
return isContextCreated; return isContextCreated;
} }
bool OSXOpenGLRendererBegin() bool cgl_initOpenGL_LegacyAuto()
{
return __cgl_initOpenGL(kCGLOGLPVersion_Legacy);
}
bool cgl_initOpenGL_3_2_CoreProfile()
{
return __cgl_initOpenGL(kCGLOGLPVersion_3_2_Core);
}
void cgl_deinitOpenGL()
{
if (OSXOpenGLRendererContext == NULL)
{
return;
}
CGLSetCurrentContext(NULL);
SILENCE_DEPRECATION_MACOS_10_7( CGLReleasePBuffer(OSXOpenGLRendererPBuffer) );
OSXOpenGLRendererPBuffer = NULL;
CGLReleaseContext(OSXOpenGLRendererContext);
OSXOpenGLRendererContext = NULL;
OSXOpenGLRendererContextPrev = NULL;
}
bool cgl_beginOpenGL()
{ {
OSXOpenGLRendererContextPrev = CGLGetCurrentContext(); OSXOpenGLRendererContextPrev = CGLGetCurrentContext();
CGLSetCurrentContext(OSXOpenGLRendererContext); CGLSetCurrentContext(OSXOpenGLRendererContext);
@ -1834,7 +2005,7 @@ bool OSXOpenGLRendererBegin()
return true; return true;
} }
void OSXOpenGLRendererEnd() void cgl_endOpenGL()
{ {
#ifndef PORT_VERSION_OS_X_APP #ifndef PORT_VERSION_OS_X_APP
// The OpenEmu plug-in needs the context reset after 3D rendering since OpenEmu's context // The OpenEmu plug-in needs the context reset after 3D rendering since OpenEmu's context
@ -1845,7 +2016,7 @@ void OSXOpenGLRendererEnd()
#endif #endif
} }
bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h) bool cgl_framebufferDidResizeCallback(const bool isFBOSupported, size_t w, size_t h)
{ {
bool result = false; bool result = false;
@ -1884,100 +2055,3 @@ bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w,
result = true; result = true;
return result; return result;
} }
bool CreateOpenGLRenderer()
{
bool result = false;
bool useContext_3_2 = false;
CGLPixelFormatObj cglPixFormat = NULL;
CGLContextObj newContext = NULL;
GLint virtualScreenCount = 0;
CGLPixelFormatAttribute attrs[] = {
kCGLPFAColorSize, (CGLPixelFormatAttribute)24,
kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8,
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
kCGLPFAStencilSize, (CGLPixelFormatAttribute)8,
kCGLPFAAccelerated,
(CGLPixelFormatAttribute)0, (CGLPixelFormatAttribute)0,
(CGLPixelFormatAttribute)0
};
// If we can support a 3.2 Core Profile context, then request that in our
// pixel format attributes.
#ifdef MAC_OS_X_VERSION_10_7
// As of 2021/09/03, testing has shown that macOS v10.7's OpenGL 3.2 shader
// compiler isn't very reliable, and so we're going to require macOS v10.8
// instead, which at least has a working shader compiler for OpenGL 3.2.
useContext_3_2 = IsOSXVersionSupported(10, 8, 0);
if (useContext_3_2)
{
attrs[9] = kCGLPFAOpenGLProfile;
attrs[10] = (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core;
}
#endif
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
// Remove the HW rendering requirement and try again. Note that this will
// result in SW rendering, which will cause a substantial speed hit.
attrs[8] = (CGLPixelFormatAttribute)0;
CGLChoosePixelFormat(attrs, &cglPixFormat, &virtualScreenCount);
if (cglPixFormat == NULL)
{
return result;
}
}
CGLCreateContext(cglPixFormat, NULL, &newContext);
CGLReleasePixelFormat(cglPixFormat);
RequestOpenGLRenderer_3_2(useContext_3_2);
OSXOpenGLRendererContext = newContext;
result = true;
return result;
}
void DestroyOpenGLRenderer()
{
if (OSXOpenGLRendererContext == NULL)
{
return;
}
OSXOpenGLRendererEnd();
SILENCE_DEPRECATION_MACOS_10_7( CGLReleasePBuffer(OSXOpenGLRendererPBuffer) );
OSXOpenGLRendererPBuffer = NULL;
CGLReleaseContext(OSXOpenGLRendererContext);
OSXOpenGLRendererContext = NULL;
OSXOpenGLRendererContextPrev = NULL;
}
void RequestOpenGLRenderer_3_2(bool request_3_2)
{
#ifdef OGLRENDER_3_2_H
if (request_3_2)
{
OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
return;
}
#endif
OGLLoadEntryPoints_3_2_Func = NULL;
OGLCreateRenderer_3_2_Func = NULL;
}
void SetOpenGLRendererFunctions(bool (*initFunction)(),
bool (*beginOGLFunction)(),
void (*endOGLFunction)(),
bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h))
{
oglrender_init = initFunction;
oglrender_beginOpenGL = beginOGLFunction;
oglrender_endOpenGL = endOGLFunction;
oglrender_framebufferDidResizeCallback = resizeOGLFunction;
}

View File

@ -226,10 +226,6 @@ volatile bool execute = true;
delete execControl; delete execControl;
NDS_DeInit(); NDS_DeInit();
// We must call DestroyOpenGLRenderer() after NDS_Init() because we need to wait for
// the OpenGL renderer to finish before we destroy its associated context.
DestroyOpenGLRenderer();
[super dealloc]; [super dealloc];
} }