KiCad PCB EDA Suite
cached_container_ram.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright 2013-2017 CERN
5  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Maciej Suminski <maciej.suminski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
29 #include <gal/opengl/vertex_item.h>
30 #include <gal/opengl/shader.h>
31 #include <gal/opengl/utils.h>
32 
33 #include <confirm.h>
34 #include <list>
35 #include <cassert>
36 
37 #include <wx/log.h>
38 #ifdef KICAD_GAL_PROFILE
39 #include <profile.h>
40 #endif /* KICAD_GAL_PROFILE */
41 
42 using namespace KIGFX;
43 
44 
52 static const wxChar* const traceGalCachedContainer = wxT( "KICAD_GAL_CACHED_CONTAINER" );
53 
54 
56  CACHED_CONTAINER( aSize ),
57  m_verticesBuffer( 0 )
58 {
59  glGenBuffers( 1, &m_verticesBuffer );
60  checkGlError( "generating vertices buffer", __FILE__, __LINE__ );
61 
62  m_vertices = static_cast<VERTEX*>( malloc( aSize * VERTEX_SIZE ) );
63 
64  if( !m_vertices )
65  throw std::bad_alloc();
66 }
67 
68 
70 {
71  if( glDeleteBuffers )
72  glDeleteBuffers( 1, &m_verticesBuffer );
73 
74  free( m_vertices );
75 }
76 
77 
79 {
80  if( !m_dirty )
81  return;
82 
83  // Upload vertices coordinates and shader types to GPU memory
84  glBindBuffer( GL_ARRAY_BUFFER, m_verticesBuffer );
85  checkGlError( "binding vertices buffer", __FILE__, __LINE__ );
86  glBufferData( GL_ARRAY_BUFFER, m_maxIndex * VERTEX_SIZE, m_vertices, GL_STREAM_DRAW );
87  checkGlError( "transferring vertices", __FILE__, __LINE__ );
88  glBindBuffer( GL_ARRAY_BUFFER, 0 );
89  checkGlError( "unbinding vertices buffer", __FILE__, __LINE__ );
90 }
91 
92 
93 bool CACHED_CONTAINER_RAM::defragmentResize( unsigned int aNewSize )
94 {
95  wxLogTrace( traceGalCachedContainer,
96  wxT( "Resizing & defragmenting container (memcpy) from %d to %d" ), m_currentSize,
97  aNewSize );
98 
99  // No shrinking if we cannot fit all the data
100  if( usedSpace() > aNewSize )
101  return false;
102 
103 #ifdef KICAD_GAL_PROFILE
104  PROF_COUNTER totalTime;
105 #endif /* KICAD_GAL_PROFILE */
106 
107  VERTEX* newBufferMem = static_cast<VERTEX*>( malloc( aNewSize * VERTEX_SIZE ) );
108 
109  if( !newBufferMem )
110  throw std::bad_alloc();
111 
112  defragment( newBufferMem );
113 
114  // Switch to the new vertex buffer
115  free( m_vertices );
116  m_vertices = newBufferMem;
117 
118 #ifdef KICAD_GAL_PROFILE
119  totalTime.Stop();
120 
121  wxLogTrace( traceGalCachedContainer, "Defragmented container storing %d vertices / %.1f ms",
122  m_currentSize - m_freeSpace, totalTime.msecs() );
123 #endif /* KICAD_GAL_PROFILE */
124 
125  m_freeSpace += ( aNewSize - m_currentSize );
126  m_currentSize = aNewSize;
127 
128  // Now there is only one big chunk of free memory
129  m_freeChunks.clear();
130  m_freeChunks.insert( std::make_pair( m_freeSpace, m_currentSize - m_freeSpace ) );
131  m_dirty = true;
132 
133  return true;
134 }
void Stop()
Save the time when this function was called, and set the counter stane to stop.
Definition: profile.h:85
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:191
This file is part of the common library.
double msecs(bool aSinceLast=false)
Definition: profile.h:146
void defragment(VERTEX *aTarget)
Transfer all stored data to a new buffer, removing empty spaces between the data chunks in the contai...
int checkGlError(const std::string &aInfo, const char *aFile, int aLine, bool aThrow)
Check if a recent OpenGL operation has failed.
Definition: utils.cpp:45
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
static const wxChar *const traceGalCachedContainer
Flag to enable debug output of the GAL OpenGL cached container.
A small class to help profiling.
Definition: profile.h:45
unsigned int m_freeSpace
Current container size, expressed in vertices.
Class to store VERTEX instances with caching.
CACHED_CONTAINER_RAM(unsigned int aSize=DEFAULT_SIZE)
~CACHED_CONTAINER_RAM()
Finish the vertices updates stage.
bool defragmentResize(unsigned int aNewSize) override
Defragment the currently stored data and resizes the buffer.
void Unmap() override
Finish the vertices updates stage.
FREE_CHUNK_MAP m_freeChunks
Stored VERTEX_ITEMs.
bool m_dirty
Default initial size of a container (expressed in vertices)
unsigned int usedSpace() const
Return size of the used memory space.
Class to handle an item held in a container.
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:67