//============================================================================== void RenderingThread::flushCommandBuffer(CommandBufferPtr cmdb) { cmdb->getImplementation().makeImmutable(); { LockGuard<Mutex> lock(m_mtx); // Set commands U64 diff = m_tail - m_head; if(diff < m_queue.getSize()) { U64 idx = m_tail % m_queue.getSize(); m_queue[idx] = cmdb; ++m_tail; } else { ANKI_LOGW("Rendering queue too small"); } m_condVar.notifyOne(); // Wake the thread } }
Error operator()(GlState&) { ANKI_TRACE_START_EVENT(GL_2ND_LEVEL_CMD_BUFFER); Error err = m_cmdb->getImplementation().executeAllCommands(); ANKI_TRACE_STOP_EVENT(GL_2ND_LEVEL_CMD_BUFFER); return err; }
void Texture::init(const TextureInitInfo& init) { m_impl.reset(getAllocator().newInstance<TextureImpl>(&getManager())); CommandBufferPtr cmdb = getManager().newInstance<CommandBuffer>(CommandBufferInitInfo()); cmdb->getImplementation().pushBackNewCommand<CreateTextureCommand>( this, init); cmdb->flush(); }
void OcclusionQuery::init(OcclusionQueryResultBit condRenderingBit) { m_impl.reset(getAllocator().newInstance<OcclusionQueryImpl>(&getManager())); CommandBufferPtr cmdb = getManager().newInstance<CommandBuffer>(CommandBufferInitInfo()); cmdb->getImplementation().pushBackNewCommand<CreateOqCommand>( this, condRenderingBit); cmdb->flush(); }
//============================================================================== void RenderingThread::threadLoop() { prepare(); while(1) { CommandBufferPtr cmd; // Wait for something { LockGuard<Mutex> lock(m_mtx); while(m_tail == m_head) { m_condVar.wait(m_mtx); } // Check signals if(m_renderingThreadSignal == 1) { // Requested to stop break; } U64 idx = m_head % m_queue.getSize(); // Pop a command cmd = m_queue[idx]; m_queue[idx] = CommandBufferPtr(); // Insert empty cmd buffer ++m_head; } ANKI_TRACE_START_EVENT(GL_THREAD); Error err = cmd->getImplementation().executeAllCommands(); ANKI_TRACE_STOP_EVENT(GL_THREAD); if(err) { ANKI_LOGE("Error in rendering thread. Aborting"); abort(); } } finish(); }