From 61c48c525c116493231ea48cac6ad5b82ade4baa Mon Sep 17 00:00:00 2001 From: matsukaze Date: Fri, 7 Feb 2014 22:55:03 -0500 Subject: [PATCH] Fixes for style conformance: replace stl containers with Qt --- interface/src/PrimitiveRenderer.cpp | 236 ++++++++++++++++------------ interface/src/PrimitiveRenderer.h | 84 ++++++++-- 2 files changed, 207 insertions(+), 113 deletions(-) diff --git a/interface/src/PrimitiveRenderer.cpp b/interface/src/PrimitiveRenderer.cpp index 05c0c9444a..2f1ab1fd05 100644 --- a/interface/src/PrimitiveRenderer.cpp +++ b/interface/src/PrimitiveRenderer.cpp @@ -5,6 +5,9 @@ * @author: Norman Crafts * @copyright 2014, High Fidelity, Inc. All rights reserved. */ + +#include + #include "InterfaceConfig.h" #include "OctreeElement.h" #include "PrimitiveRenderer.h" @@ -33,6 +36,10 @@ void Primitive::releaseVertexElements() { vReleaseVertexElements(); } +int Primitive::getMemoryUsage() { + return vGetMemoryUsage(); +} + Cube::Cube( float x, @@ -43,7 +50,8 @@ Cube::Cube( unsigned char g, unsigned char b, unsigned char faceExclusions - ) { + ) : + _cpuMemoryUsage(0) { initialize(x, y, z, s, r, g, b, faceExclusions); } @@ -125,6 +133,8 @@ void Cube::initializeVertices( // Add vertex element to list _vertices.push_back(v); + _cpuMemoryUsage += sizeof(VertexElement); + _cpuMemoryUsage += sizeof(VertexElement*); } } } @@ -138,6 +148,7 @@ void Cube::terminateVertices() { for ( ; it != end; ++it) { delete *it; } + _cpuMemoryUsage -= _vertices.size() * (sizeof(VertexElement) + sizeof(VertexElement*)); _vertices.clear(); } @@ -171,6 +182,8 @@ void Cube::initializeTris( // Add tri element to list _tris.push_back(tri); + _cpuMemoryUsage += sizeof(TriElement); + _cpuMemoryUsage += sizeof(TriElement*); } // Now store triangle ACD @@ -182,6 +195,8 @@ void Cube::initializeTris( // Add tri element to list _tris.push_back(tri); + _cpuMemoryUsage += sizeof(TriElement); + _cpuMemoryUsage += sizeof(TriElement*); } } } @@ -195,6 +210,7 @@ void Cube::terminateTris() { for ( ; it != end; ++it) { delete *it; } + _cpuMemoryUsage -= _tris.size() * (sizeof(TriElement) + sizeof(TriElement*)); _tris.clear(); } @@ -214,6 +230,10 @@ void Cube::vReleaseVertexElements() { terminateVertices(); } +int Cube::vGetMemoryUsage() { + return _cpuMemoryUsage; +} + unsigned char Cube::_sFaceIndexToHalfSpaceMask[6] = { OctreeElement::HalfSpace::Bottom, OctreeElement::HalfSpace::Top, @@ -223,10 +243,8 @@ unsigned char Cube::_sFaceIndexToHalfSpaceMask[6] = { OctreeElement::HalfSpace::Far, }; -#define CW_CONSTRUCTION -#ifdef CW_CONSTRUCTION // Construction vectors ordered such that the vertices of each face are -// CW in a right-handed coordinate system with B-L-N at 0,0,0. +// clockwise in a right-handed coordinate system with B-L-N at 0,0,0. float Cube::_sVertexIndexToConstructionVector[24][3] = { // Bottom { 0,0,0 }, @@ -259,42 +277,6 @@ float Cube::_sVertexIndexToConstructionVector[24][3] = { { 1,1,1 }, { 0,1,1 }, }; -#else // CW_CONSTRUCTION -// Construction vectors ordered such that the vertices of each face are -// CCW in a right-handed coordinate system with B-L-N at 0,0,0. -float Cube::_sVertexIndexToConstructionVector[24][3] = { - // Bottom - { 0,0,0 }, - { 0,0,1 }, - { 1,0,1 }, - { 1,0,0 }, - // Top - { 0,1,0 }, - { 1,1,0 }, - { 1,1,1 }, - { 0,1,1 }, - // Right - { 1,0,0 }, - { 1,0,1 }, - { 1,1,1 }, - { 1,1,0 }, - // Left - { 0,0,0 }, - { 0,1,0 }, - { 0,1,1 }, - { 0,0,1 }, - // Near - { 0,0,0 }, - { 1,0,0 }, - { 1,1,0 }, - { 0,1,0 }, - // Far - { 0,0,1 }, - { 0,1,1 }, - { 1,1,1 }, - { 1,0,1 }, -}; -#endif // Normals for a right-handed coordinate system float Cube::_sVertexIndexToNormalVector[6][3] = { @@ -325,18 +307,30 @@ void Renderer::remove( vRemove(id); } +void Renderer::release() { + vRelease(); +} + void Renderer::render() { vRender(); } +int Renderer::getMemoryUsage() { + return vGetMemoryUsage(); +} + +int Renderer::getMemoryUsageGPU() { + return vGetMemoryUsageGPU(); +} + PrimitiveRenderer::PrimitiveRenderer( int maxCount ) : _maxCount(maxCount), _vertexElementCount(0), - _maxVertexElementCount(maxCount), + _maxVertexElementCount(0), _triElementCount(0), - _maxTriElementCount(maxCount), + _maxTriElementCount(0), _primitiveCount(0), _triBufferId(0), @@ -366,7 +360,8 @@ void PrimitiveRenderer::initializeGL() { glGenBuffers(1, &_vertexBufferId); // Set up the element array buffer containing the index ids - int size = _maxCount * sizeof(GLint) * 3; + _maxTriElementCount = _maxCount * 3 * 2; + int size = _maxTriElementCount * sizeof(GLint); _gpuMemoryUsage += size; glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _triBufferId); @@ -376,7 +371,8 @@ void PrimitiveRenderer::initializeGL() { // Set up the array buffer in the form of array of structures // I chose AOS because it maximizes the amount of data tranferred // by a single glBufferSubData call. - size = _maxCount * sizeof(VertexElement); + _maxVertexElementCount = _maxCount * 4; + size = _maxVertexElementCount * sizeof(VertexElement); _gpuMemoryUsage += size; glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId); @@ -429,60 +425,22 @@ void PrimitiveRenderer::terminateBookkeeping() { while (_deconstructTriElementIndex.remove() != 0) ; - std::map::iterator it = _indexToPrimitiveMap.begin(); - std::map::iterator end = _indexToPrimitiveMap.end(); + _vertexElementCount = 0; + _triElementCount = 0; + + QMap::iterator it = _indexToPrimitiveMap.begin(); + QMap::iterator end = _indexToPrimitiveMap.end(); for ( ; it != end; ++it) { - Primitive *primitive = it->second; - delete primitive; - } -} - -int PrimitiveRenderer::vAdd( - Primitive* primitive - ) { - - int index = getAvailablePrimitiveIndex(); - if (index != 0) { - try { - // Take ownership of primitive, including responsibility - // for destruction - _indexToPrimitiveMap[index] = primitive; - constructElements(primitive); - - // No need to keep an extra copy of the vertices - primitive->releaseVertexElements(); - } catch(...) { - // STL failed, recycle the index - _availablePrimitiveIndex.add(index); - index = 0; + Primitive* primitive = it.value(); + if (primitive) { + _cpuMemoryUsage -= primitive->getMemoryUsage(); + delete primitive; } } - return index; -} -void PrimitiveRenderer::vRemove( - int index - ) { - - try { - - // Locate the primitive by id in the associative map - std::map::iterator it = _indexToPrimitiveMap.find(index); - if (it != _indexToPrimitiveMap.end()) { - Primitive *primitive = it->second; - if (primitive) { - _indexToPrimitiveMap[index] = 0; - deconstructElements(primitive); - _availablePrimitiveIndex.add(index); - } - // Not necessary to remove the item from the associative map, because - // the index is going to be re-used, but if you want to... uncomment the following: - //_indexToPrimitiveMap.erase(it); - } - } catch(...) { - // STL failed - } + _cpuMemoryUsage -= _indexToPrimitiveMap.size() * sizeof(Primitive*); + _indexToPrimitiveMap.clear(); } void PrimitiveRenderer::constructElements( @@ -491,8 +449,8 @@ void PrimitiveRenderer::constructElements( // Load vertex elements VertexElementIndexList& vertexElementIndexList = primitive->vertexElementIndices(); + VertexElementList const & vertices = primitive->vertexElements(); { - VertexElementList const & vertices = primitive->vertexElements(); VertexElementList::const_iterator it = vertices.begin(); VertexElementList::const_iterator end = vertices.end(); @@ -507,7 +465,7 @@ void PrimitiveRenderer::constructElements( } // Load tri elements - { + if (vertexElementIndexList.size() == vertices.size()) { TriElementList& tris = primitive->triElements(); TriElementList::iterator it = tris.begin(); TriElementList::iterator end = tris.end(); @@ -530,6 +488,8 @@ void PrimitiveRenderer::constructElements( transferTriElement(index, tri->indices); } } + } else { + // TODO: failure mode } } @@ -647,16 +607,91 @@ void PrimitiveRenderer::transferTriElement( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } +int PrimitiveRenderer::vAdd( + Primitive* primitive + ) { + + QMutexLocker lock(&_guard); + int index = getAvailablePrimitiveIndex(); + if (index != 0) { + try { + // Take ownership of primitive, including responsibility + // for destruction + _indexToPrimitiveMap[index] = primitive; + _constructPrimitiveIndex.add(index); + _cpuMemoryUsage += primitive->getMemoryUsage(); + _cpuMemoryUsage += sizeof(Primitive*); + } catch(...) { + // STL failed, recycle the index + _availablePrimitiveIndex.add(index); + index = 0; + } + } + return index; +} + +void PrimitiveRenderer::vRemove( + int index + ) { + + try { + QMutexLocker lock(&_guard); + + // Locate and remove the primitive by id in the associative map + Primitive* primitive = _indexToPrimitiveMap.take(index); + if (primitive) { + _cpuMemoryUsage -= primitive->getMemoryUsage(); + deconstructElements(primitive); + _availablePrimitiveIndex.add(index); + } + } catch(...) { + // STL failed + } +} + +void PrimitiveRenderer::vRelease() { + + QMutexLocker lock(&_guard); + terminateBookkeeping(); +#if 0 + QMap::iterator it = _indexToPrimitiveMap.begin(); + QMap::iterator end = _indexToPrimitiveMap.end(); + + for ( ; it != end; ++it) { + Primitive* primitive = it->second; + if (primitive) { + it->second = 0; + deconstructElements(primitive); + _availablePrimitiveIndex.add(it->first); + } + } +#endif +} + void PrimitiveRenderer::vRender() { + int id; + + QMutexLocker lock(&_guard); // Now would be an appropriate time to set the element array buffer ids // scheduled for deconstruction to the degenerate case. - int id; while ((id = _deconstructTriElementIndex.remove()) != 0) { deconstructTriElement(id); _availableTriElementIndex.add(id); } + while ((id = _constructPrimitiveIndex.remove()) != 0) { + Primitive* primitive = _indexToPrimitiveMap[id]; + if (primitive) { + constructElements(primitive); + + // No need to keep an extra copy of the vertices + _cpuMemoryUsage -= primitive->getMemoryUsage(); + primitive->releaseVertexElements(); + _cpuMemoryUsage += primitive->getMemoryUsage(); + } + } + // The application uses clockwise winding for the definition of front face, but I // arbitrarily chose counter-clockwise (that is the gl default) to construct the triangulation // so... @@ -683,8 +718,13 @@ void PrimitiveRenderer::vRender() { glDisable(GL_CULL_FACE); - // TODO: does the interface ever change the winding order? - //glFrontFace(GL_CW); err = glGetError(); } +int PrimitiveRenderer::vGetMemoryUsage() { + return _cpuMemoryUsage; +} + +int PrimitiveRenderer::vGetMemoryUsageGPU() { + return _gpuMemoryUsage; +} \ No newline at end of file diff --git a/interface/src/PrimitiveRenderer.h b/interface/src/PrimitiveRenderer.h index f2ebfe23f4..0568d3bb0a 100644 --- a/interface/src/PrimitiveRenderer.h +++ b/interface/src/PrimitiveRenderer.h @@ -9,7 +9,9 @@ #ifndef __interface__PrimitiveRenderer__ #define __interface__PrimitiveRenderer__ -#include +#include +#include + #include "Queue.h" /// Vertex element structure. @@ -46,9 +48,9 @@ typedef } TriElement; -typedef std::vector > VertexElementList; -typedef std::vector > VertexElementIndexList; -typedef std::vector > TriElementList; +typedef QVector VertexElementList; +typedef QVector VertexElementIndexList; +typedef QVector TriElementList; /// /// @class Primitive @@ -81,6 +83,10 @@ public: /// void releaseVertexElements(); + /// Get memory usage. + /// + int getMemoryUsage(); + protected: /// Default constructor prohibited to API user, restricted to service implementer. /// @@ -117,6 +123,10 @@ private: /// virtual void vReleaseVertexElements() = 0; + /// Get memory usage. + /// + virtual int vGetMemoryUsage() = 0; + }; @@ -186,12 +196,14 @@ private: VertexElementIndexList& vVertexElementIndices(); TriElementList& vTriElements(); void vReleaseVertexElements(); - + int vGetMemoryUsage(); private: VertexElementList _vertices; ///< Vertex element list - VertexElementIndexList _vertexIndices; ///< Vertex element index list - TriElementList _tris; ///< Tri element list + VertexElementIndexList _vertexIndices; ///< Vertex element index list + TriElementList _tris; ///< Tri element list + + int _cpuMemoryUsage; ///< Memory allocation of object static const int _sNumFacesPerCube = 6; static const int _sNumVerticesPerCube = 24; @@ -225,12 +237,24 @@ public: int id ///< Primitive id ); + /// Clear all primitives from renderer database + /// + void release(); + /// Render primitive database. /// The render method assumes appropriate GL context and state has /// already been provided for /// void render(); + /// Get memory usage. + /// + int getMemoryUsage(); + + /// Get GPU memory usage. + /// + int getMemoryUsageGPU(); + protected: /// Default constructor prohibited to API user, restricted to service implementer. /// @@ -261,11 +285,26 @@ private: int id ///< Primitive id ) = 0; + /// Clear all primitives from renderer database + /// Service implementer to provide private override for this method + /// in derived class + /// + virtual void vRelease() = 0; + /// Render primitive database. /// Service implementer to provide private virtual override for this method /// in derived class /// virtual void vRender() = 0; + + /// Get memory usage. + /// + virtual int vGetMemoryUsage() = 0; + + /// Get GPU memory usage. + /// + virtual int vGetMemoryUsageGPU() = 0; + }; /// @@ -373,10 +412,22 @@ private: int id ); + /// Clear all primitives from renderer database + /// + void vRelease(); + /// Render triangle database. /// void vRender(); + /// Get memory usage. + /// + int vGetMemoryUsage(); + + /// Get gpu memory usage. + /// + int vGetMemoryUsageGPU(); + private: int _maxCount; @@ -384,23 +435,26 @@ private: // GL related parameters GLuint _triBufferId; ///< GL element array buffer id - GLuint _vertexBufferId; ///< GL vertex array buffer id + GLuint _vertexBufferId; ///< GL vertex array buffer id // Book keeping parameters int _vertexElementCount; ///< Count of vertices - int _maxVertexElementCount; ///< Max count of vertices + int _maxVertexElementCount; ///< Max count of vertices - int _triElementCount; ///< Count of triangles + int _triElementCount; ///< Count of triangles int _maxTriElementCount; ///< Max count of triangles - std::map _indexToPrimitiveMap; ///< Associative map between index and primitive + QMap _indexToPrimitiveMap; ///< Associative map between index and primitive int _primitiveCount; ///< Count of primitives - Queue _availablePrimitiveIndex; ///< Queue of primitive indices available - Queue _availableVertexElementIndex; ///< Queue of vertex element indices available - Queue _availableTriElementIndex; ///< Queue of triangle element indices available - Queue _deconstructTriElementIndex; ///< Queue of triangle element indices requiring GL update + Queue _availablePrimitiveIndex; ///< Queue of primitive indices available + Queue _availableVertexElementIndex; ///< Queue of vertex element indices available + Queue _availableTriElementIndex; ///< Queue of triangle element indices available + Queue _deconstructTriElementIndex; ///< Queue of triangle element indices requiring deletion from GL + Queue _constructPrimitiveIndex; ///< Queue of primitives requiring addition to GL + + QMutex _guard; // Statistics parameters, not necessary for proper operation