Skip to content

Commit

Permalink
Cocoa Port: Update OpenGL renderer integration code to reflect curren…
Browse files Browse the repository at this point in the history
…t design patterns.
  • Loading branch information
rogerman committed Jul 26, 2024
1 parent 4c90c2d commit 2f177d1
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 128 deletions.
20 changes: 8 additions & 12 deletions desmume/src/frontend/cocoa/cocoa_GPU.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,18 +272,14 @@ extern "C"
{
#endif

bool OSXOpenGLRendererInit();
bool OSXOpenGLRendererBegin();
void OSXOpenGLRendererEnd();
bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h);

bool CreateOpenGLRenderer();
void DestroyOpenGLRenderer();
void RequestOpenGLRenderer_3_2(bool request_3_2);
void SetOpenGLRendererFunctions(bool (*initFunction)(),
bool (*beginOGLFunction)(),
void (*endOGLFunction)(),
bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h));
bool cgl_initOpenGL_StandardAuto();
bool cgl_initOpenGL_LegacyAuto();
bool cgl_initOpenGL_3_2_CoreProfile();

void cgl_deinitOpenGL();
bool cgl_beginOpenGL();
void cgl_endOpenGL();
bool cgl_framebufferDidResizeCallback(const bool isFBOSupported, size_t w, size_t h);

#ifdef __cplusplus
}
Expand Down
298 changes: 186 additions & 112 deletions desmume/src/frontend/cocoa/cocoa_GPU.mm
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,17 @@ - (id)init

isCPUCoreCountAuto = NO;
_needRestoreRender3DLock = NO;

SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
&OSXOpenGLRendererBegin,
&OSXOpenGLRendererEnd,
&OSXOpenGLRendererFramebufferDidResize);

oglrender_init = &cgl_initOpenGL_StandardAuto;
oglrender_deinit = &cgl_deinitOpenGL;
oglrender_beginOpenGL = &cgl_beginOpenGL;
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
gpuEvent = new GPUEventHandlerAsync;
Expand Down Expand Up @@ -169,10 +175,10 @@ - (id)init
openglDeviceMaxMultisamples = 0;
render3DMultisampleSizeString = @"Off";

bool isTempContextCreated = OSXOpenGLRendererInit();
bool isTempContextCreated = cgl_initOpenGL_StandardAuto();
if (isTempContextCreated)
{
OSXOpenGLRendererBegin();
cgl_beginOpenGL();

GLint maxSamplesOGL = 0;

Expand All @@ -184,8 +190,8 @@ - (id)init

openglDeviceMaxMultisamples = maxSamplesOGL;

OSXOpenGLRendererEnd();
DestroyOpenGLRenderer();
cgl_endOpenGL();
cgl_deinitOpenGL();
}

return self;
Expand Down Expand Up @@ -371,6 +377,10 @@ - (void) setRender3DRenderingEngine:(NSInteger)rendererID
puts("DeSmuME: Invalid 3D renderer chosen; falling back to SoftRasterizer.");
rendererID = CORE3DLIST_SWRASTERIZE;
}
else if (rendererID == CORE3DLIST_OPENGL)
{
oglrender_init = &cgl_initOpenGL_StandardAuto;
}

gpuEvent->ApplyRender3DSettingsLock();
GPU->Set3DRendererByID((int)rendererID);
Expand Down Expand Up @@ -1811,30 +1821,191 @@ static CVReturn MacDisplayLinkCallback(CVDisplayLinkRef displayLink,

#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 OSXOpenGLRendererContextPrev = 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)
{
isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_3_2_Core);
}

if (!isContextCreated)
{
isContextCreated = CreateOpenGLRenderer();
isContextCreated = __cgl_initOpenGL(kCGLOGLPVersion_Legacy);
}

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();
CGLSetCurrentContext(OSXOpenGLRendererContext);

return true;
}

void OSXOpenGLRendererEnd()
void cgl_endOpenGL()
{
#ifndef PORT_VERSION_OS_X_APP
// The OpenEmu plug-in needs the context reset after 3D rendering since OpenEmu's context
Expand All @@ -1845,7 +2016,7 @@ void OSXOpenGLRendererEnd()
#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;

Expand Down Expand Up @@ -1884,100 +2055,3 @@ bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w,
result = true;
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;
}
Loading

0 comments on commit 2f177d1

Please sign in to comment.