KiCad PCB EDA Suite
KIGFX::CACHED_CONTAINER Class Referenceabstract

Class to store VERTEX instances with caching. More...

#include <cached_container.h>

Inheritance diagram for KIGFX::CACHED_CONTAINER:
KIGFX::VERTEX_CONTAINER KIGFX::CACHED_CONTAINER_GPU KIGFX::CACHED_CONTAINER_RAM

Public Member Functions

 CACHED_CONTAINER (unsigned int aSize=DEFAULT_SIZE)
 
virtual ~CACHED_CONTAINER ()
 
bool IsCached () const override
 Returns true if the container caches vertex data in RAM or video memory. More...
 
virtual void SetItem (VERTEX_ITEM *aItem) override
 > More...
 
virtual void FinishItem () override
 > More...
 
virtual VERTEXAllocate (unsigned int aSize) override
 > More...
 
virtual void Delete (VERTEX_ITEM *aItem) override
 > More...
 
virtual void Clear () override
 > More...
 
virtual unsigned int GetBufferHandle () const =0
 Returns handle to the vertex buffer. More...
 
virtual bool IsMapped () const =0
 Returns true if vertex buffer is currently mapped. More...
 
virtual void Map () override=0
 > More...
 
virtual void Unmap () override=0
 > More...
 
VERTEXGetAllVertices () const
 Returns pointer to the vertices stored in the container. More...
 
virtual VERTEXGetVertices (unsigned int aOffset) const
 Function GetVertices() returns vertices stored at the specific offset. More...
 
virtual unsigned int GetSize () const
 Function GetSize() returns amount of vertices currently stored in the container. More...
 
bool IsDirty () const
 Returns information about the container cache state. More...
 
void SetDirty ()
 Sets the dirty flag, so vertices in the container are going to be reuploaded to the GPU on the next frame. More...
 
void ClearDirty ()
 Clears the dirty flag to prevent reuploading vertices to the GPU memory. More...
 

Static Public Member Functions

static VERTEX_CONTAINERMakeContainer (bool aCached)
 Returns a pointer to a new container of an appropriate type. More...
 

Protected Types

typedef std::pair< unsigned int, unsigned int > CHUNK
 

Maps size of free memory chunks to their offsets

More...
 
typedef std::multimap< unsigned int, unsigned int > FREE_CHUNK_MAP
 
typedef std::set< VERTEX_ITEM * > ITEMS
 List of all the stored items. More...
 

Protected Member Functions

bool reallocate (unsigned int aSize)
 Resizes the chunk that stores the current item to the given size. More...
 
virtual bool defragmentResize (unsigned int aNewSize)=0
 Removes empty spaces between chunks and optionally resizes the container. More...
 
void defragment (VERTEX *aTarget)
 Transfers all stored data to a new buffer, removing empty spaces between the data chunks in the container. More...
 
void mergeFreeChunks ()
 Looks for consecutive free memory chunks and merges them, decreasing fragmentation of memory. More...
 
int getChunkSize (const CHUNK &aChunk) const
 Returns the size of a chunk. More...
 
unsigned int getChunkOffset (const CHUNK &aChunk) const
 Returns the offset of a chunk. More...
 
void addFreeChunk (unsigned int aOffset, unsigned int aSize)
 Adds a chunk marked as a free space. More...
 
unsigned int usedSpace () const
 Function usedSpace() returns size of the used memory space. More...
 

Protected Attributes

FREE_CHUNK_MAP m_freeChunks
 

Stores size & offset of free chunks.

More...
 
ITEMS m_items
 

Stored VERTEX_ITEMs

More...
 
VERTEX_ITEMm_item
 

Currently modified item

More...
 
unsigned int m_chunkSize
 

Properties of currently modified chunk & item

More...
 
unsigned int m_chunkOffset
 
unsigned int m_maxIndex
 

Maximal vertex index number stored in the container

More...
 
unsigned int m_freeSpace
 

Free space left in the container, expressed in vertices

More...
 
unsigned int m_currentSize
 

Current container size, expressed in vertices

More...
 
unsigned int m_initialSize
 

Store the initial size, so it can be resized to this on Clear()

More...
 
VERTEXm_vertices
 

Actual storage memory

More...
 
bool m_failed
 
bool m_dirty
 

Static Protected Attributes

static constexpr unsigned int DEFAULT_SIZE = 1048576
 

Private Member Functions

void showFreeChunks ()
 Debug & test functions. More...
 
void showUsedChunks ()
 
void test ()
 

Detailed Description

Class to store VERTEX instances with caching.

It associates VERTEX objects and with VERTEX_ITEMs. Caching vertices data in the memory and a enables fast reuse of that data.

Definition at line 43 of file cached_container.h.

Member Typedef Documentation

typedef std::pair<unsigned int, unsigned int> KIGFX::CACHED_CONTAINER::CHUNK
protected

