3812: Make init/shutdown when GL processor creation fails safer r=def- a=Jupeyy

Especially with GL 3.3, which has a shutdown command implemented, it should only get called, if it actually created the the backend stuff.

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Jupeyy <jupjopjap@gmail.com>
This commit is contained in:
bors[bot] 2021-05-07 07:43:27 +00:00 committed by GitHub
commit 23b8ad5cc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 73 additions and 60 deletions

View file

@ -310,49 +310,10 @@ GfxOpenGLMessageCallback(GLenum source,
}
#endif
void CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand)
bool CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand)
{
m_IsOpenGLES = pCommand->m_RequestedBackend == BACKEND_TYPE_OPENGL_ES;
// set some default settings
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
#ifndef BACKEND_GL_MODERN_API
if(!IsNewApi())
{
glAlphaFunc(GL_GREATER, 0);
glEnable(GL_ALPHA_TEST);
}
#endif
glDepthMask(0);
#ifndef BACKEND_AS_OPENGL_ES
if(g_Config.m_DbgGfx)
{
if(GLEW_KHR_debug || GLEW_ARB_debug_output)
{
// During init, enable debug output
if(GLEW_KHR_debug)
{
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(GfxOpenGLMessageCallback, 0);
}
else if(GLEW_ARB_debug_output)
{
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(GfxOpenGLMessageCallback, 0);
}
dbg_msg("gfx", "Enabled OpenGL debug mode");
}
else
dbg_msg("gfx", "Requested OpenGL debug mode, but the driver does not support the required extension");
}
#endif
const char *pVendorString = (const char *)glGetString(GL_VENDOR);
dbg_msg("opengl", "Vendor string: %s", pVendorString);
@ -583,11 +544,58 @@ void CCommandProcessorFragment_OpenGL::InitOpenGL(const SCommand_Init *pCommand)
pCommand->m_pCapabilities->m_NPOTTextures = true;
}
}
if(*pCommand->m_pInitError != -2)
{
// set some default settings
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
#ifndef BACKEND_GL_MODERN_API
if(!IsNewApi())
{
glAlphaFunc(GL_GREATER, 0);
glEnable(GL_ALPHA_TEST);
}
#endif
glDepthMask(0);
#ifndef BACKEND_AS_OPENGL_ES
if(g_Config.m_DbgGfx)
{
if(GLEW_KHR_debug || GLEW_ARB_debug_output)
{
// During init, enable debug output
if(GLEW_KHR_debug)
{
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(GfxOpenGLMessageCallback, 0);
}
else if(GLEW_ARB_debug_output)
{
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(GfxOpenGLMessageCallback, 0);
}
dbg_msg("gfx", "Enabled OpenGL debug mode");
}
else
dbg_msg("gfx", "Requested OpenGL debug mode, but the driver does not support the required extension");
}
#endif
return true;
}
else
return false;
}
void CCommandProcessorFragment_OpenGL::Cmd_Init(const SCommand_Init *pCommand)
bool CCommandProcessorFragment_OpenGL::Cmd_Init(const SCommand_Init *pCommand)
{
InitOpenGL(pCommand);
if(!InitOpenGL(pCommand))
return false;
m_pTextureMemoryUsage = pCommand->m_pTextureMemoryUsage;
m_pTextureMemoryUsage->store(0, std::memory_order_relaxed);
@ -613,6 +621,8 @@ void CCommandProcessorFragment_OpenGL::Cmd_Init(const SCommand_Init *pCommand)
m_LastBlendMode = CCommandBuffer::BLEND_ALPHA;
m_LastClipEnable = false;
return true;
}
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand)
@ -1584,9 +1594,10 @@ bool CCommandProcessorFragment_OpenGL2::IsTileMapAnalysisSucceeded()
return NoError;
}
void CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand)
bool CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand)
{
CCommandProcessorFragment_OpenGL::Cmd_Init(pCommand);
if(!CCommandProcessorFragment_OpenGL::Cmd_Init(pCommand))
return false;
m_OpenGLTextureLodBIAS = g_Config.m_GfxOpenGLTextureLODBIAS;
@ -1747,7 +1758,11 @@ void CCommandProcessorFragment_OpenGL2::Cmd_Init(const SCommand_Init *pCommand)
pCommand->m_pCapabilities->m_ContextMajor = 1;
pCommand->m_pCapabilities->m_ContextMinor = 5;
pCommand->m_pCapabilities->m_ContextPatch = 0;
return false;
}
return true;
}
void CCommandProcessorFragment_OpenGL2::Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand)

View file

