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
 Function GetBufferHandle() returns handle to the vertex buffer. More...
 
virtual bool IsMapped () const =0
 Function IsMapped() returns true if vertex buffer is currently mapped. More...
 
virtual void Map () override=0
 > More...
 
virtual void Unmap () override=0
 > More...
 
virtual VERTEXGetAllVertices () const
 Function GetAllVertices() returns all 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 ()
 Function IsDirty() returns information about container cache state. More...
 
void SetDirty ()
 Function SetDirty() sets the dirty flag, so vertices in the container are going to be reuploaded to the GPU on the next frame. More...
 

Static Public Member Functions

static VERTEX_CONTAINERMakeContainer (bool aCached)
 Function MakeContainer() 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)
 Function reallocate() resizes the chunk that stores the current item to the given size. More...
 
virtual bool defragmentResize (unsigned int aNewSize)=0
 Function defragmentResize() 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 ()
 Function mergeFreeChunks() looks for consecutive free memory chunks and merges them, decreasing fragmentation of memory. More...
 
int getChunkSize (const CHUNK &aChunk) const
 Function getChunkSize() returns size of the given chunk. More...
 
unsigned int getChunkOffset (const CHUNK &aChunk) const
 Function getChunkOffset() returns offset of the chunk. More...
 
void addFreeChunk (unsigned int aOffset, unsigned int aSize)
 Function addFreeChunk Adds a chunk marked as free. 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_freeSpace
 How big is the current container, expressed in vertices. More...
 
unsigned int m_currentSize
 Store the initial size, so it can be resized to this on Clear() More...
 
unsigned int m_initialSize
 Actual storage memory (should be handled using malloc/realloc/free to speed up resizing) More...
 
VERTEXm_vertices
 State flags. 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 89 of file cached_container.h.

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

Definition at line 90 of file cached_container.h.

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

List of all the stored items.

Definition at line 93 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 )
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)
How many vertices we can store in the container.
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.
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

Function addFreeChunk Adds a chunk marked as free.

Definition at line 370 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().

371 {
372  assert( aOffset + aSize <= m_currentSize );
373  assert( aSize > 0 );
374 
375  m_freeChunks.insert( std::make_pair( aSize, aOffset ) );
376  m_freeSpace += aSize;
377 }
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
unsigned int m_freeSpace
How big is the current container, expressed in vertices.
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
VERTEX * CACHED_CONTAINER::Allocate ( unsigned int  aSize)
overridevirtual

>

Function Allocate() 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 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.

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 103 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().

104 {
105  assert( m_item != NULL );
106  assert( IsMapped() );
107 
108  if( m_failed )
109  return NULL;
110 
111  unsigned int itemSize = m_item->GetSize();
112  unsigned int newSize = itemSize + aSize;
113 
114  if( newSize > m_chunkSize )
115  {
116  // There is not enough space in the currently reserved chunk, so we have to resize it
117  if( !reallocate( newSize ) )
118  {
119  m_failed = true;
120  return NULL;
121  }
122  }
123 
124  VERTEX* reserved = &m_vertices[m_chunkOffset + itemSize];
125 
126  // Now the item officially possesses the memory chunk
127  m_item->setSize( newSize );
128 
129  // The content has to be updated
130  m_dirty = true;
131 
132 #if CACHED_CONTAINER_TEST > 0
133  test();
134 #endif
135 #if CACHED_CONTAINER_TEST > 2
136  showFreeChunks();
137  showUsedChunks();
138 #endif
139 
140  return reserved;
141 }
void showFreeChunks()
Debug & test functions.
unsigned int m_chunkSize
Properties of currently modified chunk & item
VERTEX * m_vertices
State flags.
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)
Function reallocate() 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
Function IsMapped() returns true if vertex buffer is currently mapped.
void CACHED_CONTAINER::Clear ( )
overridevirtual

>

Function Clear() removes all the data stored in the container and restores its original state.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 189 of file cached_container.cpp.

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

