Commit cd517f67 authored by Maciej Suminski's avatar Maciej Suminski

Added VBO_CONTAINER as a faster storage for vertices (OPENGL_GAL), tuned for...

Added VBO_CONTAINER as a faster storage for vertices (OPENGL_GAL), tuned for exchanging data with GPU.

Removed a few unnecessary variables and fields from OPENGL_GAL.
Added function GAL::ClearCache() for freeing memory used by cached items.
Fixed a few memory leaks (tesselator, PAINTER's settings & VIEW_ITEM's groups).
Changed a few functions into inlines.
parent 876bf75d
...@@ -21,6 +21,7 @@ set(GAL_SRCS ...@@ -21,6 +21,7 @@ set(GAL_SRCS
gal/opengl/opengl_gal.cpp gal/opengl/opengl_gal.cpp
gal/opengl/shader.cpp gal/opengl/shader.cpp
gal/opengl/vbo_item.cpp gal/opengl/vbo_item.cpp
gal/opengl/vbo_container.cpp
gal/cairo/cairo_gal.cpp gal/cairo/cairo_gal.cpp
view/wx_view_controls.cpp view/wx_view_controls.cpp
) )
......
...@@ -99,10 +99,7 @@ CAIRO_GAL::~CAIRO_GAL() ...@@ -99,10 +99,7 @@ CAIRO_GAL::~CAIRO_GAL()
delete cursorPixels; delete cursorPixels;
delete cursorPixelsSaved; delete cursorPixelsSaved;
for( int i = groups.size() - 1; i >= 0; --i ) ClearCache();
{
DeleteGroup( i );
}
deleteBitmaps(); deleteBitmaps();
} }
...@@ -687,13 +684,22 @@ void CAIRO_GAL::EndGroup() ...@@ -687,13 +684,22 @@ void CAIRO_GAL::EndGroup()
} }
void CAIRO_GAL::ClearCache()
{
for( int i = groups.size() - 1; i >= 0; --i )
{
DeleteGroup( i );
}
}
void CAIRO_GAL::DeleteGroup( int aGroupNumber ) void CAIRO_GAL::DeleteGroup( int aGroupNumber )
{ {
storePath(); storePath();
// Delete the Cairo paths // Delete the Cairo paths
for( std::deque<GroupElement>::iterator it = groups[aGroupNumber].begin(), end = groups[aGroupNumber].end(); std::deque<GroupElement>::iterator it, end;
it != end; ++it ) for( it = groups[aGroupNumber].begin(), end = groups[aGroupNumber].end(); it != end; ++it )
{ {
if( it->command == CMD_FILL_PATH || it->command == CMD_STROKE_PATH ) if( it->command == CMD_FILL_PATH || it->command == CMD_STROKE_PATH )
{ {
......
This diff is collapsed.
This diff is collapsed.
...@@ -27,107 +27,98 @@ ...@@ -27,107 +27,98 @@
* @brief Class to handle an item held in a Vertex Buffer Object. * @brief Class to handle an item held in a Vertex Buffer Object.
*/ */
#include <gal/opengl/vbo_container.h>
#include <gal/opengl/vbo_item.h> #include <gal/opengl/vbo_item.h>
#include <cstring> #include <cstring>
using namespace KiGfx; using namespace KiGfx;
VBO_ITEM::VBO_ITEM() : VBO_ITEM::VBO_ITEM( VBO_CONTAINER* aContainer ) :
m_vertices( NULL ),
m_offset( 0 ), m_offset( 0 ),
m_size( 0 ), m_size( 0 ),
m_container( aContainer ),
m_isDirty( true ), m_isDirty( true ),
m_transform( NULL ) m_transform( NULL )
{ {
// By default no shader is used // By default no shader is used
m_shader[0] = 0; m_shader[0] = 0;
// Prepare a block for storing vertices & indices // The item's size is not known yet, so we just start an item in the container
useNewBlock(); aContainer->StartItem( this );
} }
VBO_ITEM::~VBO_ITEM() VBO_ITEM::~VBO_ITEM()
{ {
if( m_isDirty ) m_container->Free( this );
{
// Data is still stored in blocks
std::list<VBO_VERTEX*>::const_iterator v_it, v_end;
for( v_it = m_vertBlocks.begin(), v_end = m_vertBlocks.end(); v_it != v_end; ++v_it )
delete[] *v_it;
}
if( m_vertices )
delete m_vertices;
} }
void VBO_ITEM::PushVertex( const GLfloat* aVertex ) void VBO_ITEM::PushVertex( VBO_VERTEX* aVertex )
{ {
if( m_spaceLeft == 0 )
useNewBlock();
if( m_transform != NULL ) if( m_transform != NULL )
{ {
// Apply transformations // Apply transformations
// X, Y, Z coordinates glm::vec4 vertex( aVertex->x, aVertex->y, aVertex->z, 1.0f );
glm::vec4 vertex( aVertex[0], aVertex[1], aVertex[2], 1.0f );
vertex = *m_transform * vertex; vertex = *m_transform * vertex;
// Replace only coordinates, leave color as it is // Replace only coordinates, leave color as it is
memcpy( &m_vertPtr->x, &vertex[0], CoordByteSize ); aVertex->x = vertex.x;
} aVertex->y = vertex.y;
else aVertex->z = vertex.z;
{
// Add the new vertex
memcpy( &m_vertPtr->x, aVertex, CoordByteSize );
} }
// Apply currently used color // Apply currently used color
memcpy( &m_vertPtr->r, m_color, ColorByteSize ); aVertex->r = m_color[0];
aVertex->g = m_color[1];
aVertex->b = m_color[2];
aVertex->a = m_color[3];
// Apply currently used shader // Apply currently used shader
memcpy( &m_vertPtr->shader, m_shader, ShaderByteSize ); for( int i = 0; i < ShaderStride; ++i )
{
aVertex->shader[i] = m_shader[i];
}
// Move to the next free space m_container->Add( this, aVertex );
m_vertPtr++;
m_size++; m_size++;
m_isDirty = true; m_isDirty = true;
m_spaceLeft--;
} }
void VBO_ITEM::PushVertices( const GLfloat* aVertices, GLuint aSize ) void VBO_ITEM::PushVertices( VBO_VERTEX* aVertices, GLuint aSize )
{ {
for( unsigned int i = 0; i < aSize; ++i ) for( unsigned int i = 0; i < aSize; ++i )
{ {
PushVertex( &aVertices[i * VertStride] ); PushVertex( &aVertices[i] );
} }
} }
GLfloat* VBO_ITEM::GetVertices() VBO_VERTEX* VBO_ITEM::GetVertices()
{ {
if( m_isDirty ) if( m_isDirty )
prepareFinal(); Finish();
return m_vertices; return m_container->GetVertices( this );
} }
void VBO_ITEM::ChangeColor( const COLOR4D& aColor ) void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
{ {
wxASSERT_MSG( false, wxT( "This was not tested yet" ) );
if( m_isDirty ) if( m_isDirty )
prepareFinal(); Finish();
// Point to color of vertices // Point to color of vertices
GLfloat* vertexPtr = m_vertices + ColorOffset; VBO_VERTEX* vertexPtr = GetVertices();
const GLfloat newColor[] = { aColor.r, aColor.g, aColor.b, aColor.a }; const GLfloat newColor[] = { aColor.r, aColor.g, aColor.b, aColor.a };
for( int i = 0; i < m_size; ++i ) for( unsigned int i = 0; i < m_size; ++i )
{ {
memcpy( vertexPtr, newColor, ColorByteSize ); memcpy( &vertexPtr->r, newColor, ColorByteSize );
// Move on to the next vertex // Move on to the next vertex
vertexPtr++; vertexPtr++;
...@@ -135,38 +126,10 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor ) ...@@ -135,38 +126,10 @@ void VBO_ITEM::ChangeColor( const COLOR4D& aColor )
} }
void VBO_ITEM::useNewBlock() void VBO_ITEM::Finish()
{ {
VBO_VERTEX* newVertBlock = new VBO_VERTEX[BLOCK_SIZE]; // The unknown-sized item has just ended, so we need to inform the container about it
m_container->EndItem();
m_vertPtr = newVertBlock;
m_vertBlocks.push_back( newVertBlock );
m_spaceLeft = BLOCK_SIZE;
}
void VBO_ITEM::prepareFinal()
{
if( m_vertices )
delete m_vertices;
// Allocate memory that would store all of vertices
m_vertices = new GLfloat[m_size * VertStride];
// Set the pointer that will move along the buffer
GLfloat* vertPtr = m_vertices;
// Copy blocks of vertices one after another to m_vertices
std::list<VBO_VERTEX*>::const_iterator v_it;
for( v_it = m_vertBlocks.begin(); *v_it != m_vertBlocks.back(); ++v_it )
{
memcpy( vertPtr, *v_it, BLOCK_SIZE * VertByteSize );
delete[] *v_it;
vertPtr += ( BLOCK_SIZE * VertStride );
}
// In the last block we need to copy only used vertices
memcpy( vertPtr, *v_it, ( BLOCK_SIZE - m_spaceLeft ) * VertByteSize );
m_isDirty = false; m_isDirty = false;
} }
...@@ -66,8 +66,8 @@ bool STROKE_FONT::LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNe ...@@ -66,8 +66,8 @@ bool STROKE_FONT::LoadNewStrokeFont( const char* const aNewStrokeFont[], int aNe
while( aNewStrokeFont[j][i] ) while( aNewStrokeFont[j][i] )
{ {
VECTOR2D point; VECTOR2D point( 0.0, 0.0 );
char coordinate[2]; char coordinate[2] = { 0, };
for( int k = 0; k < 2; k++ ) for( int k = 0; k < 2; k++ )
{ {
......
...@@ -79,6 +79,7 @@ PAINTER::PAINTER( GAL* aGal ) : ...@@ -79,6 +79,7 @@ PAINTER::PAINTER( GAL* aGal ) :
PAINTER::~PAINTER() PAINTER::~PAINTER()
{ {
delete m_stroke_font; delete m_stroke_font;
delete m_settings;
} }
......
...@@ -473,6 +473,11 @@ void VIEW::Clear() ...@@ -473,6 +473,11 @@ void VIEW::Clear()
l->items->RemoveAll(); l->items->RemoveAll();
} }
if( m_useGroups )
{
m_gal->ClearCache();
}
} }
......
...@@ -111,7 +111,7 @@ void VIEW_ITEM::setGroup( int aLayer, int aId ) ...@@ -111,7 +111,7 @@ void VIEW_ITEM::setGroup( int aLayer, int aId )
if( m_groupsSize > 0 ) if( m_groupsSize > 0 )
{ {
std::copy( m_groups, m_groups + m_groupsSize, newGroups ); std::copy( m_groups, m_groups + m_groupsSize, newGroups );
delete m_groups; delete[] m_groups;
} }
m_groups = newGroups; m_groups = newGroups;
...@@ -123,7 +123,7 @@ void VIEW_ITEM::deleteGroups() ...@@ -123,7 +123,7 @@ void VIEW_ITEM::deleteGroups()
{ {
if( m_groupsSize > 0 ) if( m_groupsSize > 0 )
{ {
delete m_groups; delete[] m_groups;
m_groupsSize = 0; m_groupsSize = 0;
} }
} }
......
...@@ -212,6 +212,9 @@ public: ...@@ -212,6 +212,9 @@ public:
/// @copydoc GAL::DeleteGroup() /// @copydoc GAL::DeleteGroup()
virtual void DeleteGroup( int aGroupNumber ); virtual void DeleteGroup( int aGroupNumber );
/// @copydoc GAL::ClearCache()
virtual void ClearCache();
// -------------------------------------------------------- // --------------------------------------------------------
// Handling the world <-> screen transformation // Handling the world <-> screen transformation
// -------------------------------------------------------- // --------------------------------------------------------
......
...@@ -370,6 +370,11 @@ public: ...@@ -370,6 +370,11 @@ public:
*/ */
virtual void DeleteGroup( int aGroupNumber ) = 0; virtual void DeleteGroup( int aGroupNumber ) = 0;
/**
* @brief Delete all data created during caching of graphic items.
*/
virtual void ClearCache() = 0;
// -------------------------------------------------------- // --------------------------------------------------------
// Handling the world <-> screen transformation // Handling the world <-> screen transformation
// -------------------------------------------------------- // --------------------------------------------------------
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
// OpenGL mathematics library // OpenGL mathematics library
#define GLM_FORCE_RADIANS #define GLM_FORCE_RADIANS
#include <gal/opengl/glm/gtc/matrix_transform.hpp>
#include <gal/opengl/vbo_item.h> #include <gal/opengl/vbo_item.h>
#include <gal/opengl/shader.h> #include <gal/opengl/shader.h>
...@@ -56,7 +58,7 @@ ...@@ -56,7 +58,7 @@
namespace KiGfx namespace KiGfx
{ {
class SHADER; class SHADER;
class VBO_ITEM; class VBO_CONTAINER;
/** /**
* @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer. * @brief Class OpenGL_GAL is the OpenGL implementation of the Graphics Abstraction Layer.
...@@ -236,6 +238,9 @@ public: ...@@ -236,6 +238,9 @@ public:
/// @copydoc GAL::DeleteGroup() /// @copydoc GAL::DeleteGroup()
virtual void DeleteGroup( int aGroupNumber ); virtual void DeleteGroup( int aGroupNumber );
/// @copydoc GAL::ClearCache()
virtual void ClearCache();
// -------------------------------------------------------- // --------------------------------------------------------
// Handling the world <-> screen transformation // Handling the world <-> screen transformation
// -------------------------------------------------------- // --------------------------------------------------------
...@@ -315,6 +320,13 @@ public: ...@@ -315,6 +320,13 @@ public:
shaderPath = aPath; shaderPath = aPath;
} }
///< Parameters passed to the GLU tesselator
typedef struct
{
VBO_ITEM* vboItem; ///< VBO_ITEM for storing new vertices
std::vector<GLdouble*>& intersectPoints; ///< Intersect points, that have to be freed
} TessParams;
protected: protected:
virtual void DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); virtual void DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
...@@ -336,20 +348,19 @@ private: ...@@ -336,20 +348,19 @@ private:
wxEvtHandler* mouseListener; wxEvtHandler* mouseListener;
wxEvtHandler* paintListener; wxEvtHandler* paintListener;
// Display lists // Display lists (used in shaderless mode)
GLuint displayListsArcs; ///< Arc display list VBO_CONTAINER* precomputedContainer; ///< Container for storing display lists
VBO_ITEM verticesArc;
GLuint displayListCircle; ///< Circle display list GLuint displayListCircle; ///< Circle display list
VBO_ITEM verticesCircle; VBO_ITEM* verticesCircle;
GLuint displayListSemiCircle; ///< Semi circle display list GLuint displayListSemiCircle; ///< Semi circle display list
VBO_ITEM verticesSemiCircle; VBO_ITEM* verticesSemiCircle;
// Vertex buffer objects related fields // Vertex buffer objects related fields
std::deque<VBO_ITEM*> vboItems; ///< Stores informations about VBO objects std::deque<VBO_ITEM*> vboItems; ///< Stores informations about VBO objects
VBO_ITEM* curVboItem; ///< Currently used VBO_ITEM (for grouping) VBO_ITEM* curVboItem; ///< Currently used VBO_ITEM (for grouping)
GLuint curVboVertId; ///< Currently used vertices VBO handle VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs
GLuint curVboIndId; ///< Currently used indices VBO handle GLuint vboVertices; ///< Currently used vertices VBO handle
int vboSize; ///< Amount of vertices stored in VBO GLuint vboIndices; ///< Currently used indices VBO handle
bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt
glm::mat4 transform; ///< Current transformation matrix glm::mat4 transform; ///< Current transformation matrix
std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices
...@@ -362,6 +373,7 @@ private: ...@@ -362,6 +373,7 @@ private:
// Polygon tesselation // Polygon tesselation
GLUtesselator* tesselator; ///< Pointer to the tesselator GLUtesselator* tesselator; ///< Pointer to the tesselator
std::vector<GLdouble*> tessIntersects; ///< Storage of intersecting points
// Shader // Shader
// Possible types of shaders // Possible types of shaders
...@@ -519,12 +531,20 @@ private: ...@@ -519,12 +531,20 @@ private:
* @brief Starts drawing in immediate mode or does nothing if an item's caching has started. * @brief Starts drawing in immediate mode or does nothing if an item's caching has started.
* @param aMode specifies the primitive or primitives that will be created. * @param aMode specifies the primitive or primitives that will be created.
*/ */
inline void begin( GLenum aMode ); inline void begin( GLenum aMode )
{
if( !isGrouping )
glBegin( aMode );
}
/** /**
* @brief Ends drawing in immediate mode or does nothing if an item's caching has started. * @brief Ends drawing in immediate mode or does nothing if an item's caching has started.
*/ */
inline void end(); inline void end()
{
if( !isGrouping )
glEnd();
}
/** /**
* @brief Adds vertex to the current item or draws it in immediate mode. * @brief Adds vertex to the current item or draws it in immediate mode.
...@@ -532,7 +552,19 @@ private: ...@@ -532,7 +552,19 @@ private:
* @param aY is Y coordinate. * @param aY is Y coordinate.
* @param aZ is Z coordinate. * @param aZ is Z coordinate.
*/ */
inline void vertex3( double aX, double aY, double aZ ); inline void vertex3( double aX, double aY, double aZ )
{
if( isGrouping )
{
// New vertex coordinates for VBO
VBO_VERTEX vertex( aX, aY, aZ );
curVboItem->PushVertex( &vertex );
}
else
{
glVertex3d( aX, aY, aZ );
}
}
/** /**
* @brief Function that replaces glTranslate and behaves according to isGrouping variable. * @brief Function that replaces glTranslate and behaves according to isGrouping variable.
...@@ -543,7 +575,17 @@ private: ...@@ -543,7 +575,17 @@ private:
* @param aY is translation in Y axis direction. * @param aY is translation in Y axis direction.
* @param aZ is translation in Z axis direction. * @param aZ is translation in Z axis direction.
*/ */
inline void translate3( double aX, double aY, double aZ ); inline void translate3( double aX, double aY, double aZ )
{
if( isGrouping )
{
transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) );
}
else
{
glTranslated( aX, aY, aZ );
}
}
/** /**
* @brief Function that replaces glColor and behaves according to isGrouping variable. * @brief Function that replaces glColor and behaves according to isGrouping variable.
...@@ -555,7 +597,17 @@ private: ...@@ -555,7 +597,17 @@ private:
* @param aB is blue component. * @param aB is blue component.
* @param aA is alpha component. * @param aA is alpha component.
*/ */
inline void color4( double aRed, double aGreen, double aBlue, double aAlpha ); inline void color4( double aRed, double aGreen, double aBlue, double aAlpha )
{
if( isGrouping )
{
curVboItem->UseColor( COLOR4D( aRed, aGreen, aBlue, aAlpha ) );
}
else
{
glColor4d( aRed, aGreen, aBlue, aAlpha );
}
}
/** /**
* @brief Function that replaces glColor and behaves according to isGrouping variable. * @brief Function that replaces glColor and behaves according to isGrouping variable.
...@@ -564,7 +616,17 @@ private: ...@@ -564,7 +616,17 @@ private:
* *
* @param aColor is the new color. * @param aColor is the new color.
*/ */
inline void color4( const COLOR4D& aColor ); inline void color4( const COLOR4D& aColor )
{
if( isGrouping )
{
curVboItem->UseColor( aColor );
}
else
{
glColor4d( aColor.r, aColor.g, aColor.b, aColor.a);
}
}
/** /**
* @brief Function that sets shader and its parameters for the currently used VBO_ITEM. * @brief Function that sets shader and its parameters for the currently used VBO_ITEM.
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file vbo_container.h
* @brief Class to store VBO_ITEMs.
*/
#ifndef VBO_CONTAINER_H_
#define VBO_CONTAINER_H_
#include <GL/gl.h>
#include <map>
#include <wx/log.h>
namespace KiGfx
{
class VBO_ITEM;
typedef struct VBO_VERTEX VBO_VERTEX;
class VBO_CONTAINER
{
public:
VBO_CONTAINER( int aSize = 1048576 );
~VBO_CONTAINER();
///< Maps size of free memory chunks to their offsets
typedef std::pair<const unsigned int, unsigned int> Chunk;
typedef std::multimap<const unsigned int, unsigned int> FreeChunkMap;
///< Maps size of reserved memory chunks to their owners (VBO_ITEMs)
typedef std::pair<VBO_ITEM* const, Chunk> ReservedChunk;
typedef std::multimap<VBO_ITEM* const, Chunk> ReservedChunkMap;
/**
* Function StartItem()
* Starts an unknown sized item. After calling the function it is possible to add vertices
* using function Add().
* @param aVboItem is the item that is going to store vertices in the container.
*/
void StartItem( VBO_ITEM* aVboItem );
/**
* Function EndItem()
* Marks current item as finished and returns unused memory to the pool. StartItem() function
* has to be called first.
*/
void EndItem();
/**
* Function Add()
* Stores given number of vertices in the container for the specific VBO_ITEM.
* @param aVboItem is the owner of the vertices.
* @param aVertex are vertices data to be stored.
* @param aSize is the number of vertices to be added.
*/
void Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned int aSize = 1 );
/**
* Function Free()
* Frees the chunk reserved by the aVboItem.
* @param aVboItem is the owner of the chunk to be freed.
*/
inline void Free( VBO_ITEM* aVboItem )
{
ReservedChunkMap::iterator it = m_reservedChunks.find( aVboItem );
free( it );
// Dynamic memory freeing, there is no point in holding
// a large amount of memory when there is no use for it
if( m_freeSpace > ( m_currentSize / 2 ) )
{
resizeContainer( m_currentSize / 2 );
}
}
/**
* Function GetAllVertices()
* Returns all vertices stored in the container. It is especially useful for transferring
* data to the GPU memory.
*/
VBO_VERTEX* GetAllVertices() const;
/**
* Function GetVertices()
* Returns vertices stored by the specific item.
* @aVboItem is the specific item.
*/
VBO_VERTEX* GetVertices( const VBO_ITEM* aVboItem ) const;
/**
* Function GetSize()
* Returns amount of vertices currently stored in the container.
*/
inline int GetSize() const
{
return m_currentSize;
}
private:
///< Stores size & offset of free chunks.
FreeChunkMap m_freeChunks;
///< Stores owners (VBO_ITEM*) of reserved chunks and their size & offset.
ReservedChunkMap m_reservedChunks;
/**
* Function allocate()
* Finds an offset where the number of vertices can be stored in a continous space. If there is
* no such chunk, appropriate amount of memory is allocated first.
* @param aVboItem is the owner of vertices to be stored.
* @param aSize is the number of vertices to be stored.
*/
unsigned int allocate( VBO_ITEM* aVboItem, unsigned int aSize );
/**
* Function getChunkSize()
* Returns size of the given chunk (works both for reserved and free chunks).
* @param aChunk is the chunk.
*/
inline int getChunkSize( const Chunk& aChunk ) const
{
return aChunk.first;
}
inline int getChunkSize( const ReservedChunk& aChunk ) const
{
return aChunk.second.first;
}
/**
* Function getChunkOffset()
* Returns offset of the given chunk (works both for reserved and free chunks).
* @param aChunk is the chunk.
*/
inline unsigned int getChunkOffset( const Chunk& aChunk ) const
{
return aChunk.second;
}
inline unsigned int getChunkOffset( const ReservedChunk& aChunk ) const
{
return aChunk.second.second;
}
/**
* Function getChunkOffset()
* Upadtes offset of the given chunk (works both for reserved and free chunks).
* !! IMPORTANT: it does not reallocate the chunk, it just changes its properties.
* @param aChunk is the chunk.
*/
inline void setChunkOffset( Chunk& aChunk, unsigned int aOffset ) const
{
aChunk.second = aOffset;
}
inline void setChunkOffset( ReservedChunk& aChunk, unsigned int aOffset ) const
{
aChunk.second.second = aOffset;
}
/**
* Function getChunkVboItem()
* Returns owner of the given reserved chunk.
* @param aChunk is the chunk.
*/
inline VBO_ITEM* getChunkVboItem( const ReservedChunk& aChunk ) const
{
return aChunk.first;
}
/**
* Function defragment()
* Removes empty spaces between chunks, so after that there is a long continous space
* for storing vertices at the and of the container.
* @return false in case of failure (eg. memory shortage)
*/
bool defragment( VBO_VERTEX* aTarget = NULL );
/**
* Function resizeChunk()
* Changes size of the chunk that stores vertices of aVboItem.
* @param aVboItem is the item for which reserved space size should be changed.
* @param aNewSize is the new size for the aVboItem, expressed in vertices number.
*/
void resizeChunk( VBO_ITEM* aVboItem, int aNewSize );
/**
* Function resizeContainer()
* Prepares a bigger container of a given size.
* @param aNewSize is the new size of container, expressed in vertices
* @return false in case of failure (eg. memory shortage)
*/
bool resizeContainer( unsigned int aNewSize );
/**
* Function free()
* Frees the space described in aChunk and returns it to the free space pool.
* @param aChunk is a space to be freed.
*/
void free( const ReservedChunkMap::iterator& aChunk );
///< How many vertices we can store in the container
unsigned int m_freeSpace;
///< How big is the current container, expressed in vertices
unsigned int m_currentSize;
///< Actual storage memory
VBO_VERTEX* m_vertices;
///< A flag saying if there is the item with an unknown size being added
bool itemStarted;
///< Variables holding the state of the item currently being added
unsigned int itemSize, itemChunkSize;
VBO_ITEM* item;
/**
* Function getPowerOf2()
* Returns the nearest power of 2, bigger than aNumber.
* @param aNumber is the number for which we look for a bigger power of 2.
*/
unsigned int getPowerOf2( unsigned int aNumber )
{
unsigned int power = 1;
while( power < aNumber && power )
power <<= 1;
return power;
}
};
} // namespace KiGfx
#endif /* VBO_CONTAINER_H_ */
...@@ -36,8 +36,6 @@ ...@@ -36,8 +36,6 @@
#include <cstddef> #include <cstddef>
#include <list>
namespace KiGfx namespace KiGfx
{ {
typedef struct VBO_VERTEX typedef struct VBO_VERTEX
...@@ -45,12 +43,31 @@ typedef struct VBO_VERTEX ...@@ -45,12 +43,31 @@ typedef struct VBO_VERTEX
GLfloat x, y, z; // Coordinates GLfloat x, y, z; // Coordinates
GLfloat r, g, b, a; // Color GLfloat r, g, b, a; // Color
GLfloat shader[4]; // Shader type & params GLfloat shader[4]; // Shader type & params
GLfloat _padding;
VBO_VERTEX()
{}
VBO_VERTEX( const GLfloat aX, const GLfloat aY, const GLfloat aZ ) :
x( aX ), y( aY ), z( aZ )
{}
VBO_VERTEX( const GLfloat *aData ) :
x( aData[0] ), y( aData[1] ), z( aData[2] )
{}
operator GLfloat*()
{
return &x;
}
} VBO_VERTEX; } VBO_VERTEX;
class VBO_CONTAINER;
class VBO_ITEM class VBO_ITEM
{ {
public: public:
VBO_ITEM(); VBO_ITEM( VBO_CONTAINER* aContainer );
~VBO_ITEM(); ~VBO_ITEM();
/** /**
...@@ -60,7 +77,7 @@ public: ...@@ -60,7 +77,7 @@ public:
* @param aVertex is a vertex to be added. * @param aVertex is a vertex to be added.
* @param aShader is an attribute for shader. * @param aShader is an attribute for shader.
*/ */
void PushVertex( const GLfloat* aVertex ); void PushVertex( VBO_VERTEX* aVertex );
/** /**
* Function PushVertices() * Function PushVertices()
...@@ -71,14 +88,14 @@ public: ...@@ -71,14 +88,14 @@ public:
* @param aSize is an amount of vertices to be added. * @param aSize is an amount of vertices to be added.
* @param aShader is an attribute for shader. * @param aShader is an attribute for shader.
*/ */
void PushVertices( const GLfloat* aVertices, GLuint aSize ); void PushVertices( VBO_VERTEX* aVertices, GLuint aSize );
/** /**
* Function GetVertices() * Function GetVertices()
* Returns a pointer to the array containing all vertices. * Returns a pointer to the array containing all vertices.
* @return Pointer to vertices packed in format {X, Y, Z, R, G, B, A}. * @return Pointer to vertices packed in format {X, Y, Z, R, G, B, A}.
*/ */
GLfloat* GetVertices(); VBO_VERTEX* GetVertices();
/** /**
...@@ -86,7 +103,7 @@ public: ...@@ -86,7 +103,7 @@ public:
* Returns information about number of vertices stored. * Returns information about number of vertices stored.
* @param Amount of vertices. * @param Amount of vertices.
*/ */
inline int GetSize() const inline unsigned int GetSize() const
{ {
return m_size; return m_size;
} }
...@@ -96,7 +113,7 @@ public: ...@@ -96,7 +113,7 @@ public:
* Sets data offset in the VBO. * Sets data offset in the VBO.
* @param aOffset is the offset expressed as a number of vertices. * @param aOffset is the offset expressed as a number of vertices.
*/ */
void SetOffset( int aOffset ) void SetOffset( unsigned int aOffset )
{ {
m_offset = aOffset; m_offset = aOffset;
} }
...@@ -106,7 +123,7 @@ public: ...@@ -106,7 +123,7 @@ public:
* Returns data offset in the VBO. * Returns data offset in the VBO.
* @return Data offset expressed as a number of vertices. * @return Data offset expressed as a number of vertices.
*/ */
inline int GetOffset() const inline unsigned int GetOffset() const
{ {
return m_offset; return m_offset;
} }
...@@ -156,16 +173,8 @@ public: ...@@ -156,16 +173,8 @@ public:
} }
} }
///< Informs the container that there will be no more vertices for the current VBO_ITEM
inline void FreeVerticesData() void Finish();
{
if( m_vertices && !m_isDirty )
{
delete[] m_vertices;
m_vertices = NULL;
}
}
///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX). ///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX).
static const int VertByteSize = sizeof(VBO_VERTEX); static const int VertByteSize = sizeof(VBO_VERTEX);
...@@ -191,28 +200,12 @@ public: ...@@ -191,28 +200,12 @@ public:
static const int IndByteSize = sizeof(GLuint); static const int IndByteSize = sizeof(GLuint);
private: private:
///< Contains vertices coordinates and colors. ///< Offset and size of data stored in the VBO_CONTAINER.
///< Packed by 7 floats for each vertex: {X, Y, Z, R, G, B, A} unsigned int m_offset;
GLfloat* m_vertices; unsigned int m_size;
///< Lists of data blocks storing vertices ///< Storage for vertices.
std::list<VBO_VERTEX*> m_vertBlocks; VBO_CONTAINER* m_container;
///< Pointers to current blocks that should be used for storing data
VBO_VERTEX* m_vertPtr;
///< How many vertices can be stored in the current buffer
int m_spaceLeft;
///< Number of vertices stored in a single block
static const int BLOCK_SIZE = 256;
///< Creates a new block for storing vertices data
void useNewBlock();
///< Prepares a continuous block of data that can be copied to graphics card buffer.
void prepareFinal();
///< Offset and size of data in VBO.
int m_offset;
int m_size;
///< Color used for new vertices pushed. ///< Color used for new vertices pushed.
GLfloat m_color[ColorStride]; GLfloat m_color[ColorStride];
......
...@@ -68,7 +68,7 @@ public: ...@@ -68,7 +68,7 @@ public:
ALL = 0xff ALL = 0xff
}; };
VIEW_ITEM() : m_view( NULL ), m_viewVisible( true ), m_groupsSize( 0 ) {} VIEW_ITEM() : m_view( NULL ), m_viewVisible( true ), m_groups( NULL ), m_groupsSize( 0 ) {}
/** /**
* Destructor. For dynamic views, removes the item from the view. * Destructor. For dynamic views, removes the item from the view.
...@@ -76,6 +76,7 @@ public: ...@@ -76,6 +76,7 @@ public:
virtual ~VIEW_ITEM() virtual ~VIEW_ITEM()
{ {
ViewRelease(); ViewRelease();
delete[] m_groups;
}; };
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment