3763: Make AddCommand usage in graphics class safer r=def- a=Jupeyy

so it doesnt add commands without rechecking if the command was actually added

## Checklist

- [ ] 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-04-07 22:34:35 +00:00 committed by GitHub
commit d969e8a922
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 223 additions and 317 deletions

View file

@ -4630,7 +4630,7 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
CmdSDL.m_pVendorString = m_aVendorString;
CmdSDL.m_pVersionString = m_aVersionString;
CmdSDL.m_pRendererString = m_aRendererString;
CmdBuffer.AddCommand(CmdSDL);
CmdBuffer.AddCommandUnsafe(CmdSDL);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
@ -4642,7 +4642,7 @@ 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;
CmdBuffer.AddCommand(CmdOpenGL);
CmdBuffer.AddCommandUnsafe(CmdOpenGL);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
@ -4650,7 +4650,7 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
if(InitError == -2)
{
CCommandProcessorFragment_OpenGL::SCommand_Shutdown CmdGL;
CmdBuffer.AddCommand(CmdGL);
CmdBuffer.AddCommandUnsafe(CmdGL);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
@ -4664,7 +4664,7 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
if(InitError != 0)
{
CCommandProcessorFragment_SDL::SCommand_Shutdown Cmd;
CmdBuffer.AddCommand(Cmd);
CmdBuffer.AddCommandUnsafe(Cmd);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
@ -4717,7 +4717,7 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidt
CmdSDL.m_Width = CurrentDisplayMode.w;
CmdSDL.m_Height = CurrentDisplayMode.h;
CmdBuffer.AddCommand(CmdSDL);
CmdBuffer.AddCommandUnsafe(CmdSDL);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
@ -4733,13 +4733,13 @@ int CGraphicsBackend_SDL_OpenGL::Shutdown()
// issue a shutdown command
CCommandBuffer CmdBuffer(1024, 512);
CCommandProcessorFragment_OpenGL::SCommand_Shutdown CmdGL;
CmdBuffer.AddCommand(CmdGL);
CmdBuffer.AddCommandUnsafe(CmdGL);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();
CCommandProcessorFragment_SDL::SCommand_Shutdown Cmd;
CmdBuffer.AddCommand(Cmd);
CmdBuffer.AddCommandUnsafe(Cmd);
RunBuffer(&CmdBuffer);
WaitForIdle();
CmdBuffer.Reset();

View file

@ -272,7 +272,8 @@ int CGraphics_Threaded::UnloadTexture(CTextureHandle Index)
CCommandBuffer::SCommand_Texture_Destroy Cmd;
Cmd.m_Slot = Index;
m_pCommandBuffer->AddCommand(Cmd);
AddCmd(
Cmd, [] { return true; }, "failed to unload texture.");
m_TextureIndices[Index] = m_FirstFreeTexture;
m_FirstFreeTexture = Index;
@ -325,13 +326,8 @@ int CGraphics_Threaded::LoadTextureRawSub(CTextureHandle TextureID, int x, int y
mem_copy(pTmpData, pData, MemSize);
Cmd.m_pData = pTmpData;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
m_pCommandBuffer->AddCommand(Cmd);
}
AddCmd(
Cmd, [] { return true; }, "failed to load raw sub texture.");
return 0;
}
@ -481,13 +477,8 @@ IGraphics::CTextureHandle CGraphics_Threaded::LoadTextureRaw(int Width, int Heig
mem_copy(pTmpData, pData, MemSize);
Cmd.m_pData = pTmpData;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
m_pCommandBuffer->AddCommand(Cmd);
}
AddCmd(
Cmd, [] { return true; }, "failed to load raw texture.");
return CreateTextureHandle(Tex);
}
@ -669,7 +660,8 @@ void CGraphics_Threaded::ScreenshotDirect()
CCommandBuffer::SCommand_Screenshot Cmd;
Cmd.m_pImage = &Image;
m_pCommandBuffer->AddCommand(Cmd);
AddCmd(
Cmd, [] { return true; }, "failed to take screenshot.");
// kick the buffer and wait for the result
KickCommandBuffer();
@ -710,7 +702,8 @@ void CGraphics_Threaded::Clear(float r, float g, float b)
Cmd.m_Color.g = g;
Cmd.m_Color.b = b;
Cmd.m_Color.a = 0;
m_pCommandBuffer->AddCommand(Cmd);
AddCmd(
Cmd, [] { return true; }, "failed to clear graphics.");
}
void CGraphics_Threaded::QuadsBegin()
@ -1126,26 +1119,21 @@ void CGraphics_Threaded::RenderTileLayer(int BufferContainerIndex, float *pColor
Cmd.m_pIndicesOffsets = (char **)Data;
Cmd.m_pDrawCount = (unsigned int *)(((char *)Data) + (sizeof(char *) * NumIndicesOffet));
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Data = m_pCommandBuffer->AllocData((sizeof(char *) + sizeof(unsigned int)) * NumIndicesOffet);
if(Data == 0x0)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return false;
}
Cmd.m_pIndicesOffsets = (char **)Data;
Cmd.m_pDrawCount = (unsigned int *)(((char *)Data) + (sizeof(char *) * NumIndicesOffet));
return true;
},
"failed to allocate memory for render command"))
{
// kick command buffer and try again
KickCommandBuffer();
Data = m_pCommandBuffer->AllocData((sizeof(char *) + sizeof(unsigned int)) * NumIndicesOffet);
if(Data == 0x0)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
Cmd.m_pIndicesOffsets = (char **)Data;
Cmd.m_pDrawCount = (unsigned int *)(((char *)Data) + (sizeof(char *) * NumIndicesOffet));
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
return;
}
mem_copy(Cmd.m_pIndicesOffsets, pOffsets, sizeof(char *) * NumIndicesOffet);
@ -1174,16 +1162,10 @@ void CGraphics_Threaded::RenderBorderTiles(int BufferContainerIndex, float *pCol
Cmd.m_Dir[1] = pDir[1];
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for render command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
return;
}
}
@ -1207,16 +1189,10 @@ void CGraphics_Threaded::RenderBorderTileLines(int BufferContainerIndex, float *
Cmd.m_Dir[1] = pDir[1];
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for render command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
return;
}
}
@ -1237,23 +1213,19 @@ void CGraphics_Threaded::RenderQuadLayer(int BufferContainerIndex, SQuadRenderIn
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_pQuadInfo = (SQuadRenderInfo *)m_pCommandBuffer->AllocData(QuadNum * sizeof(SQuadRenderInfo));
if(Cmd.m_pQuadInfo == 0x0)
{
dbg_msg("graphics", "failed to allocate data for the quad info");
return false;
}
return true;
},
"failed to allocate memory for render quad command"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pQuadInfo = (SQuadRenderInfo *)m_pCommandBuffer->AllocData(QuadNum * sizeof(SQuadRenderInfo));
if(Cmd.m_pQuadInfo == 0x0)
{
dbg_msg("graphics", "failed to allocate data for the quad info");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render quad command");
return;
}
return;
}
mem_copy(Cmd.m_pQuadInfo, pQuadInfo, sizeof(SQuadRenderInfo) * QuadNum);
@ -1274,17 +1246,10 @@ void CGraphics_Threaded::RenderText(int BufferContainerIndex, int TextQuadNum, i
mem_copy(Cmd.m_aTextColor, pTextColor, sizeof(Cmd.m_aTextColor));
mem_copy(Cmd.m_aTextOutlineColor, pTextoutlineColor, sizeof(Cmd.m_aTextOutlineColor));
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for render text command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render text command");
return;
}
return;
}
}
@ -1490,17 +1455,10 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset,
Cmd.m_pOffset = (void *)(QuadOffset * 6 * sizeof(unsigned int));
Cmd.m_BufferContainerIndex = Container.m_QuadBufferContainerIndex;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for render quad container"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render quad container");
return;
}
return;
}
}
else
@ -1573,17 +1531,10 @@ void CGraphics_Threaded::RenderQuadContainerEx(int ContainerIndex, int QuadOffse
Cmd.m_Center.x = Quad.m_aVertices[0].m_Pos.x + (Quad.m_aVertices[1].m_Pos.x - Quad.m_aVertices[0].m_Pos.x) / 2.f;
Cmd.m_Center.y = Quad.m_aVertices[0].m_Pos.y + (Quad.m_aVertices[2].m_Pos.y - Quad.m_aVertices[0].m_Pos.y) / 2.f;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for render quad container extended"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render quad container extended");
return;
}
return;
}
}
else
@ -1713,24 +1664,19 @@ void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex,
}
}
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_pRenderInfo = (IGraphics::SRenderSpriteInfo *)m_pCommandBuffer->AllocData(sizeof(IGraphics::SRenderSpriteInfo) * DrawCount);
if(Cmd.m_pRenderInfo == 0x0)
{
dbg_msg("graphics", "failed to allocate data for render info");
return false;
}
return true;
},
"failed to allocate memory for render quad container sprite"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pRenderInfo = (IGraphics::SRenderSpriteInfo *)m_pCommandBuffer->AllocData(sizeof(IGraphics::SRenderSpriteInfo) * DrawCount);
if(Cmd.m_pRenderInfo == 0x0)
{
dbg_msg("graphics", "failed to allocate data for render info");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for render quad container sprite");
return;
}
return;
}
mem_copy(Cmd.m_pRenderInfo, pRenderInfo, sizeof(IGraphics::SRenderSpriteInfo) * DrawCount);
@ -1788,16 +1734,10 @@ int CGraphics_Threaded::CreateBufferObject(size_t UploadDataSize, void *pUploadD
{
Cmd.m_pUploadData = pUploadData;
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for update buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return -1;
}
return -1;
}
}
else
@ -1808,40 +1748,31 @@ int CGraphics_Threaded::CreateBufferObject(size_t UploadDataSize, void *pUploadD
if(Cmd.m_pUploadData == NULL)
return -1;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return false;
}
return true;
},
"failed to allocate memory for create buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return -1;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer object command");
return -1;
}
return -1;
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
}
else
{
Cmd.m_pUploadData = NULL;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for create buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer object command");
return -1;
}
return -1;
}
// update the buffer instead
@ -1872,16 +1803,10 @@ void CGraphics_Threaded::RecreateBufferObject(int BufferIndex, size_t UploadData
{
Cmd.m_pUploadData = pUploadData;
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for recreate buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for recreate buffer object command");
return;
}
return;
}
}
else
@ -1892,24 +1817,19 @@ void CGraphics_Threaded::RecreateBufferObject(int BufferIndex, size_t UploadData
if(Cmd.m_pUploadData == NULL)
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return false;
}
return true;
},
"failed to allocate memory for recreate buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for recreate buffer object command");
return;
}
return;
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
@ -1917,16 +1837,11 @@ void CGraphics_Threaded::RecreateBufferObject(int BufferIndex, size_t UploadData
else
{
Cmd.m_pUploadData = NULL;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for update buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return;
}
return;
}
// update the buffer instead
@ -1956,16 +1871,10 @@ void CGraphics_Threaded::UpdateBufferObject(int BufferIndex, size_t UploadDataSi
{
Cmd.m_pUploadData = pUploadData;
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for update buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return;
}
return;
}
}
else
@ -1974,24 +1883,19 @@ void CGraphics_Threaded::UpdateBufferObject(int BufferIndex, size_t UploadDataSi
if(Cmd.m_pUploadData == NULL)
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return false;
}
return true;
},
"failed to allocate memory for update buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_pUploadData = m_pCommandBuffer->AllocData(UploadDataSize);
if(Cmd.m_pUploadData == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer object command");
return;
}
return;
}
mem_copy(Cmd.m_pUploadData, pUploadData, UploadDataSize);
@ -2007,17 +1911,10 @@ void CGraphics_Threaded::CopyBufferObject(int WriteBufferIndex, int ReadBufferIn
Cmd.m_pReadOffset = ReadOffset;
Cmd.m_CopySize = CopyDataSize;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for copy buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for copy buffer object command");
return;
}
return;
}
}
@ -2029,17 +1926,10 @@ void CGraphics_Threaded::DeleteBufferObject(int BufferIndex)
CCommandBuffer::SCommand_DeleteBufferObject Cmd;
Cmd.m_BufferIndex = BufferIndex;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for delete buffer object command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for delete buffer object command");
return;
}
return;
}
// also clear the buffer object index
@ -2071,24 +1961,19 @@ int CGraphics_Threaded::CreateBufferContainer(SBufferContainerInfo *pContainerIn
if(Cmd.m_Attributes == NULL)
return -1;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_Attributes = (SBufferContainerInfo::SAttribute *)m_pCommandBuffer->AllocData(Cmd.m_AttrCount * sizeof(SBufferContainerInfo::SAttribute));
if(Cmd.m_Attributes == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return false;
}
return true;
},
"failed to allocate memory for create buffer container command"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_Attributes = (SBufferContainerInfo::SAttribute *)m_pCommandBuffer->AllocData(Cmd.m_AttrCount * sizeof(SBufferContainerInfo::SAttribute));
if(Cmd.m_Attributes == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return -1;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for create buffer container command");
return -1;
}
return -1;
}
mem_copy(Cmd.m_Attributes, &pContainerInfo->m_Attributes[0], Cmd.m_AttrCount * sizeof(SBufferContainerInfo::SAttribute));
@ -2107,17 +1992,10 @@ void CGraphics_Threaded::DeleteBufferContainer(int ContainerIndex, bool DestroyA
Cmd.m_BufferContainerIndex = ContainerIndex;
Cmd.m_DestroyAllBO = DestroyAllBO;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for delete buffer container command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for delete buffer container command");
return;
}
return;
}
if(DestroyAllBO)
@ -2158,24 +2036,19 @@ void CGraphics_Threaded::UpdateBufferContainer(int ContainerIndex, SBufferContai
if(Cmd.m_Attributes == NULL)
return;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [&] {
Cmd.m_Attributes = (SBufferContainerInfo::SAttribute *)m_pCommandBuffer->AllocData(Cmd.m_AttrCount * sizeof(SBufferContainerInfo::SAttribute));
if(Cmd.m_Attributes == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return false;
}
return true;
},
"failed to allocate memory for update buffer container command"))
{
// kick command buffer and try again
KickCommandBuffer();
Cmd.m_Attributes = (SBufferContainerInfo::SAttribute *)m_pCommandBuffer->AllocData(Cmd.m_AttrCount * sizeof(SBufferContainerInfo::SAttribute));
if(Cmd.m_Attributes == 0x0)
{
dbg_msg("graphics", "failed to allocate data for upload data");
return;
}
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for update buffer container command");
return;
}
return;
}
mem_copy(Cmd.m_Attributes, &pContainerInfo->m_Attributes[0], Cmd.m_AttrCount * sizeof(SBufferContainerInfo::SAttribute));
@ -2190,17 +2063,10 @@ void CGraphics_Threaded::IndicesNumRequiredNotify(unsigned int RequiredIndicesCo
CCommandBuffer::SCommand_IndicesRequiredNumNotify Cmd;
Cmd.m_RequiredIndicesNum = RequiredIndicesCount;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Cmd))
if(!AddCmd(
Cmd, [] { return true; }, "failed to allocate memory for indcies required count notify command"))
{
// kick command buffer and try again
KickCommandBuffer();
if(!m_pCommandBuffer->AddCommand(Cmd))
{
dbg_msg("graphics", "failed to allocate memory for indcies required count notify command");
return;
}
return;
}
}
@ -2471,7 +2337,12 @@ void CGraphics_Threaded::Resize(int w, int h, bool SetWindowSize)
CCommandBuffer::SCommand_Resize Cmd;
Cmd.m_Width = m_ScreenWidth;
Cmd.m_Height = m_ScreenHeight;
m_pCommandBuffer->AddCommand(Cmd);
if(!AddCmd(
Cmd, [] { return true; }, "failed to add resize command"))
{
return;
}
// kick the command buffer
KickCommandBuffer();
@ -2548,7 +2419,11 @@ void CGraphics_Threaded::Swap()
// add swap command
CCommandBuffer::SCommand_Swap Cmd;
Cmd.m_Finish = g_Config.m_GfxFinish;
m_pCommandBuffer->AddCommand(Cmd);
if(!AddCmd(
Cmd, [] { return true; }, "failed to add swap command"))
{
return;
}
// kick the command buffer
KickCommandBuffer();
@ -2564,7 +2439,12 @@ bool CGraphics_Threaded::SetVSync(bool State)
CCommandBuffer::SCommand_VSync Cmd;
Cmd.m_VSync = State ? 1 : 0;
Cmd.m_pRetOk = &RetOk;
m_pCommandBuffer->AddCommand(Cmd);
if(!AddCmd(
Cmd, [] { return true; }, "failed to add vsync command"))
{
return false;
}
// kick the command buffer
KickCommandBuffer();
@ -2577,7 +2457,12 @@ void CGraphics_Threaded::InsertSignal(CSemaphore *pSemaphore)
{
CCommandBuffer::SCommand_Signal Cmd;
Cmd.m_pSemaphore = pSemaphore;
m_pCommandBuffer->AddCommand(Cmd);
if(!AddCmd(
Cmd, [] { return true; }, "failed to add signal command"))
{
return;
}
}
bool CGraphics_Threaded::IsIdle() const
@ -2637,7 +2522,12 @@ int CGraphics_Threaded::GetVideoModes(CVideoMode *pModes, int MaxModes, int Scre
Cmd.m_MaxModes = MaxModes;
Cmd.m_pNumModes = &NumModes;
Cmd.m_Screen = Screen;
m_pCommandBuffer->AddCommand(Cmd);
if(!AddCmd(
Cmd, [] { return true; }, "failed to add video mode command"))
{
return 0;
}
// kick the buffer and wait for the result and return it
KickCommandBuffer();

View file

@ -581,7 +581,7 @@ public:
}
template<class T>
bool AddCommand(const T &Command)
bool AddCommandUnsafe(const T &Command)
{
// make sure that we don't do something stupid like ->AddCommand(&Cmd);
(void)static_cast<const SCommand *>(&Command);
@ -807,6 +807,26 @@ class CGraphics_Threaded : public IEngineGraphics
}
}
template<typename TName, typename TFunc>
bool AddCmd(TName &Cmd, TFunc &&FailFunc, const char *pFailStr)
{
if(!m_pCommandBuffer->AddCommandUnsafe(Cmd))
{
// kick command buffer and try again
KickCommandBuffer();
if(!FailFunc())
return false;
if(!m_pCommandBuffer->AddCommandUnsafe(Cmd))
{
dbg_msg("graphics", "%s", pFailStr);
return false;
}
}
return true;
}
void KickCommandBuffer();
void AddBackEndWarningIfExists();
@ -1069,24 +1089,20 @@ public:
Command.m_PrimType = PrimType;
Command.m_PrimCount = PrimCount;
// check if we have enough free memory in the commandbuffer
if(!m_pCommandBuffer->AddCommand(Command))
if(
!AddCmd(
Command, [&] {
Command.m_pVertices = (decltype(Command.m_pVertices))m_pCommandBuffer->AllocData(VertSize * NumVerts);
if(Command.m_pVertices == NULL)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return false;
}
return true;
},
"failed to allocate memory for render command"))
{
// kick command buffer and try again
KickCommandBuffer();
Command.m_pVertices = (decltype(Command.m_pVertices))m_pCommandBuffer->AllocData(VertSize * NumVerts);
if(Command.m_pVertices == NULL)
{
dbg_msg("graphics", "failed to allocate data for vertices");
return;
}
if(!m_pCommandBuffer->AddCommand(Command))
{
dbg_msg("graphics", "failed to allocate memory for render command");
return;
}
return;
}
}