Changed std::map to boost::unordered_map for storing memory chunks and groups information.
This commit is contained in:
parent
00847a8aed
commit
a73216fc95
|
@ -26,8 +26,6 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include <gal/opengl/opengl_gal.h>
|
#include <gal/opengl/opengl_gal.h>
|
||||||
#include <gal/opengl/vbo_container.h>
|
#include <gal/opengl/vbo_container.h>
|
||||||
#include <gal/definitions.h>
|
#include <gal/definitions.h>
|
||||||
|
@ -39,6 +37,7 @@
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#ifndef CALLBACK
|
#ifndef CALLBACK
|
||||||
#define CALLBACK
|
#define CALLBACK
|
||||||
|
@ -82,7 +81,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
||||||
groupCounter = 0;
|
groupCounter = 0;
|
||||||
transform = glm::mat4( 1.0f ); // Identity matrix
|
transform = glm::mat4( 1.0f ); // Identity matrix
|
||||||
|
|
||||||
|
|
||||||
SetSize( parentSize );
|
SetSize( parentSize );
|
||||||
|
|
||||||
screenSize.x = parentSize.x;
|
screenSize.x = parentSize.x;
|
||||||
|
@ -1606,10 +1604,9 @@ void OPENGL_GAL::EndGroup()
|
||||||
|
|
||||||
void OPENGL_GAL::ClearCache()
|
void OPENGL_GAL::ClearCache()
|
||||||
{
|
{
|
||||||
std::map<unsigned int, VBO_ITEM*>::iterator it, end;
|
BOOST_FOREACH( GroupsMap::value_type it, groups )
|
||||||
for( it = groups.begin(), end = groups.end(); it != end; it++ )
|
|
||||||
{
|
{
|
||||||
delete it->second;
|
delete it.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
groups.clear();
|
groups.clear();
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include <gal/opengl/vbo_container.h>
|
#include <gal/opengl/vbo_container.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
|
@ -38,7 +39,8 @@
|
||||||
using namespace KiGfx;
|
using namespace KiGfx;
|
||||||
|
|
||||||
VBO_CONTAINER::VBO_CONTAINER( int aSize ) :
|
VBO_CONTAINER::VBO_CONTAINER( int aSize ) :
|
||||||
m_freeSpace( aSize ), m_currentSize( aSize ), itemStarted( false ), m_transform( NULL )
|
m_freeSpace( aSize ), m_currentSize( aSize ), itemStarted( false ), m_transform( NULL ),
|
||||||
|
m_failed( false )
|
||||||
{
|
{
|
||||||
// By default no shader is used
|
// By default no shader is used
|
||||||
m_shader[0] = 0;
|
m_shader[0] = 0;
|
||||||
|
@ -82,6 +84,7 @@ void VBO_CONTAINER::EndItem()
|
||||||
m_freeSpace += ( itemChunkSize - itemSize );
|
m_freeSpace += ( itemChunkSize - itemSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item = NULL;
|
||||||
itemStarted = false;
|
itemStarted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +94,9 @@ void VBO_CONTAINER::Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
VBO_VERTEX* vertexPtr;
|
VBO_VERTEX* vertexPtr;
|
||||||
|
|
||||||
|
if( m_failed )
|
||||||
|
return;
|
||||||
|
|
||||||
if( itemStarted ) // There is an item being created with an unknown size..
|
if( itemStarted ) // There is an item being created with an unknown size..
|
||||||
{
|
{
|
||||||
unsigned int itemChunkOffset;
|
unsigned int itemChunkOffset;
|
||||||
|
@ -98,27 +104,34 @@ void VBO_CONTAINER::Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned
|
||||||
// ..and unfortunately does not fit into currently reserved chunk
|
// ..and unfortunately does not fit into currently reserved chunk
|
||||||
if( itemSize + aSize > itemChunkSize )
|
if( itemSize + aSize > itemChunkSize )
|
||||||
{
|
{
|
||||||
// Find the previous chunk for the item, save it, so it can be removed later
|
// Find the previous chunk for the item and change mark it as NULL
|
||||||
|
// so it will not be removed during a possible defragmentation
|
||||||
ReservedChunkMap::iterator it = m_reservedChunks.find( item );
|
ReservedChunkMap::iterator it = m_reservedChunks.find( item );
|
||||||
|
m_reservedChunks.insert( ReservedChunk( static_cast<VBO_ITEM*>( NULL ), it->second ) );
|
||||||
|
m_reservedChunks.erase( it );
|
||||||
|
|
||||||
// Reserve bigger memory for the current item
|
// Reserve bigger memory fo r the current item
|
||||||
int newSize = ( 2 * itemSize ) + aSize;
|
int newSize = ( 2 * itemSize ) + aSize;
|
||||||
itemChunkOffset = allocate( aVboItem, newSize );
|
itemChunkOffset = allocate( aVboItem, newSize );
|
||||||
|
aVboItem->SetOffset( itemChunkOffset );
|
||||||
|
|
||||||
// Check if there was no error
|
// Check if there was no error
|
||||||
if( itemChunkOffset > m_currentSize )
|
if( itemChunkOffset > m_currentSize )
|
||||||
|
{
|
||||||
|
m_failed = true;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Save previous chunk's offset for copying data
|
it = m_reservedChunks.find( static_cast<VBO_ITEM*>( NULL ) );
|
||||||
|
// Check if the chunk was not reallocated after defragmentation
|
||||||
int oldItemChunkOffset = getChunkOffset( *it );
|
int oldItemChunkOffset = getChunkOffset( *it );
|
||||||
|
// Free the space previously used by the chunk
|
||||||
|
freeChunk( it );
|
||||||
|
|
||||||
// Copy all the old data
|
// Copy all the old data
|
||||||
memcpy( &m_vertices[itemChunkOffset], &m_vertices[oldItemChunkOffset],
|
memcpy( &m_vertices[itemChunkOffset], &m_vertices[oldItemChunkOffset],
|
||||||
itemSize * VBO_ITEM::VertByteSize );
|
itemSize * VBO_ITEM::VertByteSize );
|
||||||
|
|
||||||
// Return memory used by the previous chunk
|
|
||||||
freeChunk( it );
|
|
||||||
|
|
||||||
itemChunkSize = newSize;
|
itemChunkSize = newSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -310,7 +323,8 @@ bool VBO_CONTAINER::defragment( VBO_VERTEX* aTarget )
|
||||||
memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VBO_ITEM::VertByteSize );
|
memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VBO_ITEM::VertByteSize );
|
||||||
|
|
||||||
// Update new offset
|
// Update new offset
|
||||||
vboItem->SetOffset( newOffset );
|
if( vboItem )
|
||||||
|
vboItem->SetOffset( newOffset );
|
||||||
setChunkOffset( *it, newOffset );
|
setChunkOffset( *it, newOffset );
|
||||||
|
|
||||||
// Move to the next free space
|
// Move to the next free space
|
||||||
|
@ -349,26 +363,32 @@ void VBO_CONTAINER::resizeChunk( VBO_ITEM* aVboItem, int aNewSize )
|
||||||
|
|
||||||
bool VBO_CONTAINER::resizeContainer( unsigned int aNewSize )
|
bool VBO_CONTAINER::resizeContainer( unsigned int aNewSize )
|
||||||
{
|
{
|
||||||
unsigned int copySize;
|
VBO_VERTEX* newContainer;
|
||||||
|
|
||||||
if( aNewSize < m_currentSize )
|
if( aNewSize < m_currentSize )
|
||||||
{
|
{
|
||||||
// Sanity check, no shrinking if we cannot fit all the data
|
// Sanity check, no shrinking if we cannot fit all the data
|
||||||
if( ( m_currentSize - m_freeSpace ) > aNewSize )
|
if( ( m_currentSize - m_freeSpace ) > aNewSize )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
defragment();
|
newContainer = static_cast<VBO_VERTEX*>( malloc( aNewSize * sizeof( VBO_VERTEX ) ) );
|
||||||
copySize = ( m_currentSize - m_freeSpace );
|
if( newContainer == NULL )
|
||||||
|
{
|
||||||
|
wxLogError( wxT( "Run out of memory" ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defragment directly to the new, smaller container
|
||||||
|
defragment( newContainer );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
copySize = m_currentSize;
|
newContainer = static_cast<VBO_VERTEX*>( realloc( m_vertices, aNewSize * sizeof( VBO_VERTEX ) ) );
|
||||||
}
|
if( newContainer == NULL )
|
||||||
|
{
|
||||||
VBO_VERTEX* newContainer = static_cast<VBO_VERTEX*>( realloc( m_vertices, aNewSize * sizeof( VBO_VERTEX ) ) );
|
wxLogError( wxT( "Run out of memory" ) );
|
||||||
if( newContainer == NULL )
|
return false;
|
||||||
{
|
}
|
||||||
wxLogError( wxT( "Run out of memory" ) );
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vertices = newContainer;
|
m_vertices = newContainer;
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -355,7 +356,8 @@ private:
|
||||||
GLuint displayListSemiCircle; ///< Semi circle display list
|
GLuint displayListSemiCircle; ///< Semi circle display list
|
||||||
|
|
||||||
// Vertex buffer objects related fields
|
// Vertex buffer objects related fields
|
||||||
std::map<unsigned int, VBO_ITEM*> groups; ///< Stores informations about VBO objects (groups)
|
typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap;
|
||||||
|
GroupsMap groups; ///< Stores informations about VBO objects (groups)
|
||||||
unsigned int groupCounter; ///< Counter used for generating keys for groups
|
unsigned int groupCounter; ///< Counter used for generating keys for groups
|
||||||
VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping)
|
VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping)
|
||||||
VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs
|
VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs
|
||||||
|
@ -559,7 +561,7 @@ private:
|
||||||
if( isGrouping )
|
if( isGrouping )
|
||||||
{
|
{
|
||||||
// New vertex coordinates for VBO
|
// New vertex coordinates for VBO
|
||||||
VBO_VERTEX vertex = { aX, aY, aZ };
|
const VBO_VERTEX vertex = { aX, aY, aZ };
|
||||||
currentGroup->PushVertex( &vertex );
|
currentGroup->PushVertex( &vertex );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <gal/opengl/vbo_item.h>
|
#include <gal/opengl/vbo_item.h>
|
||||||
#include <gal/color4d.h>
|
#include <gal/color4d.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <boost/unordered_map.hpp>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
|
||||||
namespace KiGfx
|
namespace KiGfx
|
||||||
|
@ -52,9 +53,9 @@ public:
|
||||||
typedef std::pair<const unsigned int, unsigned int> Chunk;
|
typedef std::pair<const unsigned int, unsigned int> Chunk;
|
||||||
typedef std::multimap<const unsigned int, unsigned int> FreeChunkMap;
|
typedef std::multimap<const unsigned int, unsigned int> FreeChunkMap;
|
||||||
|
|
||||||
///< Maps size of reserved memory chunks to their owners (VBO_ITEMs)
|
///< Maps VBO_ITEMs to reserved memory chunks offsets & sizes
|
||||||
typedef std::pair<VBO_ITEM* const, Chunk> ReservedChunk;
|
typedef std::pair<VBO_ITEM* const, Chunk> ReservedChunk;
|
||||||
typedef std::multimap<VBO_ITEM* const, Chunk> ReservedChunkMap;
|
typedef boost::unordered_map<VBO_ITEM* const, Chunk> ReservedChunkMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function StartItem()
|
* Function StartItem()
|
||||||
|
@ -115,7 +116,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Function GetVertices()
|
* Function GetVertices()
|
||||||
* Returns vertices stored at the specific offset.
|
* Returns vertices stored at the specific offset.
|
||||||
* @aOffest is the specific offset.
|
* @aOffset is the specific offset.
|
||||||
*/
|
*/
|
||||||
inline VBO_VERTEX* GetVertices( unsigned int aOffset ) const
|
inline VBO_VERTEX* GetVertices( unsigned int aOffset ) const
|
||||||
{
|
{
|
||||||
|
@ -326,6 +327,9 @@ private:
|
||||||
///< Current transform matrix applied for every new vertex pushed.
|
///< Current transform matrix applied for every new vertex pushed.
|
||||||
const glm::mat4* m_transform;
|
const glm::mat4* m_transform;
|
||||||
|
|
||||||
|
///< Failure flag
|
||||||
|
bool m_failed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function getPowerOf2()
|
* Function getPowerOf2()
|
||||||
* Returns the nearest power of 2, bigger than aNumber.
|
* Returns the nearest power of 2, bigger than aNumber.
|
||||||
|
|
Loading…
Reference in New Issue