Maps size of free memory chunks to their offsets

Definition at line 87 of file cached_container.h.

typedef std::multimap<unsigned int, unsigned int> KIGFX::CACHED_CONTAINER::FREE_CHUNK_MAP
protected

Definition at line 88 of file cached_container.h.

typedef std::set<VERTEX_ITEM*> KIGFX::CACHED_CONTAINER::ITEMS
protected

List of all the stored items.

Definition at line 91 of file cached_container.h.

Constructor & Destructor Documentation

CACHED_CONTAINER::CACHED_CONTAINER ( unsigned int  aSize = DEFAULT_SIZE)

Definition at line 47 of file cached_container.cpp.

References m_freeChunks.

47  :
48  VERTEX_CONTAINER( aSize ), m_item( NULL ), m_chunkSize( 0 ), m_chunkOffset( 0 ), m_maxIndex( 0 )
49 {
50  // In the beginning there is only free space
51  m_freeChunks.insert( std::make_pair( aSize, 0 ) );
52 }
VERTEX_CONTAINER(unsigned int aSize=DEFAULT_SIZE)
unsigned int m_chunkSize
Properties of currently modified chunk & item
VERTEX_ITEM * m_item
Currently modified item
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
unsigned int m_maxIndex
Maximal vertex index number stored in the container
virtual KIGFX::CACHED_CONTAINER::~CACHED_CONTAINER ( )
inlinevirtual

Definition at line 47 of file cached_container.h.

47 {}

Member Function Documentation

void CACHED_CONTAINER::addFreeChunk ( unsigned int  aOffset,
unsigned int  aSize 
)
protected

Adds a chunk marked as a free space.

Definition at line 375 of file cached_container.cpp.

References KIGFX::VERTEX_CONTAINER::m_currentSize, m_freeChunks, and KIGFX::VERTEX_CONTAINER::m_freeSpace.

Referenced by Delete(), FinishItem(), and reallocate().

376 {
377  assert( aOffset + aSize <= m_currentSize );
378  assert( aSize > 0 );
379 
380  m_freeChunks.insert( std::make_pair( aSize, aOffset ) );
381  m_freeSpace += aSize;
382 }
unsigned int m_currentSize
Current container size, expressed in vertices
unsigned int m_freeSpace
Free space left in the container, expressed in vertices
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
VERTEX * CACHED_CONTAINER::Allocate ( unsigned int  aSize)
overridevirtual

>

Returns allocated space for the requested number of vertices associated with the current item (set with SetItem()). The allocated space is added at the end of the chunk used by the current item and may serve to store new vertices.

Parameters
aSizeis the number of vertices to be allocated.
Returns
Pointer to the allocated space or NULL in case of failure.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 105 of file cached_container.cpp.

References KIGFX::VERTEX_ITEM::GetSize(), IsMapped(), m_chunkOffset, m_chunkSize, KIGFX::VERTEX_CONTAINER::m_dirty, KIGFX::VERTEX_CONTAINER::m_failed, m_item, KIGFX::VERTEX_CONTAINER::m_vertices, reallocate(), KIGFX::VERTEX_ITEM::setSize(), showFreeChunks(), showUsedChunks(), and test().

106 {
107  assert( m_item != NULL );
108  assert( IsMapped() );
109 
110  if( m_failed )
111  return NULL;
112 
113  unsigned int itemSize = m_item->GetSize();
114  unsigned int newSize = itemSize + aSize;
115 
116  if( newSize > m_chunkSize )
117  {
118  // There is not enough space in the currently reserved chunk, so we have to resize it
119  if( !reallocate( newSize ) )
120  {
121  m_failed = true;
122  return NULL;
123  }
124  }
125 
126  VERTEX* reserved = &m_vertices[m_chunkOffset + itemSize];
127 
128  // Now the item officially possesses the memory chunk
129  m_item->setSize( newSize );
130 
131  // The content has to be updated
132  m_dirty = true;
133 
134 #if CACHED_CONTAINER_TEST > 0
135  test();
136 #endif
137 #if CACHED_CONTAINER_TEST > 2
138  showFreeChunks();
139  showUsedChunks();
140 #endif
141 
142  return reserved;
143 }
void showFreeChunks()
Debug & test functions.
Data structure for vertices {X,Y,Z,R,G,B,A,shader¶m}
Definition: vertex_common.h:50
unsigned int m_chunkSize
Properties of currently modified chunk & item
VERTEX * m_vertices
Actual storage memory
void setSize(unsigned int aSize)
Function SetSize() Sets data size in the container.
Definition: vertex_item.h:97
VERTEX_ITEM * m_item
Currently modified item
bool reallocate(unsigned int aSize)
Resizes the chunk that stores the current item to the given size.
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
virtual bool IsMapped() const =0
Returns true if vertex buffer is currently mapped.
void CACHED_CONTAINER::Clear ( )
overridevirtual

