Fix race between bgfx::begin and bgfx::frame encoder allocation. (#3646)

* Fix race between bgfx::begin and bgfx::frame encoder allocation.

* Update src/bgfx.cpp

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Branimir Karadžić
2026-03-25 21:36:02 -07:00
committed by GitHub
parent 9c98438372
commit 8532b2c45d
2 changed files with 12 additions and 8 deletions

View File

@@ -2405,7 +2405,8 @@ namespace bgfx
if (_forceNewEncoder
|| BGFX_API_THREAD_MAGIC != s_threadIndex)
{
bx::MutexScope scopeLock(m_encoderApiLock);
bx::MutexScope beginLockScope(m_encoderBeginLock);
bx::MutexScope encoderApiScope(m_encoderApiLock);
uint16_t idx = m_encoderHandle->alloc();
if (kInvalidHandle == idx)
@@ -2442,14 +2443,20 @@ namespace bgfx
m_encoder[0].end(true);
#if BGFX_CONFIG_MULTITHREADED
bx::MutexScope resourceApiScope(m_resourceApiLock);
encoderApiWait();
m_encoderBeginLock.lock(); // don't let any bgfx::begin calls...
encoderApiWait(); // wait for all started encoders to return...
bx::MutexScope encoderApiScope(m_encoderApiLock);
m_encoderBeginLock.unlock();
bx::MutexScope resourceApiScope(m_resourceApiLock);
#else
encoderApiWait();
#endif // BGFX_CONFIG_MULTITHREADED
m_encoderHandle->reset();
const uint16_t idx = m_encoderHandle->alloc();
BX_ASSERT(0 == idx, "Internal encoder handle is not 0 (idx %d).", idx); BX_UNUSED(idx);
if (0 != (_flags & BGFX_FRAME_DISCARD) )
{
m_submit->m_numRenderItems = 0;

View File

@@ -5921,16 +5921,13 @@ namespace bgfx
}
m_submit->m_perfStats.numEncoders = uint8_t(numEncoders);
m_encoderHandle->reset();
uint16_t idx = m_encoderHandle->alloc();
BX_ASSERT(0 == idx, "Internal encoder handle is not 0 (idx %d).", idx); BX_UNUSED(idx);
}
bx::Semaphore m_renderSem;
bx::Semaphore m_apiSem;
bx::Semaphore m_encoderEndSem;
bx::Mutex m_encoderApiLock;
bx::Mutex m_encoderBeginLock;
bx::Mutex m_resourceApiLock;
bx::Thread m_thread;
#else