Minor refactoring in CACHED_CONTAINER.
This commit is contained in:
parent
b32fdd97d9
commit
01912aaabd
|
@ -34,9 +34,11 @@
|
||||||
#include <gal/opengl/vertex_item.h>
|
#include <gal/opengl/vertex_item.h>
|
||||||
#include <gal/opengl/shader.h>
|
#include <gal/opengl/shader.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <wx/log.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
#ifdef __WXDEBUG__
|
||||||
|
#include <wx/log.h>
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
#endif /* __WXDEBUG__ */
|
#endif /* __WXDEBUG__ */
|
||||||
|
|
||||||
|
@ -57,7 +59,7 @@ CACHED_CONTAINER::CACHED_CONTAINER( unsigned int aSize ) :
|
||||||
|
|
||||||
void CACHED_CONTAINER::SetItem( VERTEX_ITEM* aItem )
|
void CACHED_CONTAINER::SetItem( VERTEX_ITEM* aItem )
|
||||||
{
|
{
|
||||||
wxASSERT( aItem != NULL );
|
assert( aItem != NULL );
|
||||||
|
|
||||||
m_item = aItem;
|
m_item = aItem;
|
||||||
m_itemSize = m_item->GetSize();
|
m_itemSize = m_item->GetSize();
|
||||||
|
@ -76,8 +78,8 @@ void CACHED_CONTAINER::SetItem( VERTEX_ITEM* aItem )
|
||||||
|
|
||||||
void CACHED_CONTAINER::FinishItem()
|
void CACHED_CONTAINER::FinishItem()
|
||||||
{
|
{
|
||||||
wxASSERT( m_item != NULL );
|
assert( m_item != NULL );
|
||||||
wxASSERT( m_item->GetSize() == m_itemSize );
|
assert( m_item->GetSize() == m_itemSize );
|
||||||
|
|
||||||
// Finishing the previously edited item
|
// Finishing the previously edited item
|
||||||
if( m_itemSize < m_chunkSize )
|
if( m_itemSize < m_chunkSize )
|
||||||
|
@ -86,8 +88,7 @@ void CACHED_CONTAINER::FinishItem()
|
||||||
int itemOffset = m_item->GetOffset();
|
int itemOffset = m_item->GetOffset();
|
||||||
|
|
||||||
// Add the not used memory back to the pool
|
// Add the not used memory back to the pool
|
||||||
m_freeChunks.insert( CHUNK( m_chunkSize - m_itemSize, itemOffset + m_itemSize ) );
|
addFreeChunk( itemOffset + m_itemSize, m_chunkSize - m_itemSize );
|
||||||
m_freeSpace += ( m_chunkSize - m_itemSize );
|
|
||||||
// mergeFreeChunks(); // veery slow and buggy
|
// mergeFreeChunks(); // veery slow and buggy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ void CACHED_CONTAINER::FinishItem()
|
||||||
|
|
||||||
VERTEX* CACHED_CONTAINER::Allocate( unsigned int aSize )
|
VERTEX* CACHED_CONTAINER::Allocate( unsigned int aSize )
|
||||||
{
|
{
|
||||||
wxASSERT( m_item != NULL );
|
assert( m_item != NULL );
|
||||||
|
|
||||||
if( m_failed )
|
if( m_failed )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -136,7 +137,7 @@ VERTEX* CACHED_CONTAINER::Allocate( unsigned int aSize )
|
||||||
#endif
|
#endif
|
||||||
#if CACHED_CONTAINER_TEST > 2
|
#if CACHED_CONTAINER_TEST > 2
|
||||||
showFreeChunks();
|
showFreeChunks();
|
||||||
showReservedChunks();
|
showUsedChunks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return reserved;
|
return reserved;
|
||||||
|
@ -145,8 +146,8 @@ VERTEX* CACHED_CONTAINER::Allocate( unsigned int aSize )
|
||||||
|
|
||||||
void CACHED_CONTAINER::Delete( VERTEX_ITEM* aItem )
|
void CACHED_CONTAINER::Delete( VERTEX_ITEM* aItem )
|
||||||
{
|
{
|
||||||
wxASSERT( aItem != NULL );
|
assert( aItem != NULL );
|
||||||
wxASSERT( m_items.find( aItem ) != m_items.end() );
|
assert( m_items.find( aItem ) != m_items.end() );
|
||||||
|
|
||||||
int size = aItem->GetSize();
|
int size = aItem->GetSize();
|
||||||
int offset = aItem->GetOffset();
|
int offset = aItem->GetOffset();
|
||||||
|
@ -158,8 +159,7 @@ void CACHED_CONTAINER::Delete( VERTEX_ITEM* aItem )
|
||||||
// Insert a free memory chunk entry in the place where item was stored
|
// Insert a free memory chunk entry in the place where item was stored
|
||||||
if( size > 0 )
|
if( size > 0 )
|
||||||
{
|
{
|
||||||
m_freeChunks.insert( CHUNK( size, offset ) );
|
addFreeChunk( offset, size );
|
||||||
m_freeSpace += size;
|
|
||||||
// Indicate that the item is not stored in the container anymore
|
// Indicate that the item is not stored in the container anymore
|
||||||
aItem->setSize( 0 );
|
aItem->setSize( 0 );
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,6 @@ void CACHED_CONTAINER::Clear()
|
||||||
|
|
||||||
m_items.clear();
|
m_items.clear();
|
||||||
|
|
||||||
|
|
||||||
// Now there is only free space left
|
// Now there is only free space left
|
||||||
m_freeChunks.clear();
|
m_freeChunks.clear();
|
||||||
m_freeChunks.insert( CHUNK( m_freeSpace, 0 ) );
|
m_freeChunks.insert( CHUNK( m_freeSpace, 0 ) );
|
||||||
|
@ -210,7 +209,7 @@ void CACHED_CONTAINER::Clear()
|
||||||
|
|
||||||
unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
|
unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
|
||||||
{
|
{
|
||||||
wxASSERT( aSize > 0 );
|
assert( aSize > 0 );
|
||||||
|
|
||||||
#if CACHED_CONTAINER_TEST > 2
|
#if CACHED_CONTAINER_TEST > 2
|
||||||
wxLogDebug( wxT( "Resize 0x%08lx from %d to %d" ), (long) m_item, m_itemSize, aSize );
|
wxLogDebug( wxT( "Resize 0x%08lx from %d to %d" ), (long) m_item, m_itemSize, aSize );
|
||||||
|
@ -255,44 +254,41 @@ unsigned int CACHED_CONTAINER::reallocate( unsigned int aSize )
|
||||||
newChunk = m_freeChunks.begin();
|
newChunk = m_freeChunks.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameters of the allocated cuhnk
|
// Parameters of the allocated chunk
|
||||||
unsigned int chunkSize = newChunk->first;
|
unsigned int newChunkSize = newChunk->first;
|
||||||
unsigned int chunkOffset = newChunk->second;
|
unsigned int newChunkOffset = newChunk->second;
|
||||||
|
|
||||||
wxASSERT( chunkSize >= aSize );
|
assert( newChunkSize >= aSize );
|
||||||
wxASSERT( chunkOffset < m_currentSize );
|
assert( newChunkOffset < m_currentSize );
|
||||||
|
|
||||||
// Check if the item was previously stored in the container
|
// Check if the item was previously stored in the container
|
||||||
if( m_itemSize > 0 )
|
if( m_itemSize > 0 )
|
||||||
{
|
{
|
||||||
#if CACHED_CONTAINER_TEST > 3
|
#if CACHED_CONTAINER_TEST > 3
|
||||||
wxLogDebug( wxT( "Moving 0x%08x from 0x%08x to 0x%08x" ),
|
wxLogDebug( wxT( "Moving 0x%08x from 0x%08x to 0x%08x" ),
|
||||||
(int) m_item, oldChunkOffset, chunkOffset );
|
(int) m_item, oldChunkOffset, newChunkOffset );
|
||||||
#endif
|
#endif
|
||||||
// The item was reallocated, so we have to copy all the old data to the new place
|
// The item was reallocated, so we have to copy all the old data to the new place
|
||||||
memcpy( &m_vertices[chunkOffset], &m_vertices[m_chunkOffset], m_itemSize * VertexSize );
|
memcpy( &m_vertices[newChunkOffset], &m_vertices[m_chunkOffset], m_itemSize * VertexSize );
|
||||||
|
|
||||||
// Free the space previously used by the chunk
|
// Free the space previously used by the chunk
|
||||||
wxASSERT( m_itemSize > 0 );
|
assert( m_itemSize > 0 );
|
||||||
m_freeChunks.insert( CHUNK( m_itemSize, m_chunkOffset ) );
|
addFreeChunk( m_chunkOffset, m_itemSize );
|
||||||
m_freeSpace += m_itemSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the allocated chunk from the free space pool
|
// Remove the allocated chunk from the free space pool
|
||||||
m_freeChunks.erase( newChunk );
|
m_freeChunks.erase( newChunk );
|
||||||
|
|
||||||
// If there is some space left, return it to the pool - add an entry for it
|
// If there is some space left, return it to the pool - add an entry for it
|
||||||
if( chunkSize > aSize )
|
if( newChunkSize > aSize )
|
||||||
{
|
{
|
||||||
m_freeChunks.insert( CHUNK( chunkSize - aSize, chunkOffset + aSize ) );
|
m_freeChunks.insert( CHUNK( newChunkSize - aSize, newChunkOffset + aSize ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_freeSpace -= aSize;
|
m_freeSpace -= aSize;
|
||||||
// mergeFreeChunks(); // veery slow and buggy
|
// mergeFreeChunks(); // veery slow and buggy
|
||||||
|
|
||||||
m_item->setOffset( chunkOffset );
|
return newChunkOffset;
|
||||||
|
|
||||||
return chunkOffset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -413,15 +409,14 @@ void CACHED_CONTAINER::mergeFreeChunks()
|
||||||
|
|
||||||
wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), totalTime.msecs() );
|
wxLogDebug( wxT( "Merged free chunks / %.1f ms" ), totalTime.msecs() );
|
||||||
#endif
|
#endif
|
||||||
|
#if CACHED_CONTAINER_TEST > 1
|
||||||
test();
|
test();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CACHED_CONTAINER::resizeContainer( unsigned int aNewSize )
|
bool CACHED_CONTAINER::resizeContainer( unsigned int aNewSize )
|
||||||
{
|
{
|
||||||
wxASSERT( aNewSize != m_currentSize );
|
|
||||||
|
|
||||||
#if CACHED_CONTAINER_TEST > 0
|
#if CACHED_CONTAINER_TEST > 0
|
||||||
wxLogDebug( wxT( "Resizing container from %d to %d" ), m_currentSize, aNewSize );
|
wxLogDebug( wxT( "Resizing container from %d to %d" ), m_currentSize, aNewSize );
|
||||||
#endif
|
#endif
|
||||||
|
@ -432,7 +427,7 @@ bool CACHED_CONTAINER::resizeContainer( unsigned int aNewSize )
|
||||||
{
|
{
|
||||||
// Shrinking container
|
// Shrinking container
|
||||||
// Sanity check, no shrinking if we cannot fit all the data
|
// Sanity check, no shrinking if we cannot fit all the data
|
||||||
if( reservedSpace() > aNewSize )
|
if( usedSpace() > aNewSize )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int size = aNewSize * sizeof( VERTEX );
|
int size = aNewSize * sizeof( VERTEX );
|
||||||
|
@ -452,8 +447,8 @@ bool CACHED_CONTAINER::resizeContainer( unsigned int aNewSize )
|
||||||
|
|
||||||
// We have to correct freeChunks after defragmentation
|
// We have to correct freeChunks after defragmentation
|
||||||
m_freeChunks.clear();
|
m_freeChunks.clear();
|
||||||
wxASSERT( aNewSize - reservedSpace() > 0 );
|
wxASSERT( aNewSize - usedSpace() > 0 );
|
||||||
m_freeChunks.insert( CHUNK( aNewSize - reservedSpace(), reservedSpace() ) );
|
m_freeChunks.insert( CHUNK( aNewSize - usedSpace(), usedSpace() ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -483,7 +478,16 @@ bool CACHED_CONTAINER::resizeContainer( unsigned int aNewSize )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef CACHED_CONTAINER_TEST
|
void CACHED_CONTAINER::addFreeChunk( unsigned int aOffset, unsigned int aSize )
|
||||||
|
{
|
||||||
|
assert( aOffset + aSize <= m_currentSize );
|
||||||
|
assert( aSize > 0 );
|
||||||
|
|
||||||
|
m_freeChunks.insert( CHUNK( aSize, aOffset ) );
|
||||||
|
m_freeSpace += aSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CACHED_CONTAINER::showFreeChunks()
|
void CACHED_CONTAINER::showFreeChunks()
|
||||||
{
|
{
|
||||||
FREE_CHUNK_MAP::iterator it;
|
FREE_CHUNK_MAP::iterator it;
|
||||||
|
@ -494,7 +498,7 @@ void CACHED_CONTAINER::showFreeChunks()
|
||||||
{
|
{
|
||||||
unsigned int offset = getChunkOffset( *it );
|
unsigned int offset = getChunkOffset( *it );
|
||||||
unsigned int size = getChunkSize( *it );
|
unsigned int size = getChunkSize( *it );
|
||||||
wxASSERT( size > 0 );
|
assert( size > 0 );
|
||||||
|
|
||||||
wxLogDebug( wxT( "[0x%08x-0x%08x] (size %d)" ),
|
wxLogDebug( wxT( "[0x%08x-0x%08x] (size %d)" ),
|
||||||
offset, offset + size - 1, size );
|
offset, offset + size - 1, size );
|
||||||
|
@ -502,18 +506,18 @@ void CACHED_CONTAINER::showFreeChunks()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CACHED_CONTAINER::showReservedChunks()
|
void CACHED_CONTAINER::showUsedChunks()
|
||||||
{
|
{
|
||||||
ITEMS::iterator it;
|
ITEMS::iterator it;
|
||||||
|
|
||||||
wxLogDebug( wxT( "Reserved chunks:" ) );
|
wxLogDebug( wxT( "Used chunks:" ) );
|
||||||
|
|
||||||
for( it = m_items.begin(); it != m_items.end(); ++it )
|
for( it = m_items.begin(); it != m_items.end(); ++it )
|
||||||
{
|
{
|
||||||
VERTEX_ITEM* item = *it;
|
VERTEX_ITEM* item = *it;
|
||||||
unsigned int offset = item->GetOffset();
|
unsigned int offset = item->GetOffset();
|
||||||
unsigned int size = item->GetSize();
|
unsigned int size = item->GetSize();
|
||||||
wxASSERT( size > 0 );
|
assert( size > 0 );
|
||||||
|
|
||||||
wxLogDebug( wxT( "[0x%08x-0x%08x] @ 0x%08lx (size %d)" ),
|
wxLogDebug( wxT( "[0x%08x-0x%08x] @ 0x%08lx (size %d)" ),
|
||||||
offset, offset + size - 1, (long) item, size );
|
offset, offset + size - 1, (long) item, size );
|
||||||
|
@ -530,18 +534,17 @@ void CACHED_CONTAINER::test()
|
||||||
for( itf = m_freeChunks.begin(); itf != m_freeChunks.end(); ++itf )
|
for( itf = m_freeChunks.begin(); itf != m_freeChunks.end(); ++itf )
|
||||||
freeSpace += getChunkSize( *itf );
|
freeSpace += getChunkSize( *itf );
|
||||||
|
|
||||||
wxASSERT( freeSpace == m_freeSpace );
|
assert( freeSpace == m_freeSpace );
|
||||||
|
|
||||||
// Reserved space check
|
// Used space check
|
||||||
/*unsigned int reservedSpace = 0;
|
/*unsigned int usedSpace = 0;
|
||||||
ITEMS::iterator itr;
|
ITEMS::iterator itr;
|
||||||
for( itr = m_items.begin(); itr != m_items.end(); ++itr )
|
for( itr = m_items.begin(); itr != m_items.end(); ++itr )
|
||||||
reservedSpace += ( *itr )->GetSize();
|
usedSpace += ( *itr )->GetSize();
|
||||||
reservedSpace += m_itemSize; // Add the current chunk size
|
usedSpace += m_itemSize; // Add the current chunk size
|
||||||
|
|
||||||
wxASSERT( ( freeSpace + reservedSpace ) == m_currentSize );*/
|
assert( ( freeSpace + usedSpace ) == m_currentSize );*/
|
||||||
|
|
||||||
// Overlapping check TBD
|
// Overlapping check TBD
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CACHED_CONTAINER_TEST */
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ protected:
|
||||||
* @param aSize is the number of vertices to be stored.
|
* @param aSize is the number of vertices to be stored.
|
||||||
* @return offset of the new chunk.
|
* @return offset of the new chunk.
|
||||||
*/
|
*/
|
||||||
virtual unsigned int reallocate( unsigned int aSize );
|
unsigned int reallocate( unsigned int aSize );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function defragment()
|
* Function defragment()
|
||||||
|
@ -154,16 +154,16 @@ private:
|
||||||
return aChunk.second;
|
return aChunk.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function addFreeChunk
|
||||||
|
* Adds a chunk marked as free.
|
||||||
|
*/
|
||||||
|
void addFreeChunk( unsigned int aOffset, unsigned int aSize );
|
||||||
|
|
||||||
/// Debug & test functions
|
/// Debug & test functions
|
||||||
#if CACHED_CONTAINER_TEST > 0
|
|
||||||
void showFreeChunks();
|
void showFreeChunks();
|
||||||
void showReservedChunks();
|
void showUsedChunks();
|
||||||
void test();
|
void test();
|
||||||
#else
|
|
||||||
inline void showFreeChunks() {}
|
|
||||||
inline void showReservedChunks() {}
|
|
||||||
inline void test() {}
|
|
||||||
#endif /* CACHED_CONTAINER_TEST */
|
|
||||||
};
|
};
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Allocate()
|
* Function Allocate()
|
||||||
* returns allocated space (possibly resizing the reserved memory chunk or allocating a new
|
* returns allocated space (possibly resizing the used memory chunk or allocating a new
|
||||||
* chunk if it was not stored before) for the given number of vertices associated with the
|
* chunk if it was not stored before) for the given number of vertices associated with the
|
||||||
* current item (set by SetItem()). The newly allocated space is added at the end of the chunk
|
* current item (set by SetItem()). The newly allocated space is added at the end of the chunk
|
||||||
* used by the current item and may serve to store new vertices.
|
* used by the current item and may serve to store new vertices.
|
||||||
|
@ -159,11 +159,11 @@ protected:
|
||||||
bool m_dirty;
|
bool m_dirty;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function reservedSpace()
|
* Function usedSpace()
|
||||||
* returns size of the reserved memory space.
|
* returns size of the used memory space.
|
||||||
* @return Size of the reserved memory space (expressed as a number of vertices).
|
* @return Size of the used memory space (expressed as a number of vertices).
|
||||||
*/
|
*/
|
||||||
inline unsigned int reservedSpace()
|
inline unsigned int usedSpace() const
|
||||||
{
|
{
|
||||||
return m_currentSize - m_freeSpace;
|
return m_currentSize - m_freeSpace;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue