diff --git a/yg/blitter.cpp b/yg/blitter.cpp index ea44cf76e8..e2ba491b50 100644 --- a/yg/blitter.cpp +++ b/yg/blitter.cpp @@ -150,6 +150,9 @@ namespace yg // /// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone. // OGLCHECK(glFinish()); + storage.m_vertices->discard(); + storage.m_indices->discard(); + resourceManager()->multiBlitStorages()->Free(storage); } @@ -357,6 +360,9 @@ namespace yg // /// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone. // OGLCHECK(glFinish()); + blitStorage.m_vertices->discard(); + blitStorage.m_indices->discard(); + m_resourceManager->blitStorages()->Free(blitStorage); } } diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index f3965b5069..51b9125e98 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -336,10 +336,27 @@ namespace yg { GeometryPipeline & pipeline = m_pipelines[pipelineID]; - Storage storage = pipeline.m_storage; - shared_ptr command(new UnlockStorage()); - command->m_storage = storage; + command->m_storage = pipeline.m_storage; + + processCommand(command); + } + + void GeometryBatcher::DiscardStorage::perform() + { + if (isDebugging()) + LOG(LINFO, ("performing DiscardStorage command")); + + m_storage.m_vertices->discard(); + m_storage.m_indices->discard(); + } + + void GeometryBatcher::discardPipeline(int pipelineID) + { + GeometryPipeline & pipeline = m_pipelines[pipelineID]; + + shared_ptr command(new DiscardStorage()); + command->m_storage = pipeline.m_storage; processCommand(command); } @@ -361,6 +378,8 @@ namespace yg pipeline.m_storage.m_indices, pipeline.m_currentIndex); + discardPipeline(pipelineID); + if (isDebugging()) { diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index 3fbd7e4e9b..b298ca58d5 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -107,6 +107,13 @@ namespace yg void perform(); }; + struct DiscardStorage : public Command + { + Storage m_storage; + + void perform(); + }; + public: /// INTERNAL API! USE WITH CAUTION @@ -135,6 +142,7 @@ namespace yg void flushPipeline(shared_ptr const & skinPage, int pipelineID); void unlockPipeline(int pipelineID); + void discardPipeline(int pipelineID); public: diff --git a/yg/indexbuffer.cpp b/yg/indexbuffer.cpp index 8bf31e04fd..8cb673f580 100644 --- a/yg/indexbuffer.cpp +++ b/yg/indexbuffer.cpp @@ -1,6 +1,7 @@ #include "../base/SRC_FIRST.hpp" #include "../base/logging.hpp" #include "../base/assert.hpp" +#include "../base/shared_buffer_manager.hpp" #include "internal/opengl.hpp" @@ -40,14 +41,10 @@ namespace yg ASSERT(!m_isLocked, ()); if (size != m_size) { + discard(); m_size = size; makeCurrent(); - if (m_useVA) - { - delete [] (unsigned char*) m_gpuData; - m_gpuData = new unsigned char[size]; - } - else + if (!m_useVA) OGLCHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW)); } } @@ -80,7 +77,13 @@ namespace yg m_isLocked = true; if (m_useVA) + { + if (!m_sharedBuffer) + m_sharedBuffer = SharedBufferManager::instance().reserveSharedBuffer(m_size); + + m_gpuData = &m_sharedBuffer->at(0); return m_gpuData; + } makeCurrent(); @@ -115,6 +118,19 @@ namespace yg m_gpuData = 0; } + void IndexBuffer::discard() + { + if (m_useVA) + { + if (m_sharedBuffer) + { + SharedBufferManager::instance().freeSharedBuffer(m_size, m_sharedBuffer); + m_sharedBuffer.reset(); + m_gpuData = 0; + } + } + } + void IndexBuffer::makeCurrent() { if (m_useVA) diff --git a/yg/indexbuffer.hpp b/yg/indexbuffer.hpp index d2b3f52083..1121d3f56e 100644 --- a/yg/indexbuffer.hpp +++ b/yg/indexbuffer.hpp @@ -1,5 +1,8 @@ #pragma once +#include "../std/vector.hpp" +#include "../std/shared_ptr.hpp" + namespace yg { namespace gl @@ -13,6 +16,7 @@ namespace yg void * m_gpuData; bool m_useVA; bool m_isLocked; + shared_ptr > m_sharedBuffer; public: @@ -24,8 +28,10 @@ namespace yg size_t size() const; void makeCurrent(); + void * lock(); void unlock(); + void discard(); void * glPtr(); void * data(); diff --git a/yg/vertexbuffer.cpp b/yg/vertexbuffer.cpp index 373e12f81e..a6b7a1956a 100644 --- a/yg/vertexbuffer.cpp +++ b/yg/vertexbuffer.cpp @@ -1,5 +1,6 @@ #include "../base/SRC_FIRST.hpp" #include "../base/logging.hpp" +#include "../base/shared_buffer_manager.hpp" #include "../base/assert.hpp" #include "internal/opengl.hpp" @@ -38,16 +39,14 @@ namespace yg void VertexBuffer::resize(size_t size) { ASSERT(!m_isLocked, ()); + if (size != m_size) { + discard(); + m_size = size; makeCurrent(); - if (m_useVA) - { - delete [] (unsigned char*)m_gpuData; - m_gpuData = new unsigned char [size]; - } - else + if (!m_useVA) OGLCHECK(glBufferData(GL_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW)); } } @@ -59,11 +58,8 @@ namespace yg VertexBuffer::~VertexBuffer() { - if (m_useVA) - delete [] (unsigned char*)m_gpuData; - else - if (g_doDeleteOnDestroy) - OGLCHECK(glDeleteBuffers(1, &m_id)); + if ((!m_useVA) && (g_doDeleteOnDestroy)) + OGLCHECK(glDeleteBuffers(1, &m_id)); } void * VertexBuffer::data() @@ -78,7 +74,13 @@ namespace yg m_isLocked = true; if (m_useVA) + { + if (!m_sharedBuffer) + m_sharedBuffer = SharedBufferManager::instance().reserveSharedBuffer(m_size); + + m_gpuData = &m_sharedBuffer->at(0); return m_gpuData; + } makeCurrent(); @@ -113,6 +115,19 @@ namespace yg m_gpuData = 0; } + void VertexBuffer::discard() + { + if (m_useVA) + { + if (m_sharedBuffer) + { + SharedBufferManager::instance().freeSharedBuffer(m_size, m_sharedBuffer); + m_sharedBuffer.reset(); + m_gpuData = 0; + } + } + } + void * VertexBuffer::glPtr() { if (m_useVA) diff --git a/yg/vertexbuffer.hpp b/yg/vertexbuffer.hpp index 0cf17e65f6..ec62fea777 100644 --- a/yg/vertexbuffer.hpp +++ b/yg/vertexbuffer.hpp @@ -1,5 +1,8 @@ #pragma once +#include "../std/vector.hpp" +#include "../std/shared_ptr.hpp" + namespace yg { namespace gl @@ -12,6 +15,8 @@ namespace yg unsigned int m_size; void * m_gpuData; + shared_ptr > m_sharedBuffer; + /// using VA instead of buffer objects on some old GPU's bool m_useVA; bool m_isLocked; @@ -28,6 +33,7 @@ namespace yg void makeCurrent(); void * lock(); void unlock(); + void discard(); void * glPtr(); void * data(); bool isLocked() const;