KiCad PCB EDA Suite
KIGFX::CACHED_CONTAINER_RAM Class Reference

Specialization of CACHED_CONTAINER that stores data in RAM. More...

#include <cached_container_ram.h>

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

Public Member Functions

 CACHED_CONTAINER_RAM (unsigned int aSize=DEFAULT_SIZE)
 
 ~CACHED_CONTAINER_RAM ()
 
void Map () override
 

More...
 
void Unmap () override
 

More...
 
bool IsMapped () const override
 Returns true if vertex buffer is currently mapped. More...
 
unsigned int GetBufferHandle () const override
 Function GetBufferHandle() returns handle to the vertex buffer. More...
 
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...
 
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 defragmentResize (unsigned int aNewSize) override
 Defragments the currently stored data and resizes the buffer. More...
 
bool reallocate (unsigned int aSize)
 Resizes the chunk that stores the current item to the given size. 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

GLuint m_verticesBuffer
 

Handle to vertices buffer

More...
 
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
 

Detailed Description

Specialization of CACHED_CONTAINER that stores data in RAM.

This is mainly for video cards/drivers that do not cope well with video memory mapping.

Definition at line 42 of file cached_container_ram.h.

Member Typedef Documentation

◆ CHUNK

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

Maps size of free memory chunks to their offsets

Definition at line 87 of file cached_container.h.

◆ FREE_CHUNK_MAP

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

Definition at line 88 of file cached_container.h.

◆ ITEMS

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

List of all the stored items.

Definition at line 91 of file cached_container.h.

Constructor & Destructor Documentation

◆ CACHED_CONTAINER_RAM()

CACHED_CONTAINER_RAM::CACHED_CONTAINER_RAM ( unsigned int  aSize = DEFAULT_SIZE)

Definition at line 42 of file cached_container_ram.cpp.

42  :
43  CACHED_CONTAINER( aSize ), m_verticesBuffer( 0 )
44 {
45  glGenBuffers( 1, &m_verticesBuffer );
46  checkGlError( "generating vertices buffer" );
47 
48  m_vertices = static_cast<VERTEX*>( malloc( aSize * VERTEX_SIZE ) );
49 }
int checkGlError(const std::string &aInfo, bool aThrow)
Checks if one of recent OpenGL operations has failed.
Definition: utils.cpp:30
VERTEX * m_vertices
Actual storage memory
CACHED_CONTAINER(unsigned int aSize=DEFAULT_SIZE)
GLuint m_verticesBuffer
Handle to vertices buffer
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:63

References checkGlError(), KIGFX::VERTEX_CONTAINER::m_vertices, m_verticesBuffer, and KIGFX::VERTEX_SIZE.

◆ ~CACHED_CONTAINER_RAM()

CACHED_CONTAINER_RAM::~CACHED_CONTAINER_RAM ( )

Definition at line 52 of file cached_container_ram.cpp.

53 {
54  glDeleteBuffers( 1, &m_verticesBuffer );
55  free( m_vertices );
56 }
VERTEX * m_vertices
Actual storage memory
GLuint m_verticesBuffer
Handle to vertices buffer

References KIGFX::VERTEX_CONTAINER::m_vertices, and m_verticesBuffer.

Member Function Documentation

◆ addFreeChunk()

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

Adds a chunk marked as a free space.

Definition at line 376 of file cached_container.cpp.

377 {
378  assert( aOffset + aSize <= m_currentSize );
379  assert( aSize > 0 );
380 
381  m_freeChunks.insert( std::make_pair( aSize, aOffset ) );
382  m_freeSpace += aSize;
383 }
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.

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

Referenced by KIGFX::CACHED_CONTAINER::Delete(), KIGFX::CACHED_CONTAINER::FinishItem(), and KIGFX::CACHED_CONTAINER::reallocate().

◆ Allocate()

VERTEX * CACHED_CONTAINER::Allocate ( unsigned int  aSize)
overridevirtualinherited

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 106 of file cached_container.cpp.

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

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

◆ Clear()

void CACHED_CONTAINER::Clear ( )
overridevirtualinherited

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

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 192 of file cached_container.cpp.

193 {
195  m_maxIndex = 0;
196  m_failed = false;
197 
198  // Set the size of all the stored VERTEX_ITEMs to 0, so it is clear that they are not held
199  // in the container anymore
200  for( ITEMS::iterator it = m_items.begin(); it != m_items.end(); ++it )
201  ( *it )->setSize( 0 );
202 
203  m_items.clear();
204 
205  // Now there is only free space left
206  m_freeChunks.clear();
207  m_freeChunks.insert( std::make_pair( m_freeSpace, 0 ) );
208 }
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

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

◆ ClearDirty()

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.

146  {
147  m_dirty = false;
148  }

References KIGFX::VERTEX_CONTAINER::m_dirty.

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

◆ defragment()

void CACHED_CONTAINER::defragment ( VERTEX aTarget)
protectedinherited

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

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

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

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

◆ defragmentResize()

bool CACHED_CONTAINER_RAM::defragmentResize ( unsigned int  aNewSize)
overrideprotectedvirtual