>

Removes all data stored in the container and restores its original state.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 191 of file cached_container.cpp.

References KIGFX::VERTEX_CONTAINER::m_currentSize, KIGFX::VERTEX_CONTAINER::m_failed, m_freeChunks, KIGFX::VERTEX_CONTAINER::m_freeSpace, m_items, and m_maxIndex.

192 {
194  m_maxIndex = 0;
195  m_failed = false;
196 
197  // Set the size of all the stored VERTEX_ITEMs to 0, so it is clear that they are not held
198  // in the container anymore
199  for( ITEMS::iterator it = m_items.begin(); it != m_items.end(); ++it )
200  ( *it )->setSize( 0 );
201 
202  m_items.clear();
203 
204  // Now there is only free space left
205  m_freeChunks.clear();
206  m_freeChunks.insert( std::make_pair( m_freeSpace, 0 ) );
207 }
unsigned int m_currentSize
Current container size, expressed in vertices
ITEMS m_items
Stored VERTEX_ITEMs
unsigned int m_freeSpace
Free space left in the container, expressed in vertices
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
unsigned int m_maxIndex
Maximal vertex index number stored in the container
void KIGFX::VERTEX_CONTAINER::ClearDirty ( )
inlineinherited

Clears the dirty flag to prevent reuploading vertices to the GPU memory.

Definition at line 145 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_dirty.

Referenced by KIGFX::GPU_CACHED_MANAGER::EndDrawing().

146  {
147  m_dirty = false;
148  }
void CACHED_CONTAINER::defragment ( VERTEX aTarget)
protected

Transfers all stored data to a new buffer, removing empty spaces between the data chunks in the container.

Parameters
aTargetis the destination for the defragmented data.

Definition at line 282 of file cached_container.cpp.

References KIGFX::VERTEX_ITEM::GetOffset(), KIGFX::VERTEX_ITEM::GetSize(), m_chunkOffset, m_item, m_items, m_maxIndex, KIGFX::VERTEX_CONTAINER::m_vertices, KIGFX::VERTEX_ITEM::setOffset(), KIGFX::VERTEX_CONTAINER::usedSpace(), and KIGFX::VERTEX_SIZE.

Referenced by KIGFX::CACHED_CONTAINER_RAM::defragmentResize(), and KIGFX::CACHED_CONTAINER_GPU::defragmentResizeMemcpy().

283 {
284  // Defragmentation
285  ITEMS::iterator it, it_end;
286  int newOffset = 0;
287 
288  for( VERTEX_ITEM* item : m_items )
289  {
290  int itemOffset = item->GetOffset();
291  int itemSize = item->GetSize();
292 
293  // Move an item to the new container
294  memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VERTEX_SIZE );
295 
296  // Update new offset
297  item->setOffset( newOffset );
298 
299  // Move to the next free space
300  newOffset += itemSize;
301  }
302 
303  // Move the current item and place it at the end
304  if( m_item->GetSize() > 0 )
305  {
306  memcpy( &aTarget[newOffset], &m_vertices[m_item->GetOffset()],
307  m_item->GetSize() * VERTEX_SIZE );
308  m_item->setOffset( newOffset );
309  m_chunkOffset = newOffset;
310  }
311 
312  m_maxIndex = usedSpace();
313 }
unsigned int usedSpace() const
Function usedSpace() returns size of the used memory space.
VERTEX * m_vertices
Actual storage memory
ITEMS m_items
Stored VERTEX_ITEMs
VERTEX_ITEM * m_item
Currently modified item
void setOffset(unsigned int aOffset)
Function SetOffset() Sets data offset in the container.
Definition: vertex_item.h:87
unsigned int GetOffset() const
Function GetOffset() Returns data offset in the container.
Definition: vertex_item.h:66
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:57
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
unsigned int m_maxIndex
Maximal vertex index number stored in the container
virtual bool KIGFX::CACHED_CONTAINER::defragmentResize ( unsigned int  aNewSize)
protectedpure virtual

Removes empty spaces between chunks and optionally resizes the container.

After the operation there is continous space for storing vertices at the end of the container.

Parameters
aNewSizeis the new size of container, expressed in number of vertices
Returns
false in case of failure (e.g. memory shortage)

Implemented in KIGFX::CACHED_CONTAINER_GPU, and KIGFX::CACHED_CONTAINER_RAM.

Referenced by Delete(), and reallocate().

void CACHED_CONTAINER::Delete ( VERTEX_ITEM aItem)
overridevirtual

>

Erases the data related to an item.

Parameters
aItemis the item to be erased.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 146 of file cached_container.cpp.