@ -74,7 +74,7 @@ protected:
bool IsTexturedState(const CCommandBuffer::SState &State);
static bool Texture2DTo3D(void *pImageBuffer, int ImageWidth, int ImageHeight, int ImageColorChannelCount, int SplitCountWidth, int SplitCountHeight, void *pTarget3DImageData, int &Target3DImageWidth, int &Target3DImageHeight);
void InitOpenGL(const SCommand_Init *pCommand);
bool InitOpenGL(const SCommand_Init *pCommand);
void SetState(const CCommandBuffer::SState &State, bool Use2DArrayTexture = false);
virtual bool IsNewApi() { return false; }
@ -84,7 +84,7 @@ protected:
static int TexFormatToImageColorChannelCount(int TexFormat);
static void *Resize(int Width, int Height, int NewWidth, int NewHeight, int Format, const unsigned char *pData);
virtual void Cmd_Init(const SCommand_Init *pCommand);
virtual bool Cmd_Init(const SCommand_Init *pCommand);
virtual void Cmd_Shutdown(const SCommand_Shutdown *pCommand) {}
virtual void Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand);
virtual void Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand);
@ -165,7 +165,7 @@ protected:
void SetState(const CCommandBuffer::SState &State, CGLSLTWProgram *pProgram, bool Use2DArrayTextures = false);
#ifndef BACKEND_GL_MODERN_API
void Cmd_Init(const SCommand_Init *pCommand) override;
bool Cmd_Init(const SCommand_Init *pCommand) override;
void Cmd_RenderTex3D(const CCommandBuffer::SCommand_RenderTex3D *pCommand) override;

View file

@ -67,9 +67,10 @@ void CCommandProcessorFragment_OpenGL3_3::InitPrimExProgram(CGLSLPrimitiveExProg
pProgram->SetUniformVec2(pProgram->m_LocCenter, 1, Center);
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand)
bool CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand)
{
InitOpenGL(pCommand);
if(!InitOpenGL(pCommand))
return false;
m_OpenGLTextureLodBIAS = g_Config.m_GfxOpenGLTextureLODBIAS;
@ -483,6 +484,8 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_Init(const SCommand_Init *pCommand
// fix the alignment to allow even 1byte changes, e.g. for alpha components
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
return true;
}
void CCommandProcessorFragment_OpenGL3_3::Cmd_Shutdown(const SCommand_Shutdown *pCommand)

View file

@ -81,7 +81,7 @@ protected:
void UploadStreamBufferData(unsigned int PrimitiveType, const void *pVertices, size_t VertSize, unsigned int PrimitiveCount, bool AsTex3D = false);
void RenderText(const CCommandBuffer::SState &State, int DrawNum, int TextTextureIndex, int TextOutlineTextureIndex, int TextureSize, const float *pTextColor, const float *pTextOutlineColor);
void Cmd_Init(const SCommand_Init *pCommand) override;
bool Cmd_Init(const SCommand_Init *pCommand) override;
void Cmd_Shutdown(const SCommand_Shutdown *pCommand) override;
void Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand) override;
void Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand) override;

View file

@ -886,14 +886,12 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
CmdOpenGL.m_pStorage = pStorage;
CmdOpenGL.m_pCapabilities = &m_Capabilites;
CmdOpenGL.m_pInitError = &InitError;
CmdOpenGL.m_pCapabilities = &m_Capabilites;
CmdOpenGL.m_RequestedMajor = g_Config.m_GfxOpenGLMajor;
CmdOpenGL.m_RequestedMinor = g_Config.m_GfxOpenGLMinor;
CmdOpenGL.m_RequestedPatch = g_Config.m_GfxOpenGLPatch;
CmdOpenGL.m_GlewMajor = GlewMajor;
CmdOpenGL.m_GlewMinor = GlewMinor;
CmdOpenGL.m_GlewPatch = GlewPatch;
CmdOpenGL.m_pInitError = &InitError;
CmdOpenGL.m_pErrStringPtr = &pErrorStr;
CmdOpenGL.m_pVendorString = m_aVendorString;
CmdOpenGL.m_pVersionString = m_aVersionString;
@ -904,23 +902,20 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
}
if(InitError == -2)
if(InitError != 0)
{
if(InitError != -2)
{
// shutdown the context, as it might have been initialized
CCommandProcessorFragment_OpenGLBase::SCommand_Shutdown CmdGL;
CmdBuffer.AddCommandUnsafe(CmdGL);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
g_Config.m_GfxOpenGLMajor = m_Capabilites.m_ContextMajor;
g_Config.m_GfxOpenGLMinor = m_Capabilites.m_ContextMinor;
g_Config.m_GfxOpenGLPatch = m_Capabilites.m_ContextPatch;
}
}
if(InitError != 0)
{
CCommandProcessorFragment_SDL::SCommand_Shutdown Cmd;
CmdBuffer.AddCommandUnsafe(Cmd);
RunBuffer(&CmdBuffer);