Defragments the currently stored data and resizes the buffer.

Parameters
aNewSizeis the new buffer vertex buffer size, expressed as the number of vertices.
Returns
true on success.

Implements KIGFX::CACHED_CONTAINER.

Definition at line 74 of file cached_container_ram.cpp.

75 {
76  wxLogTrace( "GAL_CACHED_CONTAINER",
77  wxT( "Resizing & defragmenting container (memcpy) from %d to %d" ),
78  m_currentSize, aNewSize );
79 
80  // No shrinking if we cannot fit all the data
81  if( usedSpace() > aNewSize )
82  return false;
83 
84 #ifdef __WXDEBUG__
85  PROF_COUNTER totalTime;
86 #endif /* __WXDEBUG__ */
87 
88  VERTEX* newBufferMem = static_cast<VERTEX*>( malloc( aNewSize * VERTEX_SIZE ) );
89 
90  if( !newBufferMem )
91  return false;
92 
93  defragment( newBufferMem );
94 
95  // Switch to the new vertex buffer
96  free( m_vertices );
97  m_vertices = newBufferMem;
98 
99 #ifdef __WXDEBUG__
100  totalTime.Stop();
101 
102  wxLogTrace( "GAL_CACHED_CONTAINER",
103  "Defragmented container storing %d vertices / %.1f ms",
104  m_currentSize - m_freeSpace, totalTime.msecs() );
105 #endif /* __WXDEBUG__ */
106 
107  m_freeSpace += ( aNewSize - m_currentSize );
108  m_currentSize = aNewSize;
109 
110  // Now there is only one big chunk of free memory
111  m_freeChunks.clear();
112  m_freeChunks.insert( std::make_pair( m_freeSpace, m_currentSize - m_freeSpace ) );
113  m_dirty = true;
114 
115  return true;
116 }
void Stop()
save the time when this function was called, and set the counter stane to stop
Definition: profile.h:82
Data structure for vertices {X,Y,Z,R,G,B,A,shader&param}
Definition: vertex_common.h:56
double msecs(bool aSinceLast=false)
Definition: profile.h:143
void defragment(VERTEX *aTarget)
Transfers all stored data to a new buffer, removing empty spaces between the data chunks in the conta...
unsigned int m_currentSize
Current container size, expressed in vertices
The class PROF_COUNTER is a small class to help profiling.
Definition: profile.h:44
VERTEX * m_vertices
Actual storage memory
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 usedSpace() const
Function usedSpace() returns size of the used memory space.
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:63

References KIGFX::CACHED_CONTAINER::defragment(), KIGFX::VERTEX_CONTAINER::m_currentSize, KIGFX::VERTEX_CONTAINER::m_dirty, KIGFX::CACHED_CONTAINER::m_freeChunks, KIGFX::VERTEX_CONTAINER::m_freeSpace, KIGFX::VERTEX_CONTAINER::m_vertices, PROF_COUNTER::msecs(), PROF_COUNTER::Stop(), KIGFX::VERTEX_CONTAINER::usedSpace(), and KIGFX::VERTEX_SIZE.

◆ Delete()

void CACHED_CONTAINER::Delete ( VERTEX_ITEM aItem)
overridevirtualinherited

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 147 of file cached_container.cpp.

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

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

◆ FinishItem()

void CACHED_CONTAINER::FinishItem ( )
overridevirtualinherited

Clean up after adding an item.

Reimplemented from KIGFX::VERTEX_CONTAINER.

Definition at line 73 of file cached_container.cpp.

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

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

◆ GetAllVertices()

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.

101  {
102  return m_vertices;
103  }
VERTEX * m_vertices
Actual storage memory

References KIGFX::VERTEX_CONTAINER::m_vertices.

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

◆ GetBufferHandle()

unsigned int KIGFX::CACHED_CONTAINER_RAM::GetBufferHandle ( ) const
inlineoverridevirtual

Function GetBufferHandle() returns handle to the vertex buffer.

It might be negative if the buffer is not initialized.

Implements KIGFX::CACHED_CONTAINER.

Definition at line 63 of file cached_container_ram.h.

64  {
65  return m_verticesBuffer; // make common with CACHED_CONTAINER_RAM
66  }
GLuint m_verticesBuffer
Handle to vertices buffer

References m_verticesBuffer.

◆ getChunkOffset()

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

Returns the offset of a chunk.

Parameters
aChunkis the chunk.

Definition at line 156 of file cached_container.h.

157  {
158  return aChunk.second;
159  }

Referenced by KIGFX::CACHED_CONTAINER::reallocate(), and KIGFX::CACHED_CONTAINER::showFreeChunks().

◆ getChunkSize()

int KIGFX::CACHED_CONTAINER::getChunkSize ( const CHUNK aChunk) const
inlineprotectedinherited

Returns the size of a chunk.

Parameters
aChunkis the chunk.

Definition at line 146 of file cached_container.h.

147  {
148  return aChunk.first;
149  }