References addFreeChunk(), defragmentResize(), KIGFX::VERTEX_ITEM::GetOffset(), KIGFX::VERTEX_ITEM::GetSize(), KIGFX::VERTEX_CONTAINER::m_currentSize, KIGFX::VERTEX_CONTAINER::m_freeSpace, KIGFX::VERTEX_CONTAINER::m_initialSize, m_items, and test().

147 {
148  assert( aItem != NULL );
149  assert( m_items.find( aItem ) != m_items.end() || aItem->GetSize() == 0 );
150 
151  int size = aItem->GetSize();
152 
153  if( size == 0 )
154  return; // Item is not stored here
155 
156  int offset = aItem->GetOffset();
157 
158 #if CACHED_CONTAINER_TEST > 1
159  wxLogDebug( wxT( "Removing 0x%08lx (size %d offset %d)" ), (long) aItem, size, offset );
160 #endif
161 
162  // Insert a free memory chunk entry in the place where item was stored
163  addFreeChunk( offset, size );
164 
165  // Indicate that the item is not stored in the container anymore
166  aItem->setSize( 0 );
167 
168  m_items.erase( aItem );
169 
170 #if CACHED_CONTAINER_TEST > 0
171  test();
172 #endif
173 
174  // This dynamic memory freeing optimize memory usage, but in fact can create
175  // out of memory issues because freeing and reallocation large chuncks of memory
176  // can create memory fragmentation and no room to reallocate large chuncks
177  // after many free/reallocate cycles during a session using the same complex board
178  // So it can be disable.
179  // Currently: it is disable to avoid "out of memory" issues
180 #if 0
181  // Dynamic memory freeing, there is no point in holding
182  // a large amount of memory when there is no use for it
183  if( m_freeSpace > ( 0.75 * m_currentSize ) && m_currentSize > m_initialSize )
184  {
186  }
187 #endif
188 }
unsigned int m_initialSize
Store the initial size, so it can be resized to this on Clear()
void addFreeChunk(unsigned int aOffset, unsigned int aSize)
Adds a chunk marked as a free space.
unsigned int m_currentSize
Current container size, expressed in vertices
void setSize(unsigned int aSize)
Function SetSize() Sets data size in the container.
Definition: vertex_item.h:97
ITEMS m_items
Stored VERTEX_ITEMs
unsigned int m_freeSpace
Free space left in the container, expressed in vertices
unsigned int GetOffset() const
Function GetOffset() Returns data offset in the container.
Definition: vertex_item.h:66
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
virtual bool defragmentResize(unsigned int aNewSize)=0
Removes empty spaces between chunks and optionally resizes the container.
void CACHED_CONTAINER::FinishItem ( )
overridevirtual

>

Clean up after adding an item.

Reimplemented from KIGFX::VERTEX_CONTAINER.

Definition at line 72 of file cached_container.cpp.

References addFreeChunk(), KIGFX::VERTEX_ITEM::GetOffset(), KIGFX::VERTEX_ITEM::GetSize(), m_chunkOffset, m_chunkSize, m_item, m_items, m_maxIndex, max, and test().

73 {
74  assert( m_item != NULL );
75 
76  unsigned int itemSize = m_item->GetSize();
77 
78  // Finishing the previously edited item
79  if( itemSize < m_chunkSize )
80  {
81  // There is some not used but reserved memory left, so we should return it to the pool
82  int itemOffset = m_item->GetOffset();
83 
84  // Add the not used memory back to the pool
85  addFreeChunk( itemOffset + itemSize, m_chunkSize - itemSize );
86  // mergeFreeChunks(); // veery slow and buggy
87 
88  m_maxIndex = std::max( itemOffset + itemSize, m_maxIndex );
89  }
90 
91  if( itemSize > 0 )
92  m_items.insert( m_item );
93 
94  m_item = NULL;
95  m_chunkSize = 0;
96  m_chunkOffset = 0;
97 
98 #if CACHED_CONTAINER_TEST > 1
99  wxLogDebug( wxT( "Finishing item 0x%08lx (size %d)" ), (long) m_item, itemSize );
100  test();
101 #endif
102 }
void addFreeChunk(unsigned int aOffset, unsigned int aSize)
Adds a chunk marked as a free space.
unsigned int m_chunkSize
Properties of currently modified chunk & item
ITEMS m_items
Stored VERTEX_ITEMs
VERTEX_ITEM * m_item
Currently modified item
unsigned int GetOffset() const
Function GetOffset() Returns data offset in the container.
Definition: vertex_item.h:66
#define max(a, b)
Definition: auxiliary.h:86
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
unsigned int m_maxIndex
Maximal vertex index number stored in the container
VERTEX* KIGFX::VERTEX_CONTAINER::GetAllVertices ( ) const
inlineinherited

Returns pointer to the vertices stored in the container.

Definition at line 100 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_vertices.

Referenced by KIGFX::GPU_NONCACHED_MANAGER::EndDrawing().

