CommandBufferImpl.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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/Gr/gl/StateTracker.h>
  8. #include <AnKi/Util/Assert.h>
  9. #include <AnKi/Util/Allocator.h>
  10. namespace anki {
  11. // Forward
  12. class GlState;
  13. /// @addtogroup opengl
  14. /// @{
  15. template<typename T>
  16. using CommandBufferAllocator = StackAllocator<T>;
  17. /// The base of all GL commands.
  18. class GlCommand
  19. {
  20. public:
  21. GlCommand* m_nextCommand = nullptr;
  22. virtual ~GlCommand()
  23. {
  24. }
  25. /// Execute command
  26. virtual ANKI_USE_RESULT Error operator()(GlState& state) = 0;
  27. };
  28. /// A number of GL commands organized in a chain
  29. class CommandBufferImpl final : public CommandBuffer
  30. {
  31. public:
  32. GlCommand* m_firstCommand = nullptr;
  33. GlCommand* m_lastCommand = nullptr;
  34. CommandBufferAllocator<U8> m_alloc;
  35. Bool m_immutable = false;
  36. CommandBufferFlag m_flags;
  37. #if ANKI_EXTRA_CHECKS
  38. Bool m_executed = false;
  39. #endif
  40. StateTracker m_state;
  41. /// Default constructor
  42. CommandBufferImpl(GrManager* manager, CString name)
  43. : CommandBuffer(manager, name)
  44. {
  45. }
  46. ~CommandBufferImpl()
  47. {
  48. destroy();
  49. }
  50. /// Initialize.
  51. void init(const CommandBufferInitInfo& init);
  52. /// Get the internal allocator.
  53. CommandBufferAllocator<U8> getInternalAllocator() const
  54. {
  55. return m_alloc;
  56. }
  57. /// Create a new command and add it to the chain.
  58. template<typename TCommand, typename... TArgs>
  59. void pushBackNewCommand(TArgs&&... args);
  60. /// Execute all commands
  61. ANKI_USE_RESULT Error executeAllCommands();
  62. /// Fake that it's been executed
  63. void makeExecuted()
  64. {
  65. #if ANKI_EXTRA_CHECKS
  66. m_executed = true;
  67. #endif
  68. }
  69. /// Make immutable
  70. void makeImmutable()
  71. {
  72. m_immutable = true;
  73. }
  74. Bool isEmpty() const
  75. {
  76. return m_firstCommand == nullptr;
  77. }
  78. Bool isSecondLevel() const
  79. {
  80. return !!(m_flags & CommandBufferFlag::SECOND_LEVEL);
  81. }
  82. void flushDrawcall(CommandBuffer& cmdb);
  83. private:
  84. void destroy();
  85. };
  86. template<typename TCommand, typename... TArgs>
  87. inline void CommandBufferImpl::pushBackNewCommand(TArgs&&... args)
  88. {
  89. ANKI_ASSERT(!m_immutable);
  90. TCommand* newCommand = m_alloc.template newInstance<TCommand>(std::forward<TArgs>(args)...);
  91. if(m_firstCommand != nullptr)
  92. {
  93. ANKI_ASSERT(m_lastCommand != nullptr);
  94. ANKI_ASSERT(m_lastCommand->m_nextCommand == nullptr);
  95. m_lastCommand->m_nextCommand = newCommand;
  96. m_lastCommand = newCommand;
  97. }
  98. else
  99. {
  100. ANKI_ASSERT(m_lastCommand == nullptr);
  101. m_firstCommand = newCommand;
  102. m_lastCommand = newCommand;
  103. }
  104. }
  105. /// @}
  106. } // end namespace anki