Referenced by KIGFX::CACHED_CONTAINER::reallocate(), KIGFX::CACHED_CONTAINER::showFreeChunks(), and KIGFX::CACHED_CONTAINER::test().

◆ GetSize()

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.

120  {
121  return m_currentSize;
122  }
unsigned int m_currentSize
Current container size, expressed in vertices

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

◆ GetVertices()

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.

111  {
112  return &m_vertices[aOffset];
113  }
VERTEX * m_vertices
Actual storage memory

References KIGFX::VERTEX_CONTAINER::m_vertices.

◆ IsCached()

bool KIGFX::CACHED_CONTAINER::IsCached ( ) const
inlineoverridevirtualinherited

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  }

◆ IsDirty()

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.

129  {
130  return m_dirty;
131  }

References KIGFX::VERTEX_CONTAINER::m_dirty.

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

◆ IsMapped()

bool KIGFX::CACHED_CONTAINER_RAM::IsMapped ( ) const
inlineoverridevirtual

Returns true if vertex buffer is currently mapped.

Implements KIGFX::CACHED_CONTAINER.

Definition at line 54 of file cached_container_ram.h.

55  {
56  return true;
57  }

◆ MakeContainer()

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.

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.

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

◆ Map()

void KIGFX::CACHED_CONTAINER_RAM::Map ( )
inlineoverridevirtual

Finishes the vertices updates stage.

Implements KIGFX::CACHED_CONTAINER.

Definition at line 49 of file cached_container_ram.h.

49 {}

◆ mergeFreeChunks()

void CACHED_CONTAINER::mergeFreeChunks ( )
protectedinherited

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

Definition at line 317 of file cached_container.cpp.

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

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

◆ reallocate()

bool CACHED_CONTAINER::reallocate ( unsigned int  aSize)
protectedinherited

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

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

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

Referenced by KIGFX::CACHED_CONTAINER::Allocate().

◆ SetDirty()

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.

138  {
139  m_dirty = true;
140  }

References KIGFX::VERTEX_CONTAINER::m_dirty.

◆ SetItem()

void CACHED_CONTAINER::SetItem ( VERTEX_ITEM aItem)
overridevirtualinherited

Implements KIGFX::VERTEX_CONTAINER.

Definition at line 56 of file cached_container.cpp.

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

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

◆ Unmap()

void CACHED_CONTAINER_RAM::Unmap ( )
overridevirtual

Finishes the vertices updates stage.

Implements KIGFX::CACHED_CONTAINER.

Definition at line 59 of file cached_container_ram.cpp.

60 {
61  if( !m_dirty )
62  return;
63 
64  // Upload vertices coordinates and shader types to GPU memory
65  glBindBuffer( GL_ARRAY_BUFFER, m_verticesBuffer );
66  checkGlError( "binding vertices buffer" );
67  glBufferData( GL_ARRAY_BUFFER, m_maxIndex * VERTEX_SIZE, m_vertices, GL_STREAM_DRAW );
68  checkGlError( "transferring vertices" );
69  glBindBuffer( GL_ARRAY_BUFFER, 0 );
70  checkGlError( "unbinding vertices buffer" );
71 }
int checkGlError(const std::string &aInfo, bool aThrow)
Checks if one of recent OpenGL operations has failed.
Definition: utils.cpp:30
VERTEX * m_vertices
Actual storage memory
GLuint m_verticesBuffer
Handle to vertices buffer
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:63
unsigned int m_maxIndex
Maximal vertex index number stored in the container

References checkGlError(), KIGFX::VERTEX_CONTAINER::m_dirty, KIGFX::CACHED_CONTAINER::m_maxIndex, KIGFX::VERTEX_CONTAINER::m_vertices, m_verticesBuffer, and KIGFX::VERTEX_SIZE.

◆ usedSpace()

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_currentSize, and KIGFX::VERTEX_CONTAINER::m_freeSpace.

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

Member Data Documentation

◆ DEFAULT_SIZE

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

Definition at line 180 of file vertex_container.h.

◆ m_chunkOffset

◆ m_chunkSize

unsigned int KIGFX::CACHED_CONTAINER::m_chunkSize
protectedinherited

◆ m_currentSize

◆ m_dirty

◆ m_failed

bool KIGFX::VERTEX_CONTAINER::m_failed
protectedinherited

◆ m_freeChunks

◆ m_freeSpace

◆ m_initialSize

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 KIGFX::CACHED_CONTAINER::Delete().

◆ m_item

◆ m_items

◆ m_maxIndex

unsigned int KIGFX::CACHED_CONTAINER::m_maxIndex
protectedinherited

Maximal vertex index number stored in the container

Definition at line 107 of file cached_container.h.

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

◆ m_vertices

◆ m_verticesBuffer

GLuint KIGFX::CACHED_CONTAINER_RAM::m_verticesBuffer
protected

Handle to vertices buffer

Definition at line 70 of file cached_container_ram.h.

Referenced by CACHED_CONTAINER_RAM(), GetBufferHandle(), Unmap(), and ~CACHED_CONTAINER_RAM().


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