diff --git a/include/CMeshBuffer.h b/include/CMeshBuffer.h index fe84fb9f..6233bbe5 100644 --- a/include/CMeshBuffer.h +++ b/include/CMeshBuffer.h @@ -21,6 +21,7 @@ namespace scene CMeshBuffer() : ChangedID_Vertex(1), ChangedID_Index(1) , MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER) + , HWBuffer(NULL) , PrimitiveType(EPT_TRIANGLES) { #ifdef _DEBUG @@ -286,12 +287,22 @@ namespace scene /** This shouldn't be used for anything outside the VideoDriver. */ virtual u32 getChangedID_Index() const _IRR_OVERRIDE_ {return ChangedID_Index;} + virtual void setHWBuffer(void *ptr) const _IRR_OVERRIDE_ { + HWBuffer = ptr; + } + + virtual void *getHWBuffer() const _IRR_OVERRIDE_ { + return HWBuffer; + } + + u32 ChangedID_Vertex; u32 ChangedID_Index; //! hardware mapping hint E_HARDWARE_MAPPING MappingHint_Vertex; E_HARDWARE_MAPPING MappingHint_Index; + mutable void *HWBuffer; //! Material for this meshbuffer. video::SMaterial Material; diff --git a/include/IMeshBuffer.h b/include/IMeshBuffer.h index 488eb029..a2cd13a4 100644 --- a/include/IMeshBuffer.h +++ b/include/IMeshBuffer.h @@ -145,6 +145,10 @@ namespace scene /** This shouldn't be used for anything outside the VideoDriver. */ virtual u32 getChangedID_Index() const = 0; + //! Used by the VideoDriver to remember the buffer link. + virtual void setHWBuffer(void *ptr) const = 0; + virtual void *getHWBuffer() const = 0; + //! Describe what kind of primitive geometry is used by the meshbuffer /** Note: Default is EPT_TRIANGLES. Using other types is fine for rendering. But meshbuffer manipulation functions might expect type EPT_TRIANGLES diff --git a/include/SSkinMeshBuffer.h b/include/SSkinMeshBuffer.h index a6c2b68d..809bd680 100644 --- a/include/SSkinMeshBuffer.h +++ b/include/SSkinMeshBuffer.h @@ -23,6 +23,7 @@ struct SSkinMeshBuffer : public IMeshBuffer ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt), PrimitiveType(EPT_TRIANGLES), MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER), + HWBuffer(NULL), BoundingBoxNeedsRecalculated(true) { #ifdef _DEBUG @@ -383,6 +384,15 @@ struct SSkinMeshBuffer : public IMeshBuffer virtual u32 getChangedID_Index() const _IRR_OVERRIDE_ {return ChangedID_Index;} + virtual void setHWBuffer(void *ptr) const _IRR_OVERRIDE_ { + HWBuffer = ptr; + } + + virtual void *getHWBuffer() const _IRR_OVERRIDE_ { + return HWBuffer; + } + + //! Call this after changing the positions of any vertex. void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; } @@ -409,6 +419,8 @@ struct SSkinMeshBuffer : public IMeshBuffer E_HARDWARE_MAPPING MappingHint_Vertex:3; E_HARDWARE_MAPPING MappingHint_Index:3; + mutable void *HWBuffer; + bool BoundingBoxNeedsRecalculated:1; }; diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp index 20ee0938..98b2bf77 100644 --- a/source/Irrlicht/CNullDriver.cpp +++ b/source/Irrlicht/CNullDriver.cpp @@ -1689,9 +1689,9 @@ CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* return 0; //search for hardware links - core::map< const scene::IMeshBuffer*,SHWBufferLink* >::Node* node = HWBufferMap.find(mb); - if (node) - return node->getValue(); + SHWBufferLink *HWBuffer = reinterpret_cast(mb->getHWBuffer()); + if (HWBuffer) + return HWBuffer; return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it } @@ -1700,20 +1700,13 @@ CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* //! Update all hardware buffers, remove unused ones void CNullDriver::updateAllHardwareBuffers() { - core::map::ParentFirstIterator Iterator=HWBufferMap.getParentFirstIterator(); + auto it = HWBufferList.begin(); + while (it != HWBufferList.end()) { + SHWBufferLink *Link = *it; + ++it; - for (;!Iterator.atEnd();Iterator++) - { - SHWBufferLink *Link=Iterator.getNode()->getValue(); - - Link->LastUsed++; - if (Link->LastUsed>20000) - { + if (!Link->MeshBuffer || Link->MeshBuffer->getReferenceCount() == 1) deleteHardwareBuffer(Link); - - // todo: needs better fix - Iterator = HWBufferMap.getParentFirstIterator(); - } } } @@ -1722,7 +1715,7 @@ void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer) { if (!HWBuffer) return; - HWBufferMap.remove(HWBuffer->MeshBuffer); + HWBufferList.erase(HWBuffer->listPosition); delete HWBuffer; } @@ -1730,17 +1723,19 @@ void CNullDriver::deleteHardwareBuffer(SHWBufferLink *HWBuffer) //! Remove hardware buffer void CNullDriver::removeHardwareBuffer(const scene::IMeshBuffer* mb) { - core::map::Node* node = HWBufferMap.find(mb); - if (node) - deleteHardwareBuffer(node->getValue()); + if (!mb) + return; + SHWBufferLink *HWBuffer = reinterpret_cast(mb->getHWBuffer()); + if (HWBuffer) + deleteHardwareBuffer(HWBuffer); } //! Remove all hardware buffers void CNullDriver::removeAllHardwareBuffers() { - while (HWBufferMap.size()) - deleteHardwareBuffer(HWBufferMap.getRoot()->getValue()); + while (!HWBufferList.empty()) + deleteHardwareBuffer(HWBufferList.front()); } diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h index e95931f4..c9960f9a 100644 --- a/source/Irrlicht/CNullDriver.h +++ b/source/Irrlicht/CNullDriver.h @@ -21,6 +21,7 @@ #include "SVertexIndex.h" #include "SLight.h" #include "SExposedVideoData.h" +#include namespace irr { @@ -388,25 +389,29 @@ namespace video { SHWBufferLink(const scene::IMeshBuffer *_MeshBuffer) :MeshBuffer(_MeshBuffer), - ChangedID_Vertex(0),ChangedID_Index(0),LastUsed(0), + ChangedID_Vertex(0),ChangedID_Index(0), Mapped_Vertex(scene::EHM_NEVER),Mapped_Index(scene::EHM_NEVER) { - if (MeshBuffer) + if (MeshBuffer) { MeshBuffer->grab(); + MeshBuffer->setHWBuffer(reinterpret_cast(this)); + } } virtual ~SHWBufferLink() { - if (MeshBuffer) + if (MeshBuffer) { + MeshBuffer->setHWBuffer(NULL); MeshBuffer->drop(); + } } const scene::IMeshBuffer *MeshBuffer; u32 ChangedID_Vertex; u32 ChangedID_Index; - u32 LastUsed; scene::E_HARDWARE_MAPPING Mapped_Vertex; scene::E_HARDWARE_MAPPING Mapped_Index; + std::list::iterator listPosition; }; //! Gets hardware buffer link from a meshbuffer (may create or update buffer) @@ -818,8 +823,7 @@ namespace video core::array Lights; core::array MaterialRenderers; - //core::array HWBufferLinks; - core::map< const scene::IMeshBuffer* , SHWBufferLink* > HWBufferMap; + std::list HWBufferList; io::IFileSystem* FileSystem; diff --git a/source/Irrlicht/COGLES2Driver.cpp b/source/Irrlicht/COGLES2Driver.cpp index 87d93c1f..14e28c21 100644 --- a/source/Irrlicht/COGLES2Driver.cpp +++ b/source/Irrlicht/COGLES2Driver.cpp @@ -589,13 +589,12 @@ COGLES2Driver::~COGLES2Driver() SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(mb); //add to map - HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer); + HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer); HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex(); HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index(); HWBuffer->Mapped_Vertex = mb->getHardwareMappingHint_Vertex(); HWBuffer->Mapped_Index = mb->getHardwareMappingHint_Index(); - HWBuffer->LastUsed = 0; HWBuffer->vbo_verticesID = 0; HWBuffer->vbo_indicesID = 0; HWBuffer->vbo_verticesSize = 0; @@ -642,8 +641,6 @@ COGLES2Driver::~COGLES2Driver() updateHardwareBuffer(HWBuffer); //check if update is needed - HWBuffer->LastUsed = 0;//reset count - const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; const void *vertices = mb->getVertices(); const void *indexList = mb->getIndices(); diff --git a/source/Irrlicht/COGLESDriver.cpp b/source/Irrlicht/COGLESDriver.cpp index 44154023..a48909e1 100644 --- a/source/Irrlicht/COGLESDriver.cpp +++ b/source/Irrlicht/COGLESDriver.cpp @@ -456,13 +456,12 @@ COGLES1Driver::SHWBufferLink *COGLES1Driver::createHardwareBuffer(const scene::I SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb); //add to map - HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer); + HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer); HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex(); HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index(); HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); - HWBuffer->LastUsed=0; HWBuffer->vbo_verticesID=0; HWBuffer->vbo_indicesID=0; HWBuffer->vbo_verticesSize=0; @@ -509,8 +508,6 @@ void COGLES1Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) updateHardwareBuffer(HWBuffer); //check if update is needed - HWBuffer->LastUsed=0;//reset count - const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; const void *vertices=mb->getVertices(); const void *indexList=mb->getIndices(); diff --git a/source/Irrlicht/COpenGLDriver.cpp b/source/Irrlicht/COpenGLDriver.cpp index bde8ddc8..c03ac342 100644 --- a/source/Irrlicht/COpenGLDriver.cpp +++ b/source/Irrlicht/COpenGLDriver.cpp @@ -571,13 +571,12 @@ COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::I SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb); //add to map - HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer); + HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer); HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex(); HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index(); HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); - HWBuffer->LastUsed=0; HWBuffer->vbo_verticesID=0; HWBuffer->vbo_indicesID=0; HWBuffer->vbo_verticesSize=0; @@ -626,7 +625,6 @@ void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) return; updateHardwareBuffer(_HWBuffer); //check if update is needed - _HWBuffer->LastUsed=0; //reset count #if defined(GL_ARB_vertex_buffer_object) SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;