101  {
102  return m_vertices;
103  }
VERTEX * m_vertices
Actual storage memory
virtual unsigned int KIGFX::CACHED_CONTAINER::GetBufferHandle ( ) const
pure virtual

Returns handle to the vertex buffer.

It might be negative if the buffer is not initialized.

Implemented in KIGFX::CACHED_CONTAINER_RAM, and KIGFX::CACHED_CONTAINER_GPU.

Referenced by KIGFX::GPU_CACHED_MANAGER::EndDrawing().

unsigned int KIGFX::CACHED_CONTAINER::getChunkOffset ( const CHUNK aChunk) const
inlineprotected

Returns the offset of a chunk.

Parameters
aChunkis the chunk.

Definition at line 156 of file cached_container.h.

Referenced by reallocate(), and showFreeChunks().

157  {
158  return aChunk.second;
159  }
int KIGFX::CACHED_CONTAINER::getChunkSize ( const CHUNK aChunk) const
inlineprotected

Returns the size of a chunk.

Parameters
aChunkis the chunk.

Definition at line 146 of file cached_container.h.

Referenced by reallocate(), showFreeChunks(), and test().

147  {
148  return aChunk.first;
149  }
virtual unsigned int KIGFX::VERTEX_CONTAINER::GetSize ( ) const
inlinevirtualinherited

Function GetSize() returns amount of vertices currently stored in the container.

Reimplemented in KIGFX::NONCACHED_CONTAINER.

Definition at line 119 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_currentSize.

Referenced by KIGFX::GPU_CACHED_MANAGER::BeginDrawing(), KIGFX::GPU_CACHED_MANAGER::DrawAll(), KIGFX::GPU_NONCACHED_MANAGER::EndDrawing(), and KIGFX::GPU_CACHED_MANAGER::GPU_CACHED_MANAGER().

120  {
121  return m_currentSize;
122  }
unsigned int m_currentSize
Current container size, expressed in vertices
virtual VERTEX* KIGFX::VERTEX_CONTAINER::GetVertices ( unsigned int  aOffset) const
inlinevirtualinherited

Function GetVertices() returns vertices stored at the specific offset.

Parameters
aOffsetis the offset.

Definition at line 110 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_vertices.

111  {
112  return &m_vertices[aOffset];
113  }
VERTEX * m_vertices
Actual storage memory
bool KIGFX::CACHED_CONTAINER::IsCached ( ) const
inlineoverridevirtual

Returns true if the container caches vertex data in RAM or video memory.

Otherwise it is a single batch draw which is later discarded.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 49 of file cached_container.h.

50  {
51  return true;
52  }
bool KIGFX::VERTEX_CONTAINER::IsDirty ( ) const
inlineinherited

Returns information about the container cache state.

Returns
True in case the vertices have to be reuploaded.

Definition at line 128 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_dirty.

Referenced by KIGFX::GPU_CACHED_MANAGER::BeginDrawing().

129  {
130  return m_dirty;
131  }
virtual bool KIGFX::CACHED_CONTAINER::IsMapped ( ) const
pure virtual

Returns true if vertex buffer is currently mapped.

Implemented in KIGFX::CACHED_CONTAINER_RAM, and KIGFX::CACHED_CONTAINER_GPU.

Referenced by Allocate(), KIGFX::GPU_CACHED_MANAGER::EndDrawing(), and reallocate().

VERTEX_CONTAINER * VERTEX_CONTAINER::MakeContainer ( bool  aCached)
staticinherited

Returns a pointer to a new container of an appropriate type.

Definition at line 40 of file vertex_container.cpp.

Referenced by KIGFX::VERTEX_MANAGER::VERTEX_MANAGER().

41 {
42  if( aCached )
43  {
44  const char* vendor = (const char*) glGetString( GL_VENDOR );
45 
46  // Open source drivers do not cope well with GPU memory mapping,
47  // so the vertex data has to be kept in RAM
48  if( strstr( vendor, "X.Org" ) || strstr( vendor, "nouveau" ) )
49  return new CACHED_CONTAINER_RAM;
50  else
51  return new CACHED_CONTAINER_GPU;
52  }
53 
54  return new NONCACHED_CONTAINER;
55 }
Specialization of CACHED_CONTAINER that stores data in RAM.
Specialization of CACHED_CONTAINER that stores data in video memory via memory mapping.
virtual void KIGFX::CACHED_CONTAINER::Map ( )
overridepure virtual

>

Prepares the container for vertices updates.

Reimplemented from KIGFX::VERTEX_CONTAINER.

Implemented in KIGFX::CACHED_CONTAINER_GPU, and KIGFX::CACHED_CONTAINER_RAM.

void CACHED_CONTAINER::mergeFreeChunks ( )
protected

Looks for consecutive free memory chunks and merges them, decreasing fragmentation of memory.

Definition at line 316 of file cached_container.cpp.

References m_freeChunks, PROF_COUNTER::msecs(), PROF_COUNTER::Stop(), and test().

