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 <[email protected]>
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
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
42using namespace KIGFX;
43
44
52static const wxChar* const traceGalCachedContainer = wxT( "KICAD_GAL_CACHED_CONTAINER" );
53
54
55CACHED_CONTAINER_RAM::CACHED_CONTAINER_RAM( unsigned int aSize ) :
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
93bool 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}
~CACHED_CONTAINER_RAM()
Finish the vertices updates stage.
void Unmap() override
Finish the vertices updates stage.
bool defragmentResize(unsigned int aNewSize) override
Defragment the currently stored data and resizes the buffer.
Class to store VERTEX instances with caching.
FREE_CHUNK_MAP m_freeChunks
Stored VERTEX_ITEMs.
void defragment(VERTEX *aTarget)
Transfer all stored data to a new buffer, removing empty spaces between the data chunks in the contai...
unsigned int m_currentSize
Store the initial size, so it can be resized to this on Clear()
unsigned int m_freeSpace
Current container size, expressed in vertices.
unsigned int usedSpace() const
Return size of the used memory space.
bool m_dirty
Default initial size of a container (expressed in vertices)
A thread-safe event counter.
Definition: profile.h:226
This file is part of the common library.
static const wxChar *const traceGalCachedContainer
Flag to enable debug output of the GAL OpenGL cached container.
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:243
static constexpr size_t VERTEX_SIZE
Definition: vertex_common.h:67
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
Class to handle an item held in a container.