190 {
192  m_failed = false;
193 
194  // Set the size of all the stored VERTEX_ITEMs to 0, so it is clear that they are not held
195  // in the container anymore
196  for( ITEMS::iterator it = m_items.begin(); it != m_items.end(); ++it )
197  ( *it )->setSize( 0 );
198 
199  m_items.clear();
200 
201  // Now there is only free space left
202  m_freeChunks.clear();
203  m_freeChunks.insert( std::make_pair( m_freeSpace, 0 ) );
204 }
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
ITEMS m_items
Stored VERTEX_ITEMs
unsigned int m_freeSpace
How big is the current container, expressed in vertices.
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
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 279 of file cached_container.cpp.

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

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

280 {
281  // Defragmentation
282  ITEMS::iterator it, it_end;
283  int newOffset = 0;
284 
285  for( VERTEX_ITEM* item : m_items )
286  {
287  int itemOffset = item->GetOffset();
288  int itemSize = item->GetSize();
289 
290  // Move an item to the new container
291  memcpy( &aTarget[newOffset], &m_vertices[itemOffset], itemSize * VertexSize );
292 
293  // Update new offset
294  item->setOffset( newOffset );
295 
296  // Move to the next free space
297  newOffset += itemSize;
298  }
299 
300  // Move the current item and place it at the end
301  if( m_item->GetSize() > 0 )
302  {
303  memcpy( &aTarget[newOffset], &m_vertices[m_item->GetOffset()],
304  m_item->GetSize() * VertexSize );
305  m_item->setOffset( newOffset );
306  m_chunkOffset = newOffset;
307  }
308 }
const size_t VertexSize
Definition: vertex_common.h:57
VERTEX * m_vertices
State flags.
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
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
virtual bool KIGFX::CACHED_CONTAINER::defragmentResize ( unsigned int  aNewSize)
protectedpure virtual

Function defragmentResize() 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

>

Function Delete() erases the selected item.

Parameters
aItemis the item to be erased.

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 144 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().

145 {
146  assert( aItem != NULL );
147  assert( m_items.find( aItem ) != m_items.end() || aItem->GetSize() == 0 );
148 
149  int size = aItem->GetSize();
150 
151  if( size == 0 )
152  return; // Item is not stored here
153 
154  int offset = aItem->GetOffset();
155 
156 #if CACHED_CONTAINER_TEST > 1
157  wxLogDebug( wxT( "Removing 0x%08lx (size %d offset %d)" ), (long) aItem, size, offset );
158 #endif
159 
160  // Insert a free memory chunk entry in the place where item was stored
161  addFreeChunk( offset, size );
162 
163  // Indicate that the item is not stored in the container anymore
164  aItem->setSize( 0 );
165 
166  m_items.erase( aItem );
167 
168 #if CACHED_CONTAINER_TEST > 0
169  test();
170 #endif
171 
172  // This dynamic memory freeing optimize memory usage, but in fact can create
173  // out of memory issues because freeing and reallocation large chuncks of memory
174  // can create memory fragmentation and no room to reallocate large chuncks
175  // after many free/reallocate cycles during a session using the same complex board
176  // So it can be disable.
177  // Currently: it is disable to avoid "out of memory" issues
178 #if 0
179  // Dynamic memory freeing, there is no point in holding
180  // a large amount of memory when there is no use for it
181  if( m_freeSpace > ( 0.75 * m_currentSize ) && m_currentSize > m_initialSize )
182  {
184  }
185 #endif
186 }
unsigned int m_initialSize
Actual storage memory (should be handled using malloc/realloc/free to speed up resizing) ...
void addFreeChunk(unsigned int aOffset, unsigned int aSize)
Function addFreeChunk Adds a chunk marked as free.
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
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
How big is the current 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
Function defragmentResize() removes empty spaces between chunks and optionally resizes the container...
void CACHED_CONTAINER::FinishItem ( )
overridevirtual

>

