//============================================================================== void RenderingThread::finish() { // Iterate the queue and release the refcounts for(U i = 0; i < m_queue.getSize(); i++) { if(m_queue[i].isCreated()) { // Fake that it's executed to avoid warnings m_queue[i]->getImplementation().makeExecuted(); // Release m_queue[i] = CommandBufferPtr(); } } m_manager->getImplementation() .getDynamicMemoryManager() .destroyRenderThread(); // Cleanup GL m_manager->getImplementation().getState().destroy(); // Cleanup glFinish(); m_manager->getImplementation().pinContextToCurrentThread(false); }
//============================================================================== void CommandBuffer::finish() { #if ANKI_ASSERTS_ENABLED if(!m_impl->m_dbg.m_secondLevel) { ANKI_ASSERT(!m_impl->m_dbg.m_insideRenderPass); } #endif getManager().getImplementation().getRenderingThread().finishCommandBuffer( CommandBufferPtr(this)); }
//============================================================================== 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(); }