317 {
318  if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged
319  return;
320 
321 #ifdef __WXDEBUG__
322  PROF_COUNTER totalTime;
323 #endif /* __WXDEBUG__ */
324 
325  // Reversed free chunks map - this one stores chunk size with its offset as the key
326  std::list<CHUNK> freeChunks;
327 
328  FREE_CHUNK_MAP::const_iterator it, it_end;
329 
330  for( it = m_freeChunks.begin(), it_end = m_freeChunks.end(); it != it_end; ++it )
331  {
332  freeChunks.push_back( std::make_pair( it->second, it->first ) );
333  }
334 
335  m_freeChunks.clear();
336  freeChunks.sort();
337 
338  std::list<CHUNK>::const_iterator itf, itf_end;
339  unsigned int offset = freeChunks.front().first;
340  unsigned int size = freeChunks.front().second;
341  freeChunks.pop_front();
342 
343  for( itf = freeChunks.begin(), itf_end = freeChunks.end(); itf != itf_end; ++itf )
344  {
345  if( itf->first == offset + size )
346  {
347  // These chunks can be merged, so just increase the current chunk size and go on
348  size += itf->second;
349  }
350  else
351  {
352  // These chunks cannot be merged
353  // So store the previous one
354  m_freeChunks.insert( std::make_pair( size, offset ) );
355  // and let's check the next chunk
356  offset = itf->first;
357  size = itf->second;
358 
359  }
360  }
361 
362  // Add the last one
363  m_freeChunks.insert( std::make_pair( size, offset ) );
364 
365 #ifdef __WXDEBUG__
366  totalTime.Stop();
367  wxLogDebug( "Merged free chunks / %.1f ms", totalTime.msecs() );
368 #endif /* __WXDEBUG__ */
369 #if CACHED_CONTAINER_TEST > 0
370  test();
371 #endif
372 }
void Stop()
save the time when this function was called, and set the counter stane to stop
Definition: profile.h:82
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:45
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
double msecs() const
Definition: profile.h:124
bool CACHED_CONTAINER::reallocate ( unsigned int  aSize)
protected

Resizes the chunk that stores the current item to the given size.

The current item has its offset adjusted after the call, and the new chunk parameters are stored in m_chunkOffset and m_chunkSize.

Parameters
aSizeis the requested chunk size.
Returns
true in case of success, false otherwise

Definition at line 210 of file cached_container.cpp.

References addFreeChunk(), defragmentResize(), getChunkOffset(), getChunkSize(), KIGFX::VERTEX_ITEM::GetSize(), IsMapped(), m_chunkOffset, m_chunkSize, KIGFX::VERTEX_CONTAINER::m_currentSize, m_freeChunks, KIGFX::VERTEX_CONTAINER::m_freeSpace, m_item, KIGFX::VERTEX_CONTAINER::m_vertices, KIGFX::VERTEX_ITEM::setOffset(), and KIGFX::VERTEX_SIZE.

Referenced by Allocate().

211 {
212  assert( aSize > 0 );
213  assert( IsMapped() );
214 
215  unsigned int itemSize = m_item->GetSize();
216 
217 #if CACHED_CONTAINER_TEST > 2
218  wxLogDebug( wxT( "Resize %p from %d to %d" ), m_item, itemSize, aSize );
219 #endif
220 
221  // Find a free space chunk >= aSize
222  FREE_CHUNK_MAP::iterator newChunk = m_freeChunks.lower_bound( aSize );
223 
224  // Is there enough space to store vertices?
225  if( newChunk == m_freeChunks.end() )
226  {
227  bool result;
228 
229  // Would it be enough to double the current space?
230  if( aSize < m_freeSpace + m_currentSize )
231  {
232  // Yes: exponential growing
233  result = defragmentResize( m_currentSize * 2 );
234  }
235  else
236  {
237  // No: grow to the nearest greater power of 2
238  result = defragmentResize( pow( 2, ceil( log2( m_currentSize * 2 + aSize ) ) ) );
239  }
240 
241  if( !result )
242  return false;
243 
244  newChunk = m_freeChunks.lower_bound( aSize );
245  assert( newChunk != m_freeChunks.end() );
246  }
247 
248  // Parameters of the allocated chunk
249  unsigned int newChunkSize = getChunkSize( *newChunk );
250  unsigned int newChunkOffset = getChunkOffset( *newChunk );
251 
252  assert( newChunkSize >= aSize );
253  assert( newChunkOffset < m_currentSize );
254 
255  // Check if the item was previously stored in the container
256  if( itemSize > 0 )
257  {
258 #if CACHED_CONTAINER_TEST > 3
259  wxLogDebug( wxT( "Moving 0x%08x from 0x%08x to 0x%08x" ),
260  (int) m_item, oldChunkOffset, newChunkOffset );
261 #endif
262  // The item was reallocated, so we have to copy all the old data to the new place
263  memcpy( &m_vertices[newChunkOffset], &m_vertices[m_chunkOffset], itemSize * VERTEX_SIZE );
264 
265  // Free the space used by the previous chunk
267  }
268 
269  // Remove the new allocated chunk from the free space pool
270  m_freeChunks.erase( newChunk );
271  m_freeSpace -= newChunkSize;
272 
273  m_chunkSize = newChunkSize;
274  m_chunkOffset = newChunkOffset;
275 
277 
278  return true;
279 }
int getChunkSize(const CHUNK &aChunk) const
Returns the size of a chunk.
void addFreeChunk(unsigned int aOffset, unsigned int aSize)
Adds a chunk marked as a free space.
unsigned int m_currentSize
Current container size, expressed in vertices
unsigned int m_chunkSize
Properties of currently modified chunk & item
VERTEX * m_vertices
Actual storage memory
VERTEX_ITEM * m_item
Currently modified item
unsigned int m_freeSpace
Free space left in the container, expressed in vertices
unsigned int getChunkOffset(const CHUNK &aChunk) const
Returns the offset of a chunk.
void setOffset(unsigned int aOffset)
Function SetOffset() Sets data offset in the container.
Definition: vertex_item.h:87
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:57
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
virtual bool IsMapped() const =0
Returns true if vertex buffer is currently mapped.
virtual bool defragmentResize(unsigned int aNewSize)=0
Removes empty spaces between chunks and optionally resizes the container.
void KIGFX::VERTEX_CONTAINER::SetDirty ( )
inlineinherited

