Minor refactoring in CACHED_CONTAINER.

This commit is contained in:
Maciej Suminski 2016-05-02 16:12:16 +02:00
parent b32fdd97d9
commit 01912aaabd
3 changed files with 63 additions and 60 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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;
} }