Function FinishItem() does the cleaning 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, 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 
89  if( itemSize > 0 )
90  m_items.insert( m_item );
91 
92  m_item = NULL;
93  m_chunkSize = 0;
94  m_chunkOffset = 0;
95 
96 #if CACHED_CONTAINER_TEST > 1
97  wxLogDebug( wxT( "Finishing item 0x%08lx (size %d)" ), (long) m_item, itemSize );
98  test();
99 #endif
100 }
void addFreeChunk(unsigned int aOffset, unsigned int aSize)
Function addFreeChunk Adds a chunk marked as free.
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
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
virtual VERTEX* KIGFX::VERTEX_CONTAINER::GetAllVertices ( ) const
inlinevirtualinherited

Function GetAllVertices() returns all the vertices stored in the container.

It is especially useful for transferring data to the GPU memory.

Definition at line 112 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_vertices.

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

113  {
114  return m_vertices;
115  }
VERTEX * m_vertices
State flags.
virtual unsigned int KIGFX::CACHED_CONTAINER::GetBufferHandle ( ) const
pure virtual

Function GetBufferHandle() 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

Function getChunkOffset() returns offset of the chunk.

Parameters
aChunkis the chunk.

Definition at line 160 of file cached_container.h.

Referenced by reallocate(), and showFreeChunks().

161  {
162  return aChunk.second;
163  }
int KIGFX::CACHED_CONTAINER::getChunkSize ( const CHUNK aChunk) const
inlineprotected

Function getChunkSize() returns size of the given chunk.

Parameters
aChunkis the chunk.

Definition at line 149 of file cached_container.h.

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

150  {
151  return aChunk.first;
152  }
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 131 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().

132  {
133  return m_currentSize;
134  }
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
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 122 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_vertices.

123  {
124  return &m_vertices[aOffset];
125  }
VERTEX * m_vertices
State flags.
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 ( )
inlineinherited

Function IsDirty() returns information about container cache state.

Clears the flag after calling the function.

Returns
true in case the vertices have to be reuploaded.

Definition at line 141 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_dirty.

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

142  {
143  bool state = m_dirty;
144 
145  m_dirty = false;
146 
147  return state;
148  }
virtual bool KIGFX::CACHED_CONTAINER::IsMapped ( ) const
pure virtual

Function IsMapped() 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

Function MakeContainer() 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 unsigned char* vendor = glGetString( GL_VENDOR );
45 
46  // AMD/ATI cards do not cope well with GPU memory mapping,
47  // so the vertex data has to be kept in RAM
48  if( strstr( (const char*) vendor, "AMD" ) )
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

>

Function Map() 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

Function mergeFreeChunks() looks for consecutive free memory chunks and merges them, decreasing fragmentation of memory.

Definition at line 311 of file cached_container.cpp.

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

312 {
313  if( m_freeChunks.size() <= 1 ) // There are no chunks that can be merged
314  return;
315 
316 #ifdef __WXDEBUG__
317  PROF_COUNTER totalTime;
318 #endif /* __WXDEBUG__ */
319 
320  // Reversed free chunks map - this one stores chunk size with its offset as the key
321  std::list<CHUNK> freeChunks;
322 
323  FREE_CHUNK_MAP::const_iterator it, it_end;
324 
325  for( it = m_freeChunks.begin(), it_end = m_freeChunks.end(); it != it_end; ++it )
326  {
327  freeChunks.push_back( std::make_pair( it->second, it->first ) );
328  }
329 
330  m_freeChunks.clear();
331  freeChunks.sort();
332 
333  std::list<CHUNK>::const_iterator itf, itf_end;
334  unsigned int offset = freeChunks.front().first;
335  unsigned int size = freeChunks.front().second;
336  freeChunks.pop_front();
337 
338  for( itf = freeChunks.begin(), itf_end = freeChunks.end(); itf != itf_end; ++itf )
339  {
340  if( itf->first == offset + size )
341  {
342  // These chunks can be merged, so just increase the current chunk size and go on
343  size += itf->second;
344  }
345  else
346  {
347  // These chunks cannot be merged
348  // So store the previous one
349  m_freeChunks.insert( std::make_pair( size, offset ) );
350  // and let's check the next chunk
351  offset = itf->first;
352  size = itf->second;
353 
354  }
355  }
356 
357  // Add the last one
358  m_freeChunks.insert( std::make_pair( size, offset ) );
359 
360 #ifdef __WXDEBUG__
361  totalTime.Stop();
362  wxLogDebug( "Merged free chunks / %.1f ms", totalTime.msecs() );
363 #endif /* __WXDEBUG__ */
364 #if CACHED_CONTAINER_TEST > 0
365  test();
366 #endif
367 }
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

