diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.cpp b/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.cpp index a5275c8a..44cd4da4 100644 --- a/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.cpp +++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.cpp @@ -1,6 +1,8 @@ #include "RingBufferPool.h" #include #include +#include +#include namespace opengl { @@ -50,10 +52,11 @@ size_t PoolBufferPointer::getSize() const } RingBufferPool::RingBufferPool(size_t _poolSize) : - m_poolBuffer(_poolSize, 0), + m_poolBuffer(m_startBufferPoolSize, 0), m_inUseStartOffset(0), m_inUseEndOffset(0), - m_full(false) + m_full(false), + m_maxBufferPoolSize(_poolSize) { } @@ -61,14 +64,14 @@ RingBufferPool::RingBufferPool(size_t _poolSize) : PoolBufferPointer RingBufferPool::createPoolBuffer(const char* _buffer, size_t _bufferSize) { size_t realBufferSize = _bufferSize; - size_t remainder = _bufferSize % 4; + const size_t remainder = _bufferSize % 4; if (remainder != 0) realBufferSize = _bufferSize + 4 - remainder; - size_t tempInUseStart = m_inUseStartOffset; + const size_t tempInUseStart = m_inUseStartOffset; - size_t remaining = tempInUseStart > m_inUseEndOffset || m_full ? + const size_t remaining = tempInUseStart > m_inUseEndOffset || m_full ? static_cast(tempInUseStart - m_inUseEndOffset) : m_poolBuffer.size() - m_inUseEndOffset + tempInUseStart; @@ -91,7 +94,7 @@ PoolBufferPointer RingBufferPool::createPoolBuffer(const char* _buffer, size_t _ { std::unique_lock lock(m_mutex); m_condition.wait(lock, [this, realBufferSize] { - size_t tempInUseStartLocal = m_inUseStartOffset; + const size_t tempInUseStartLocal = m_inUseStartOffset; return realBufferSize < tempInUseStartLocal || tempInUseStartLocal == m_inUseEndOffset; }); @@ -105,14 +108,28 @@ PoolBufferPointer RingBufferPool::createPoolBuffer(const char* _buffer, size_t _ } else { // Wait until enough space is avalable { + if (realBufferSize > m_maxBufferPoolSize) { + std::stringstream errorString; + errorString << " Attempted to create buffer of invalid size, size=" << realBufferSize << ", max_size=" << m_maxBufferPoolSize; + LOG(LOG_ERROR, errorString.str().c_str()); + throw std::runtime_error(errorString.str().c_str()); + } + std::unique_lock lock(m_mutex); + if (m_poolBuffer.size() < realBufferSize) { + std::stringstream errorString; + errorString << " Increasing buffer size from " << m_poolBuffer.size() << " to " << realBufferSize; + LOG(LOG_VERBOSE, errorString.str().c_str()); + + m_poolBuffer.resize(realBufferSize); + } m_condition.wait(lock, [this, realBufferSize] { - size_t tempInUseStartLocal = m_inUseStartOffset; - size_t remainingLocal = - tempInUseStartLocal > m_inUseEndOffset || m_full ? static_cast( - tempInUseStartLocal - m_inUseEndOffset) : - m_poolBuffer.size() - m_inUseEndOffset + tempInUseStartLocal; + const size_t tempInUseStartLocal = m_inUseStartOffset; + const size_t remainingLocal = + tempInUseStartLocal > m_inUseEndOffset || m_full ? static_cast( + tempInUseStartLocal - m_inUseEndOffset) : + m_poolBuffer.size() - m_inUseEndOffset + tempInUseStartLocal; return remainingLocal >= realBufferSize; }); @@ -133,6 +150,7 @@ const char* RingBufferPool::getBufferFromPool(PoolBufferPointer _poolBufferPoint if (!_poolBufferPointer.isValid()) { return nullptr; } else { + std::unique_lock lock(m_mutex); return m_poolBuffer.data() + _poolBufferPointer.m_offset; } } diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.h b/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.h index c8834621..6c1598d6 100644 --- a/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.h +++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/RingBufferPool.h @@ -34,10 +34,17 @@ public: explicit RingBufferPool(size_t _poolSize); + // Create a buffer pool. This method will block if there is not enough space until + // enough space has been freed from a seperate thread. If a buffer bigger than the + // maximum is allocated, then a run time exception will be thrown PoolBufferPointer createPoolBuffer(const char* _buffer, size_t _bufferSize); + // Retrieves a buffer from the buffer pool, will return a nullptr if an invalid + // buffer is provided const char* getBufferFromPool(PoolBufferPointer _poolBufferPointer); + // Removes the give buffer from the pool, no action will be taken if the provided + // buffer is not valid void removeBufferFromPool(PoolBufferPointer _poolBufferPointer); private: @@ -47,6 +54,8 @@ private: std::mutex m_mutex; std::atomic m_full; std::condition_variable_any m_condition; + size_t m_maxBufferPoolSize; + static const size_t m_startBufferPoolSize = 1024 * 100; }; } \ No newline at end of file diff --git a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp index 4aee8a30..f8241fce 100644 --- a/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp +++ b/src/Graphics/OpenGLContext/ThreadedOpenGl/opengl_Command.cpp @@ -5,8 +5,8 @@ namespace opengl { - // 15MB memory pool - RingBufferPool OpenGlCommand::m_ringBufferPool(1024 * 1024 * 15 ); + // Max memory pool size + RingBufferPool OpenGlCommand::m_ringBufferPool(1024 * 1024 * 200 ); void OpenGlCommand::performCommandSingleThreaded() {