From 47698970699d2b2b671ede97573a77f0cc8af28a Mon Sep 17 00:00:00 2001 From: exmix Date: Sat, 12 Jul 2014 17:13:35 +0200 Subject: [PATCH] [drape] dynamic buffers support --- drape/binding_info.cpp | 34 ++++++---- drape/binding_info.hpp | 8 ++- drape/drape_tests/bingind_info_tests.cpp | 29 +++++++++ drape/drape_tests/drape_tests.pro | 5 +- drape/vertex_array_buffer.cpp | 82 ++++++++++++++++++------ drape/vertex_array_buffer.hpp | 18 ++++-- 6 files changed, 131 insertions(+), 45 deletions(-) create mode 100644 drape/drape_tests/bingind_info_tests.cpp diff --git a/drape/binding_info.cpp b/drape/binding_info.cpp index b31e5d1a3a..92aca9b9fa 100644 --- a/drape/binding_info.cpp +++ b/drape/binding_info.cpp @@ -48,40 +48,45 @@ bool BindingDecl::operator<(BindingDecl const & other) const } BindingInfo::BindingInfo() + : m_info(0) { - m_size = 0; } -BindingInfo::BindingInfo(uint16_t count) +BindingInfo::BindingInfo(uint8_t count, uint8_t id) + : m_info(((uint16_t)count << 8) | id) { m_bindings.reset(new BindingDecl[count]); - m_size = count; } BindingInfo::~BindingInfo() { } -uint16_t BindingInfo::GetCount() const +uint8_t BindingInfo::GetCount() const { - return m_size; + return (m_info & 0xFF00) >> 8; +} + +uint8_t BindingInfo::GetID() const +{ + return m_info & 0xFF; } BindingDecl const & BindingInfo::GetBindingDecl(uint16_t index) const { - ASSERT_LESS(index, m_size, ()); + ASSERT_LESS(index, GetCount(), ()); return m_bindings[index]; } BindingDecl & BindingInfo::GetBindingDecl(uint16_t index) { - ASSERT_LESS(index, m_size, ()); + ASSERT_LESS(index, GetCount(), ()); return m_bindings[index]; } uint16_t BindingInfo::GetElementSize() const { - if (m_size == 0) + if (GetCount() == 0) return 0; uint8_t stride = m_bindings[0].m_stride; @@ -89,18 +94,23 @@ uint16_t BindingInfo::GetElementSize() const return stride; int calcStride = 0; - for (uint16_t i = 0; i < m_size; ++i) + for (uint16_t i = 0; i < GetCount(); ++i) calcStride += (m_bindings[i].m_componentCount * sizeOfType(m_bindings[i].m_componentType)); return calcStride; } +bool BindingInfo::IsDynamic() const +{ + return GetID() > 0; +} + bool BindingInfo::operator<(BindingInfo const & other) const { - if (m_size != other.m_size) - return m_size < other.m_size; + if (m_info != other.m_info) + return m_info < other.m_info; - for (uint16_t i = 0; i < m_size; ++i) + for (uint16_t i = 0; i < GetCount(); ++i) { BindingDecl & thisDecl = m_bindings[i]; BindingDecl & otherDecl = other.m_bindings[i]; diff --git a/drape/binding_info.hpp b/drape/binding_info.hpp index db0df9f4a2..026403c3ba 100644 --- a/drape/binding_info.hpp +++ b/drape/binding_info.hpp @@ -21,17 +21,19 @@ class BindingInfo { public: BindingInfo(); - BindingInfo(uint16_t count); + BindingInfo(uint8_t count, uint8_t id = 0); ~BindingInfo(); - uint16_t GetCount() const; + uint8_t GetCount() const; + uint8_t GetID() const; BindingDecl const & GetBindingDecl(uint16_t index) const; BindingDecl & GetBindingDecl(uint16_t index); uint16_t GetElementSize() const; + bool IsDynamic() const; bool operator< (BindingInfo const & other) const; protected: shared_array m_bindings; - uint16_t m_size; + uint16_t m_info; }; diff --git a/drape/drape_tests/bingind_info_tests.cpp b/drape/drape_tests/bingind_info_tests.cpp new file mode 100644 index 0000000000..3b990a0377 --- /dev/null +++ b/drape/drape_tests/bingind_info_tests.cpp @@ -0,0 +1,29 @@ +#include "../../testing/testing.hpp" + +#include "../../drape/binding_info.hpp" + +UNIT_TEST(BindingInfoIDTest) +{ + { + BindingInfo info(1, 1); + TEST_EQUAL(info.GetID(), 1, ()); + } + + { + BindingInfo info(1); + TEST_EQUAL(info.GetID(), 0, ()); + } +} + +UNIT_TEST(DynamicHandlingTest) +{ + { + BindingInfo info(1); + TEST_EQUAL(info.IsDynamic(), false, ()); + } + + { + BindingInfo info(1, 1); + TEST_EQUAL(info.IsDynamic(), true, ()); + } +} diff --git a/drape/drape_tests/drape_tests.pro b/drape/drape_tests/drape_tests.pro index 3ebd83e5ff..5d5e0c8f02 100644 --- a/drape/drape_tests/drape_tests.pro +++ b/drape/drape_tests/drape_tests.pro @@ -37,8 +37,9 @@ SOURCES += \ compile_shaders_test.cpp \ batcher_tests.cpp \ pointers_tests.cpp \ - font_texture_tests.cpp + font_texture_tests.cpp \ + bingind_info_tests.cpp \ HEADERS += \ glmock_functions.hpp \ - enum_shaders.hpp + enum_shaders.hpp \ diff --git a/drape/vertex_array_buffer.cpp b/drape/vertex_array_buffer.cpp index 72c8c0f677..e4bb22de6a 100644 --- a/drape/vertex_array_buffer.cpp +++ b/drape/vertex_array_buffer.cpp @@ -16,7 +16,8 @@ VertexArrayBuffer::VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBuff VertexArrayBuffer::~VertexArrayBuffer() { m_indexBuffer.Destroy(); - DeleteRange(m_buffers, MasterPointerDeleter()); + DeleteRange(m_staticBuffers, MasterPointerDeleter()); + DeleteRange(m_dynamicBuffers, MasterPointerDeleter()); if (m_VAO != 0) { @@ -30,7 +31,7 @@ VertexArrayBuffer::~VertexArrayBuffer() void VertexArrayBuffer::Render() { - if (!m_buffers.empty()) + if (!(m_staticBuffers.empty() && m_dynamicBuffers.empty())) { ASSERT(!m_program.IsNull(), ("Somebody not call Build. It's very bad. Very very bad")); /// if OES_vertex_array_object is supported than all bindings already saved in VAO @@ -38,8 +39,9 @@ void VertexArrayBuffer::Render() if (GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject)) Bind(); else - BindBuffers(); + BindStaticBuffers(); + BindDynamicBuffers(); m_indexBuffer->Bind(); GLFunctions::glDrawElements(m_indexBuffer->GetCurrentSize()); } @@ -53,26 +55,54 @@ void VertexArrayBuffer::Build(RefPointer program) if (!GLExtensionsList::Instance().IsSupported(GLExtensionsList::VertexArrayObject)) return; - if (m_buffers.empty()) + if (m_staticBuffers.empty()) return; m_VAO = GLFunctions::glGenVertexArray(); Bind(); - BindBuffers(); + BindStaticBuffers(); } void VertexArrayBuffer::UploadData(BindingInfo const & bindingInfo, void const * data, uint16_t count) { - RefPointer buffer = GetBuffer(bindingInfo); + RefPointer buffer; + if (!bindingInfo.IsDynamic()) + buffer = GetOrCreateStaticBuffer(bindingInfo); + else + buffer = GetOrCreateDynamicBuffer(bindingInfo); buffer->UploadData(data, count); } -RefPointer VertexArrayBuffer::GetBuffer(BindingInfo const & bindingInfo) +RefPointer VertexArrayBuffer::GetOrCreateDynamicBuffer(BindingInfo const & bindingInfo) { - buffers_map_t::iterator it = m_buffers.find(bindingInfo); - if (it == m_buffers.end()) + return GetOrCreateBuffer(bindingInfo, m_dynamicBuffers); +} + +RefPointer VertexArrayBuffer::GetDynamicBuffer(BindingInfo const & bindingInfo) const +{ + return GetBuffer(bindingInfo, m_dynamicBuffers); +} + +RefPointer VertexArrayBuffer::GetOrCreateStaticBuffer(BindingInfo const & bindingInfo) +{ + return GetOrCreateBuffer(bindingInfo, m_staticBuffers); +} + +RefPointer VertexArrayBuffer::GetBuffer(BindingInfo const & bindingInfo, const buffers_map_t & buffers) const +{ + buffers_map_t::const_iterator it = buffers.find(bindingInfo); + if (it == buffers.end()) + return RefPointer(); + + return it->second.GetRefPointer(); +} + +RefPointer VertexArrayBuffer::GetOrCreateBuffer(BindingInfo const & bindingInfo, buffers_map_t & buffers) +{ + buffers_map_t::iterator it = buffers.find(bindingInfo); + if (it == buffers.end()) { - MasterPointer & buffer = m_buffers[bindingInfo]; + MasterPointer & buffer = buffers[bindingInfo]; buffer.Reset(new DataBuffer(bindingInfo.GetElementSize(), m_dataBufferSize)); return buffer.GetRefPointer(); } @@ -87,32 +117,32 @@ uint16_t VertexArrayBuffer::GetAvailableIndexCount() const uint16_t VertexArrayBuffer::GetAvailableVertexCount() const { - if (m_buffers.empty()) + if (m_staticBuffers.empty()) return m_dataBufferSize; #ifdef DEBUG - buffers_map_t::const_iterator it = m_buffers.begin(); + buffers_map_t::const_iterator it = m_staticBuffers.begin(); uint16_t prev = it->second->GetAvailableSize(); - for (; it != m_buffers.end(); ++it) + for (; it != m_staticBuffers.end(); ++it) ASSERT(prev == it->second->GetAvailableSize(), ()); #endif - return m_buffers.begin()->second->GetAvailableSize(); + return m_staticBuffers.begin()->second->GetAvailableSize(); } uint16_t VertexArrayBuffer::GetStartIndexValue() const { - if (m_buffers.empty()) + if (m_staticBuffers.empty()) return 0; #ifdef DEBUG - buffers_map_t::const_iterator it = m_buffers.begin(); + buffers_map_t::const_iterator it = m_staticBuffers.begin(); uint16_t prev = it->second->GetCurrentSize(); - for (; it != m_buffers.end(); ++it) + for (; it != m_staticBuffers.end(); ++it) ASSERT(prev == it->second->GetCurrentSize(), ()); #endif - return m_buffers.begin()->second->GetCurrentSize(); + return m_staticBuffers.begin()->second->GetCurrentSize(); } bool VertexArrayBuffer::IsFilled() const @@ -137,10 +167,20 @@ void VertexArrayBuffer::Bind() GLFunctions::glBindVertexArray(m_VAO); } -void VertexArrayBuffer::BindBuffers() +void VertexArrayBuffer::BindStaticBuffers() { - buffers_map_t::iterator it = m_buffers.begin(); - for (; it != m_buffers.end(); ++it) + BindBuffers(m_staticBuffers); +} + +void VertexArrayBuffer::BindDynamicBuffers() +{ + BindBuffers(m_dynamicBuffers); +} + +void VertexArrayBuffer::BindBuffers(buffers_map_t const & buffers) +{ + buffers_map_t::const_iterator it = buffers.begin(); + for (; it != buffers.end(); ++it) { BindingInfo const & binding = it->first; RefPointer buffer = it->second.GetRefPointer(); diff --git a/drape/vertex_array_buffer.hpp b/drape/vertex_array_buffer.hpp index 46378a05da..a99ae5165b 100644 --- a/drape/vertex_array_buffer.hpp +++ b/drape/vertex_array_buffer.hpp @@ -10,6 +10,7 @@ class VertexArrayBuffer { + typedef map > buffers_map_t; public: VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBufferSize); ~VertexArrayBuffer(); @@ -31,18 +32,21 @@ public: void UploadIndexes(uint16_t const * data, uint16_t count); private: - friend class IndexBufferMutator; - void UpdateIndexBuffer(uint16_t const * data, uint16_t count); + RefPointer GetOrCreateStaticBuffer(BindingInfo const & bindingInfo); + RefPointer GetOrCreateDynamicBuffer(BindingInfo const & bindingInfo); + RefPointer GetDynamicBuffer(BindingInfo const & bindingInfo) const; -private: - RefPointer GetBuffer(BindingInfo const & bindingInfo); + RefPointer GetOrCreateBuffer(BindingInfo const & bindingInfo, buffers_map_t & buffers); + RefPointer GetBuffer(BindingInfo const & bindingInfo, buffers_map_t const & buffers) const; void Bind(); - void BindBuffers(); + void BindStaticBuffers(); + void BindDynamicBuffers(); + void BindBuffers(buffers_map_t const & buffers); private: int m_VAO; - typedef map > buffers_map_t; - buffers_map_t m_buffers; + buffers_map_t m_staticBuffers; + buffers_map_t m_dynamicBuffers; MasterPointer m_indexBuffer; uint32_t m_dataBufferSize;