Function reallocate() 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 207 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::VertexSize.

Referenced by Allocate().

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

Function SetDirty() sets the dirty flag, so vertices in the container are going to be reuploaded to the GPU on the next frame.

Definition at line 155 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_dirty.

156  {
157  m_dirty = true;
158  }
void CACHED_CONTAINER::SetItem ( VERTEX_ITEM aItem)
overridevirtual

>

Function SetItem() sets the item in order to modify or finishes its current modifications.

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 380 of file cached_container.cpp.

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

Referenced by Allocate().

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

Definition at line 400 of file cached_container.cpp.

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

Referenced by Allocate().

401 {
402 #ifdef __WXDEBUG__
403  ITEMS::iterator it;
404 
405  wxLogDebug( wxT( "Used chunks:" ) );
406 
407  for( it = m_items.begin(); it != m_items.end(); ++it )
408  {
409  VERTEX_ITEM* item = *it;
410  unsigned int offset = item->GetOffset();
411  unsigned int size = item->GetSize();
412  assert( size > 0 );
413 
414  wxLogDebug( wxT( "[0x%08x-0x%08x] @ 0x%p (size %d)" ),
415  offset, offset + size - 1, item, size );
416  }
417 #endif /* __WXDEBUG__ */
418 }
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 421 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().

422 {
423 #ifdef __WXDEBUG__
424  // Free space check
425  unsigned int freeSpace = 0;
426  FREE_CHUNK_MAP::iterator itf;
427 
428  for( itf = m_freeChunks.begin(); itf != m_freeChunks.end(); ++itf )
429  freeSpace += getChunkSize( *itf );
430 
431  assert( freeSpace == m_freeSpace );
432 
433  // Used space check
434  unsigned int used_space = 0;
435  ITEMS::iterator itr;
436  for( itr = m_items.begin(); itr != m_items.end(); ++itr )
437  used_space += ( *itr )->GetSize();
438 
439  // If we have a chunk assigned, then there must be an item edited
440  assert( m_chunkSize == 0 || m_item );
441 
442  // Currently reserved chunk is also counted as used
443  used_space += m_chunkSize;
444 
445  assert( ( m_freeSpace + used_space ) == m_currentSize );
446 
447  // Overlapping check TODO
448 #endif /* __WXDEBUG__ */
449 }
int getChunkSize(const CHUNK &aChunk) const
Function getChunkSize() returns size of the given chunk.
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
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
How big is the current container, expressed in vertices.
FREE_CHUNK_MAP m_freeChunks
Stores size & offset of free chunks.
virtual void KIGFX::CACHED_CONTAINER::Unmap ( )
overridepure virtual

>

Function Unmap() 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 184 of file vertex_container.h.

References KIGFX::VERTEX_CONTAINER::m_freeSpace.

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

Member Data Documentation

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

Definition at line 190 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 105 of file cached_container.h.

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

bool KIGFX::VERTEX_CONTAINER::m_dirty
protectedinherited
bool KIGFX::VERTEX_CONTAINER::m_failed
protectedinherited

Definition at line 176 of file vertex_container.h.

Referenced by Allocate(), and Clear().

unsigned int KIGFX::VERTEX_CONTAINER::m_initialSize
protectedinherited

Actual storage memory (should be handled using malloc/realloc/free to speed up resizing)

Definition at line 170 of file vertex_container.h.

Referenced by Delete().

VERTEX_ITEM* KIGFX::CACHED_CONTAINER::m_item
protected

Currently modified item

Definition at line 102 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

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