Changed std::map to boost::unordered_map for storing memory chunks and groups information.

This commit is contained in:
Maciej Suminski 2013-07-01 13:20:48 +02:00
parent 00847a8aed
commit a73216fc95
4 changed files with 53 additions and 30 deletions

View File

@ -26,8 +26,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <cmath>
#include <gal/opengl/opengl_gal.h>
#include <gal/opengl/vbo_container.h>
#include <gal/definitions.h>
@ -39,6 +37,7 @@
#endif /* __WXDEBUG__ */
#include <limits>
#include <boost/foreach.hpp>
#ifndef CALLBACK
#define CALLBACK
@ -82,7 +81,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
groupCounter = 0;
transform = glm::mat4( 1.0f ); // Identity matrix
SetSize( parentSize );
screenSize.x = parentSize.x;
@ -1606,10 +1604,9 @@ void OPENGL_GAL::EndGroup()
void OPENGL_GAL::ClearCache()
{
std::map<unsigned int, VBO_ITEM*>::iterator it, end;
for( it = groups.begin(), end = groups.end(); it != end; it++ )
BOOST_FOREACH( GroupsMap::value_type it, groups )
{
delete it->second;
delete it.second;
}
groups.clear();

View File

@ -30,6 +30,7 @@
#include <gal/opengl/vbo_container.h>
#include <cstring>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <wx/log.h>
#ifdef __WXDEBUG__
#include <profile.h>
@ -38,7 +39,8 @@
using namespace KiGfx;
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
m_shader[0] = 0;
@ -82,6 +84,7 @@ void VBO_CONTAINER::EndItem()
m_freeSpace += ( itemChunkSize - itemSize );
}
item = NULL;
itemStarted = false;
}
@ -91,6 +94,9 @@ void VBO_CONTAINER::Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned
unsigned int offset;
VBO_VERTEX* vertexPtr;
if( m_failed )
return;
if( itemStarted ) // There is an item being created with an unknown size..
{
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
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 );
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;
itemChunkOffset = allocate( aVboItem, newSize );
aVboItem->SetOffset( itemChunkOffset );
// Check if there was no error
if( itemChunkOffset > m_currentSize )
{
m_failed = true;
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 );
// Free the space previously used by the chunk
freeChunk( it );
// Copy all the old data
memcpy( &m_vertices[itemChunkOffset], &m_vertices[oldItemChunkOffset],
itemSize * VBO_ITEM::VertByteSize );
// Return memory used by the previous chunk
freeChunk( it );
itemChunkSize = newSize;
}
else
@ -310,7 +323,8 @@ bool VBO_CONTAINER::defragment( VBO_VERTEX* aTarget )
memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VBO_ITEM::VertByteSize );
// Update new offset
vboItem->SetOffset( newOffset );
if( vboItem )
vboItem->SetOffset( newOffset );
setChunkOffset( *it, newOffset );
// 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 )
{
unsigned int copySize;
VBO_VERTEX* newContainer;
if( aNewSize < m_currentSize )
{
// Sanity check, no shrinking if we cannot fit all the data
if( ( m_currentSize - m_freeSpace ) > aNewSize )
return false;
defragment();
copySize = ( m_currentSize - m_freeSpace );
newContainer = static_cast<VBO_VERTEX*>( malloc( aNewSize * sizeof( VBO_VERTEX ) ) );
if( newContainer == NULL )
{
wxLogError( wxT( "Run out of memory" ) );
return false;
}
// Defragment directly to the new, smaller container
defragment( newContainer );
}
else
{
copySize = m_currentSize;
}
VBO_VERTEX* newContainer = static_cast<VBO_VERTEX*>( realloc( m_vertices, aNewSize * sizeof( VBO_VERTEX ) ) );
if( newContainer == NULL )
{
wxLogError( wxT( "Run out of memory" ) );
return false;
newContainer = static_cast<VBO_VERTEX*>( realloc( m_vertices, aNewSize * sizeof( VBO_VERTEX ) ) );
if( newContainer == NULL )
{
wxLogError( wxT( "Run out of memory" ) );
return false;
}
}
m_vertices = newContainer;

View File

@ -49,6 +49,7 @@
#include <iterator>
#include <vector>
#include <algorithm>
#include <boost/unordered_map.hpp>
#include <stdlib.h>
#include <iostream>
@ -355,7 +356,8 @@ private:
GLuint displayListSemiCircle; ///< Semi circle display list
// 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
VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping)
VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs
@ -559,7 +561,7 @@ private:
if( isGrouping )
{
// New vertex coordinates for VBO
VBO_VERTEX vertex = { aX, aY, aZ };
const VBO_VERTEX vertex = { aX, aY, aZ };
currentGroup->PushVertex( &vertex );
}
else

View File

@ -35,6 +35,7 @@
#include <gal/opengl/vbo_item.h>
#include <gal/color4d.h>
#include <map>
#include <boost/unordered_map.hpp>
#include <wx/log.h>
namespace KiGfx
@ -52,9 +53,9 @@ public:
typedef std::pair<const unsigned int, unsigned int> Chunk;
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::multimap<VBO_ITEM* const, Chunk> ReservedChunkMap;
typedef boost::unordered_map<VBO_ITEM* const, Chunk> ReservedChunkMap;
/**
* Function StartItem()
@ -115,7 +116,7 @@ public:
/**
* Function GetVertices()
* 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
{
@ -326,6 +327,9 @@ private:
///< Current transform matrix applied for every new vertex pushed.
const glm::mat4* m_transform;
///< Failure flag
bool m_failed;
/**
* Function getPowerOf2()
* Returns the nearest power of 2, bigger than aNumber.