diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index aad54f8b7..e016d1318 100755 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -9180,6 +9180,8 @@ bool GPUSubsystem::Change3DRendererByID(int rendererID) Render3DError error = newRenderer->SetFramebufferSize(GPU->GetCustomFramebufferWidth(), GPU->GetCustomFramebufferHeight()); if (error != RENDER3DERROR_NOERR) { + newRenderInterface->NDS_3D_Close(); + printf("GPU: 3D framebuffer resize error. 3D rendering will be disabled for this renderer. (Error code = %d)\n", (int)error); return result; } diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 0578569d3..01eb45041 100755 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -105,7 +105,7 @@ void ENDGL() bool (*oglrender_init)() = NULL; bool (*oglrender_beginOpenGL)() = NULL; void (*oglrender_endOpenGL)() = NULL; -bool (*oglrender_framebufferDidResizeCallback)(size_t w, size_t h) = NULL; +bool (*oglrender_framebufferDidResizeCallback)(const bool isFBOSupported, size_t w, size_t h) = NULL; void (*OGLLoadEntryPoints_3_2_Func)() = NULL; void (*OGLCreateRenderer_3_2_Func)(OpenGLRenderer **rendererPtr) = NULL; @@ -5368,16 +5368,18 @@ Render3DError OpenGLRenderer_1_2::RenderFlush(bool willFlushBuffer32, bool willF Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h) { + Render3DError error = OGLERROR_NOERR; OGLRenderRef &OGLRef = *this->ref; if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT) { - return OGLERROR_NOERR; + return error; } if (!BEGINGL()) { - return OGLERROR_BEGINGL_FAILED; + error = OGLERROR_BEGINGL_FAILED; + return error; } glFinish(); @@ -5462,13 +5464,17 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h) if (oglrender_framebufferDidResizeCallback != NULL) { - oglrender_framebufferDidResizeCallback(w, h); + bool clientResizeSuccess = oglrender_framebufferDidResizeCallback(this->isFBOSupported, w, h); + if (!clientResizeSuccess) + { + error = OGLERROR_CLIENT_RESIZE_ERROR; + } } glFinish(); ENDGL(); - return OGLERROR_NOERR; + return error; } Render3DError OpenGLRenderer_2_0::InitFinalRenderStates(const std::set *oglExtensionSet) diff --git a/desmume/src/OGLRender.h b/desmume/src/OGLRender.h index 0644e6843..def9567a4 100755 --- a/desmume/src/OGLRender.h +++ b/desmume/src/OGLRender.h @@ -314,6 +314,7 @@ enum OGLErrorCode OGLERROR_DRIVER_VERSION_TOO_OLD, OGLERROR_BEGINGL_FAILED, + OGLERROR_CLIENT_RESIZE_ERROR, OGLERROR_FEATURE_UNSUPPORTED, OGLERROR_VBO_UNSUPPORTED, @@ -580,7 +581,7 @@ extern bool (*oglrender_beginOpenGL)(); extern void (*oglrender_endOpenGL)(); //This is called by OGLRender whenever the framebuffer is resized. -extern bool (*oglrender_framebufferDidResizeCallback)(size_t w, size_t h); +extern bool (*oglrender_framebufferDidResizeCallback)(const bool isFBOSupported, size_t w, size_t h); // Helper functions for calling the above function pointers at the // beginning and ending of OpenGL commands. diff --git a/desmume/src/OGLRender_3_2.cpp b/desmume/src/OGLRender_3_2.cpp index fc0b2b925..0642d8e16 100755 --- a/desmume/src/OGLRender_3_2.cpp +++ b/desmume/src/OGLRender_3_2.cpp @@ -2590,16 +2590,18 @@ Render3DError OpenGLRenderer_3_2::SetupTexture(const POLY &thePoly, size_t polyR Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h) { + Render3DError error = OGLERROR_NOERR; OGLRenderRef &OGLRef = *this->ref; if (w < GPU_FRAMEBUFFER_NATIVE_WIDTH || h < GPU_FRAMEBUFFER_NATIVE_HEIGHT) { - return OGLERROR_NOERR; + return error; } if (!BEGINGL()) { - return OGLERROR_BEGINGL_FAILED; + error = OGLERROR_BEGINGL_FAILED; + return error; } glFinish(); @@ -2656,8 +2658,8 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h) if (this->isSampleShadingSupported) { - Render3DError error = this->CreateMSGeometryZeroDstAlphaProgram(MSGeometryZeroDstAlphaPixelMaskVtxShader_150, MSGeometryZeroDstAlphaPixelMaskFragShader_150); - this->willUsePerSampleZeroDstPass = (error == OGLERROR_NOERR); + Render3DError shaderError = this->CreateMSGeometryZeroDstAlphaProgram(MSGeometryZeroDstAlphaPixelMaskVtxShader_150, MSGeometryZeroDstAlphaPixelMaskFragShader_150); + this->willUsePerSampleZeroDstPass = (shaderError == OGLERROR_NOERR); } // Call ResizeMultisampledFBOs() after _framebufferWidth and _framebufferHeight are set @@ -2667,13 +2669,17 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h) if (oglrender_framebufferDidResizeCallback != NULL) { - oglrender_framebufferDidResizeCallback(w, h); + bool clientResizeSuccess = oglrender_framebufferDidResizeCallback(this->isFBOSupported, w, h); + if (!clientResizeSuccess) + { + error = OGLERROR_CLIENT_RESIZE_ERROR; + } } glFinish(); ENDGL(); - return OGLERROR_NOERR; + return error; } Render3DError OpenGLRenderer_3_2::RenderPowerOff() diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.h b/desmume/src/frontend/cocoa/cocoa_GPU.h index b3b93ec15..86dd4efe8 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.h +++ b/desmume/src/frontend/cocoa/cocoa_GPU.h @@ -206,7 +206,7 @@ CVReturn MacDisplayLinkCallback(CVDisplayLinkRef displayLink, bool OSXOpenGLRendererInit(); bool OSXOpenGLRendererBegin(); void OSXOpenGLRendererEnd(); -bool OSXOpenGLRendererFramebufferDidResize(size_t w, size_t h); +bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h); bool CreateOpenGLRenderer(); void DestroyOpenGLRenderer(); @@ -214,7 +214,7 @@ void RequestOpenGLRenderer_3_2(bool request_3_2); void SetOpenGLRendererFunctions(bool (*initFunction)(), bool (*beginOGLFunction)(), void (*endOGLFunction)(), - bool (*resizeOGLFunction)(size_t w, size_t h)); + bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h)); #ifdef __cplusplus } diff --git a/desmume/src/frontend/cocoa/cocoa_GPU.mm b/desmume/src/frontend/cocoa/cocoa_GPU.mm index 04a3f4ec0..cd09a3392 100644 --- a/desmume/src/frontend/cocoa/cocoa_GPU.mm +++ b/desmume/src/frontend/cocoa/cocoa_GPU.mm @@ -1795,36 +1795,43 @@ void OSXOpenGLRendererEnd() #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -bool OSXOpenGLRendererFramebufferDidResize(size_t w, size_t h) +bool OSXOpenGLRendererFramebufferDidResize(const bool isFBOSupported, size_t w, size_t h) { bool result = false; - // Create a PBuffer for legacy contexts since the availability of FBOs - // is not guaranteed. - if (OGLCreateRenderer_3_2_Func == NULL) + if (isFBOSupported) { - CGLPBufferObj newPBuffer = NULL; - - CGLCreatePBuffer(w, h, GL_TEXTURE_2D, GL_RGBA, 0, &newPBuffer); - - if (newPBuffer == NULL) - { - return result; - } - else - { - GLint virtualScreenID = 0; - CGLGetVirtualScreen(OSXOpenGLRendererContext, &virtualScreenID); - CGLSetPBuffer(OSXOpenGLRendererContext, newPBuffer, 0, 0, virtualScreenID); - } - - CGLPBufferObj oldPBuffer = OSXOpenGLRendererPBuffer; - OSXOpenGLRendererPBuffer = newPBuffer; - CGLReleasePBuffer(oldPBuffer); - result = true; + return result; } + if (IsOSXVersionSupported(10, 13, 0)) + { + printf("Mac OpenGL: P-Buffers cannot be created on macOS v10.13 High Sierra and later.\n"); + return result; + } + + // Create a PBuffer if FBOs are not supported. + CGLPBufferObj newPBuffer = NULL; + CGLError error = CGLCreatePBuffer(w, h, GL_TEXTURE_2D, GL_RGBA, 0, &newPBuffer); + + if ( (newPBuffer == NULL) || (error != kCGLNoError) ) + { + printf("Mac OpenGL: ERROR - Could not create the P-Buffer: %s\n", CGLErrorString(error)); + return result; + } + else + { + GLint virtualScreenID = 0; + CGLGetVirtualScreen(OSXOpenGLRendererContext, &virtualScreenID); + CGLSetPBuffer(OSXOpenGLRendererContext, newPBuffer, 0, 0, virtualScreenID); + } + + CGLPBufferObj oldPBuffer = OSXOpenGLRendererPBuffer; + OSXOpenGLRendererPBuffer = newPBuffer; + CGLReleasePBuffer(oldPBuffer); + + result = true; return result; } @@ -1892,11 +1899,8 @@ void DestroyOpenGLRenderer() return; } - if (OGLCreateRenderer_3_2_Func == NULL) - { - CGLReleasePBuffer(OSXOpenGLRendererPBuffer); - OSXOpenGLRendererPBuffer = NULL; - } + CGLReleasePBuffer(OSXOpenGLRendererPBuffer); + OSXOpenGLRendererPBuffer = NULL; CGLReleaseContext(OSXOpenGLRendererContext); OSXOpenGLRendererContext = NULL; @@ -1921,7 +1925,7 @@ void RequestOpenGLRenderer_3_2(bool request_3_2) void SetOpenGLRendererFunctions(bool (*initFunction)(), bool (*beginOGLFunction)(), void (*endOGLFunction)(), - bool (*resizeOGLFunction)(size_t w, size_t h)) + bool (*resizeOGLFunction)(const bool isFBOSupported, size_t w, size_t h)) { oglrender_init = initFunction; oglrender_beginOpenGL = beginOGLFunction;