RenderingThread.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Gr/CommandBuffer.h>
  7. #include <AnKi/Util/Thread.h>
  8. namespace anki {
  9. /// @addtogroup opengl
  10. /// @{
  11. /// Command queue. It's essentialy a queue of command buffers waiting for execution and a server
  12. class RenderingThread
  13. {
  14. friend class SyncCommand;
  15. friend class SwapBuffersCommand;
  16. public:
  17. RenderingThread(GrManagerImpl* device);
  18. ~RenderingThread();
  19. /// Start the working thread
  20. /// @note Don't free the context before calling #stop
  21. void start();
  22. /// Stop the working thread
  23. void stop();
  24. /// Push a command buffer to the queue for deferred execution
  25. void flushCommandBuffer(CommandBufferPtr commands, FencePtr* fence);
  26. /// Push a command buffer to the queue and wait for it
  27. void finishCommandBuffer(CommandBufferPtr commands);
  28. /// Sync the client and server
  29. void syncClientServer();
  30. /// Return true if this is the main thread
  31. Bool isServerThread() const
  32. {
  33. return m_serverThreadId == Thread::getCurrentThreadId();
  34. }
  35. /// Swap buffers
  36. void swapBuffers();
  37. private:
  38. WeakPtr<GrManagerImpl> m_manager;
  39. static const U QUEUE_SIZE = 1024 * 2;
  40. DynamicArray<CommandBufferPtr> m_queue; ///< Command queue
  41. U64 m_tail; ///< Tail of queue
  42. U64 m_head; ///< Head of queue. Points to the end
  43. U8 m_renderingThreadSignal; ///< Signal to the thread
  44. Mutex m_mtx; ///< Wake the thread
  45. ConditionVariable m_condVar; ///< To wake up the thread
  46. Thread m_thread;
  47. /// @name Swap_buffers_vars
  48. /// @{
  49. CommandBufferPtr m_swapBuffersCommands;
  50. ConditionVariable m_frameCondVar;
  51. Mutex m_frameMtx;
  52. Bool m_frameWait = false;
  53. /// @}
  54. ThreadId m_serverThreadId;
  55. /// A special command buffer that is called every time we want to wait for the server
  56. CommandBufferPtr m_syncCommands;
  57. Barrier m_syncBarrier{2};
  58. SpinLock m_syncLock;
  59. /// Command buffer with an empty command.
  60. CommandBufferPtr m_emptyCmdb;
  61. /// The function that the thread runs
  62. static ANKI_USE_RESULT Error threadCallback(ThreadCallbackInfo&);
  63. void threadLoop();
  64. void prepare();
  65. void finish();
  66. void swapBuffersInternal();
  67. };
  68. /// @}
  69. } // end namespace anki