Sets the dirty flag, so vertices in the container are going to be reuploaded to the GPU on the next frame.

Definition at line 137 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_dirty.

138  {
139  m_dirty = true;
140  }
void CACHED_CONTAINER::SetItem ( VERTEX_ITEM aItem)
overridevirtual

>

Sets the item for the further actions.

Parameters
aItemis the item or NULL in case of finishing the item.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 55 of file cached_container.cpp.

References KIGFX::VERTEX_ITEM::GetOffset(), KIGFX::VERTEX_ITEM::GetSize(), m_chunkOffset, m_chunkSize, and m_item.

56 {
57  assert( aItem != NULL );
58 
59  unsigned int itemSize = aItem->GetSize();
60  m_item = aItem;
61  m_chunkSize = itemSize;
62 
63  // Get the previously set offset if the item was stored previously
64  m_chunkOffset = itemSize > 0 ? aItem->GetOffset() : -1;
65 
66 #if CACHED_CONTAINER_TEST > 1
67  wxLogDebug( wxT( "Adding/editing item 0x%08lx (size %d)" ), (long) m_item, itemSize );
68 #endif
69 }
unsigned int m_chunkSize
Properties of currently modified chunk & item
VERTEX_ITEM * m_item
Currently modified item
unsigned int GetOffset() const
Function GetOffset() Returns data offset in the container.
Definition: vertex_item.h:66
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
void CACHED_CONTAINER::showFreeChunks ( )
private

Debug & test functions.

Definition at line 385 of file cached_container.cpp.

References getChunkOffset(), getChunkSize(), and m_freeChunks.

Referenced by Allocate().

386 {
387 #ifdef __WXDEBUG__
388  FREE_CHUNK_MAP::iterator it;
389 
390  wxLogDebug( wxT( "Free chunks:" ) );
391 
392  for( it = m_freeChunks.begin(); it != m_freeChunks.end(); ++it )
393  {
394  unsigned int offset = getChunkOffset( *it );
395  unsigned int size = getChunkSize( *it );
396  assert( size > 0 );
397 
398  wxLogDebug( wxT( "[0x%08x-0x%08x] (size %d)" ),
399  offset, offset + size - 1, size );
400  }
401 #endif /* __WXDEBUG__ */
402 }
int getChunkSize(const CHUNK &aChunk) const
Returns the size of a chunk.
unsigned int getChunkOffset(const CHUNK &aChunk) const
Returns the offset of a chunk.
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
void CACHED_CONTAINER::showUsedChunks ( )
private

Definition at line 405 of file cached_container.cpp.

References KIGFX::VERTEX_ITEM::GetOffset(), KIGFX::VERTEX_ITEM::GetSize(), and m_items.

Referenced by Allocate().

406 {
407 #ifdef __WXDEBUG__
408  ITEMS::iterator it;
409 
410  wxLogDebug( wxT( "Used chunks:" ) );
411 
412  for( it = m_items.begin(); it != m_items.end(); ++it )
413  {
414  VERTEX_ITEM* item = *it;
415  unsigned int offset = item->GetOffset();
416  unsigned int size = item->GetSize();
417  assert( size > 0 );
418 
419  wxLogDebug( wxT( "[0x%08x-0x%08x] @ 0x%p (size %d)" ),
420  offset, offset + size - 1, item, size );
421  }
422 #endif /* __WXDEBUG__ */
423 }
ITEMS m_items
Stored VERTEX_ITEMs
unsigned int GetOffset() const
Function GetOffset() Returns data offset in the container.
Definition: vertex_item.h:66
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
void CACHED_CONTAINER::test ( )
private

Definition at line 426 of file cached_container.cpp.

References getChunkSize(), m_chunkSize, KIGFX::VERTEX_CONTAINER::m_currentSize, m_freeChunks, KIGFX::VERTEX_CONTAINER::m_freeSpace, m_item, and m_items.

Referenced by Allocate(), Delete(), FinishItem(), and mergeFreeChunks().

427 {
428 #ifdef __WXDEBUG__
429  // Free space check
430  unsigned int freeSpace = 0;
431  FREE_CHUNK_MAP::iterator itf;
432 
433  for( itf = m_freeChunks.begin(); itf != m_freeChunks.end(); ++itf )
434  freeSpace += getChunkSize( *itf );
435 
436  assert( freeSpace == m_freeSpace );
437 
438  // Used space check
439  unsigned int used_space = 0;
440  ITEMS::iterator itr;
441  for( itr = m_items.begin(); itr != m_items.end(); ++itr )
442  used_space += ( *itr )->GetSize();
443 
444  // If we have a chunk assigned, then there must be an item edited
445  assert( m_chunkSize == 0 || m_item );
446 
447  // Currently reserved chunk is also counted as used
448  used_space += m_chunkSize;
449 
450  assert( ( m_freeSpace + used_space ) == m_currentSize );
451 
452  // Overlapping check TODO
453 #endif /* __WXDEBUG__ */
454 }
int getChunkSize(const CHUNK &aChunk) const
Returns the size of a chunk.
unsigned int m_currentSize
Current container size, expressed in vertices
unsigned int m_chunkSize
Properties of currently modified chunk & item
ITEMS m_items
Stored VERTEX_ITEMs
VERTEX_ITEM * m_item
Currently modified item
unsigned int m_freeSpace
Free space left in the container, expressed in vertices
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
virtual void KIGFX::CACHED_CONTAINER::Unmap ( )
overridepure virtual

>

Finishes the vertices updates stage.

Reimplemented from KIGFX::VERTEX_CONTAINER.

Implemented in KIGFX::CACHED_CONTAINER_GPU, and KIGFX::CACHED_CONTAINER_RAM.

Referenced by KIGFX::GPU_CACHED_MANAGER::EndDrawing().

unsigned int KIGFX::VERTEX_CONTAINER::usedSpace ( ) const
inlineprotectedinherited

Function usedSpace() returns size of the used memory space.

Returns
Size of the used memory space (expressed as a number of vertices).Default initial size of a container (expressed in vertices)

Definition at line 174 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_freeSpace.

Referenced by defragment(), KIGFX::CACHED_CONTAINER_RAM::defragmentResize(), KIGFX::CACHED_CONTAINER_GPU::defragmentResize(), and KIGFX::CACHED_CONTAINER_GPU::defragmentResizeMemcpy().

Member Data Documentation

constexpr unsigned int KIGFX::VERTEX_CONTAINER::DEFAULT_SIZE = 1048576
staticprotectedinherited

Definition at line 180 of file vertex_container.h.

unsigned int KIGFX::CACHED_CONTAINER::m_chunkOffset
protected
unsigned int KIGFX::CACHED_CONTAINER::m_chunkSize
protected

Properties of currently modified chunk & item

Definition at line 103 of file cached_container.h.

Referenced by Allocate(), FinishItem(), reallocate(), SetItem(), and test().

bool KIGFX::VERTEX_CONTAINER::m_failed
protectedinherited

Definition at line 166 of file vertex_container.h.

Referenced by Allocate(), and Clear().

unsigned int KIGFX::VERTEX_CONTAINER::m_initialSize
protectedinherited

Store the initial size, so it can be resized to this on Clear()

Definition at line 160 of file vertex_container.h.

Referenced by Delete().

VERTEX_ITEM* KIGFX::CACHED_CONTAINER::m_item
protected

Currently modified item

Definition at line 100 of file cached_container.h.

Referenced by Allocate(), defragment(), KIGFX::CACHED_CONTAINER_GPU::defragmentResize(), FinishItem(), reallocate(), SetItem(), and test().

ITEMS KIGFX::CACHED_CONTAINER::m_items
protected
unsigned int KIGFX::CACHED_CONTAINER::m_maxIndex
protected

Maximal vertex index number stored in the container

Definition at line 107 of file cached_container.h.

Referenced by Clear(), defragment(), FinishItem(), and KIGFX::CACHED_CONTAINER_RAM::Unmap().


The documentation for this class was generated from the following files: