Show
Ignore:
Timestamp:
10/03/09 11:25:23 (4 years ago)
Author:
robert
Message:

Introduced new GLBufferObject pool for managing the memory footprint taken up by VertexBufferObejct?, ElementBufferObject? and PixelBufferObject?.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/include/osg/BufferObject

    r10600 r10601  
    1818#include <osg/Object> 
    1919#include <osg/buffered_value> 
     20#include <osg/FrameStamp> 
     21 
     22#include <list> 
     23#include <map> 
    2024 
    2125#ifndef GL_ARB_vertex_buffer_object 
     
    103107class BufferObject; 
    104108 
     109class BufferObjectProfile 
     110{ 
     111    public: 
     112        BufferObjectProfile(): 
     113            _target(0), 
     114            _usage(0), 
     115            _size(0) {} 
     116 
     117        BufferObjectProfile(GLenum target, GLenum usage, unsigned int size): 
     118            _target(target), 
     119            _usage(usage), 
     120            _size(size) {} 
     121 
     122        BufferObjectProfile(const BufferObjectProfile& bpo): 
     123            _target(bpo._target), 
     124            _usage(bpo._usage), 
     125            _size(bpo._size) {} 
     126 
     127        bool operator < (const BufferObjectProfile& rhs) const 
     128        { 
     129            if (_target < rhs._target) return true; 
     130            else if (_target > rhs._target) return false; 
     131            if (_usage < rhs._usage) return true; 
     132            else if (_usage > rhs._usage) return false; 
     133            return _size < rhs._size; 
     134        } 
     135 
     136        bool operator == (const BufferObjectProfile& rhs) const 
     137        { 
     138            return (_target == rhs._target) && 
     139                   (_usage == rhs._usage) && 
     140                   (_size == rhs._size); 
     141        } 
     142 
     143        void setProfile(GLenum target, GLenum usage, unsigned int size) 
     144        { 
     145            _target = target; 
     146            _usage = usage; 
     147            _size = size; 
     148        } 
     149 
     150        BufferObjectProfile& operator = (const BufferObjectProfile& rhs) 
     151        { 
     152            _target = rhs._target; 
     153            _usage = rhs._usage; 
     154            _size = rhs._size; 
     155            return *this; 
     156        } 
     157 
     158        GLenum _target; 
     159        GLenum _usage; 
     160        GLenum _size; 
     161}; 
     162 
     163// forward declare 
     164class GLBufferObjectSet; 
     165class GLBufferObjectManager; 
     166 
    105167class OSG_EXPORT GLBufferObject : public Referenced 
    106168{ 
     
    108170 
    109171        GLBufferObject(unsigned int contextID, BufferObject* bufferObject=0); 
     172 
     173        void setProfile(const BufferObjectProfile& profile) { _profile = profile; } 
     174        const BufferObjectProfile& getProfile() const { return _profile; } 
    110175 
    111176        void setBufferObject(BufferObject* bufferObject); 
     
    144209        inline GLsizeiptrARB getOffset(unsigned int i) const { return _bufferEntries[i].offset; } 
    145210 
    146         inline void bindBuffer() const 
     211        void bindBuffer(); 
     212 
     213        inline void unbindBuffer() 
    147214        {  
    148             _extensions->glBindBuffer(_target,_glObjectID); 
    149         } 
    150  
    151         inline void unbindBuffer() const 
    152         {  
    153             _extensions->glBindBuffer(_target,0); 
     215            _extensions->glBindBuffer(_profile._target,0); 
    154216        } 
    155217 
     
    177239        static void deleteBufferObject(unsigned int contextID,GLuint globj); 
    178240 
    179         /** flush all the cached display list which need to be deleted 
    180           * in the OpenGL context related to contextID.*/ 
    181         static void flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime); 
    182  
    183         /** dicard all the cached display list which need to be deleted 
    184           * in the OpenGL context related to contextID. 
    185           * Note, unlike flush no OpenGL calls are made, instead the handles are all removed. 
    186           * this call is useful for when an OpenGL context has been destroyed. */ 
    187         static void discardDeletedBufferObjects(unsigned int contextID); 
     241        static void flushAllDeletedBufferObjects(unsigned int contextID); 
     242        static void discardAllDeletedBufferObjects(unsigned int contextID); 
     243        static void flushDeletedBufferObjects(unsigned int contextID,double currentTime, double& availbleTime); 
     244        static void releaseGLBufferObject(unsigned int contextID, GLBufferObject* to); 
    188245 
    189246        /** Extensions class which encapsulates the querying of extensions and 
     
    265322        GLuint                  _glObjectID; 
    266323 
    267         GLenum                  _target; 
    268         GLenum                  _usage; 
     324        BufferObjectProfile     _profile; 
     325        unsigned int            _allocatedSize; 
    269326 
    270327        bool                    _dirty; 
    271  
    272         mutable unsigned int    _totalSize; 
    273328 
    274329        typedef std::vector<BufferEntry> BufferEntries; 
     
    278333 
    279334    public: 
     335 
     336        GLBufferObjectSet*      _set; 
     337        GLBufferObject*         _previous; 
     338        GLBufferObject*         _next; 
     339        unsigned int            _frameLastUsed; 
     340 
     341    public: 
    280342        Extensions*             _extensions; 
    281343 
    282344}; 
     345 
     346typedef std::list< ref_ptr<GLBufferObject> > GLBufferObjectList; 
     347 
     348class OSG_EXPORT GLBufferObjectSet : public Referenced 
     349{ 
     350    public: 
     351        GLBufferObjectSet(GLBufferObjectManager* parent, const BufferObjectProfile& profile); 
     352 
     353        void handlePendingOrphandedGLBufferObjects(); 
     354        void flushAllDeletedGLBufferObjects(); 
     355        void discardAllDeletedGLBufferObjects(); 
     356        void flushDeletedGLBufferObjects(double currentTime, double& availableTime); 
     357 
     358        GLBufferObject* takeFromOrphans(BufferObject* bufferObject); 
     359        GLBufferObject* takeOrGenerate(BufferObject* bufferObject); 
     360 
     361        void moveToBack(GLBufferObject* to); 
     362        void addToBack(GLBufferObject* to); 
     363        void orphan(GLBufferObject* to); 
     364        void remove(GLBufferObject* to); 
     365 
     366        unsigned int size() const { return _profile._size * _numOfGLBufferObjects; } 
     367 
     368        bool makeSpace(unsigned int& size); 
     369 
     370        bool checkConsistency() const; 
     371 
     372        GLBufferObjectManager* getParent() { return _parent; } 
     373 
     374 
     375    protected: 
     376 
     377        virtual ~GLBufferObjectSet(); 
     378 
     379        OpenThreads::Mutex  _mutex; 
     380 
     381        GLBufferObjectManager*  _parent; 
     382        unsigned int            _contextID; 
     383        BufferObjectProfile     _profile; 
     384        unsigned int            _numOfGLBufferObjects; 
     385        GLBufferObjectList      _orphanedGLBufferObjects; 
     386        GLBufferObjectList      _pendingOrphanedGLBufferObjects; 
     387 
     388        GLBufferObject*         _head; 
     389        GLBufferObject*         _tail; 
     390}; 
     391 
     392class OSG_EXPORT GLBufferObjectManager : public osg::Referenced 
     393{ 
     394    public: 
     395        GLBufferObjectManager(unsigned int contextID); 
     396 
     397        unsigned int getContextID() const { return _contextID; } 
     398 
     399 
     400        void setNumberActiveGLBufferObjects(unsigned int size) { _numActiveGLBufferObjects = size; } 
     401        unsigned int& getNumberActiveGLBufferObjects() { return _numActiveGLBufferObjects; } 
     402        unsigned int getNumberActiveGLBufferObjects() const { return _numActiveGLBufferObjects; } 
     403 
     404        void setNumberOrphanedGLBufferObjects(unsigned int size) { _numOrphanedGLBufferObjects = size; } 
     405        unsigned int& getNumberOrphanedGLBufferObjects() { return _numOrphanedGLBufferObjects; } 
     406        unsigned int getNumberOrphanedGLBufferObjects() const { return _numOrphanedGLBufferObjects; } 
     407 
     408        void setCurrGLBufferObjectPoolSize(unsigned int size) { _currGLBufferObjectPoolSize = size; } 
     409        unsigned int& getCurrGLBufferObjectPoolSize() { return _currGLBufferObjectPoolSize; } 
     410        unsigned int getCurrGLBufferObjectPoolSize() const { return _currGLBufferObjectPoolSize; } 
     411 
     412        void setMaxGLBufferObjectPoolSize(unsigned int size); 
     413        unsigned int getMaxGLBufferObjectPoolSize() const { return _maxGLBufferObjectPoolSize; } 
     414 
     415        bool hasSpace(unsigned int size) const { return (_currGLBufferObjectPoolSize+size)<=_maxGLBufferObjectPoolSize; } 
     416        bool makeSpace(unsigned int size); 
     417 
     418        GLBufferObject* generateGLBufferObject(const osg::BufferObject* bufferObject); 
     419 
     420        void handlePendingOrphandedGLBufferObjects(); 
     421        void flushAllDeletedGLBufferObjects(); 
     422        void discardAllDeletedGLBufferObjects(); 
     423        void flushDeletedGLBufferObjects(double currentTime, double& availableTime); 
     424        void releaseGLBufferObject(GLBufferObject* to); 
     425 
     426        GLBufferObjectSet* getGLBufferObjectSet(const BufferObjectProfile& profile); 
     427 
     428        void newFrame(osg::FrameStamp* fs); 
     429        void resetStats(); 
     430        void reportStats(); 
     431 
     432        unsigned int& getFrameNumber() { return _frameNumber; } 
     433        unsigned int& getNumberFrames() { return _numFrames; } 
     434 
     435        unsigned int& getNumberDeleted() { return _numDeleted; } 
     436        double& getDeleteTime() { return _deleteTime; } 
     437 
     438        unsigned int& getNumberGenerated() { return _numGenerated; } 
     439        double& getGenerateTime() { return _generateTime; } 
     440 
     441        unsigned int& getNumberApplied() { return _numApplied; } 
     442        double& getApplyTime() { return _applyTime; } 
     443 
     444        static osg::ref_ptr<GLBufferObjectManager>& getGLBufferObjectManager(unsigned int contextID); 
     445 
     446    protected: 
     447 
     448        typedef std::map< BufferObjectProfile, osg::ref_ptr<GLBufferObjectSet> > GLBufferObjectSetMap; 
     449        unsigned int            _contextID; 
     450        unsigned int            _numActiveGLBufferObjects; 
     451        unsigned int            _numOrphanedGLBufferObjects; 
     452        unsigned int            _currGLBufferObjectPoolSize; 
     453        unsigned int            _maxGLBufferObjectPoolSize; 
     454        GLBufferObjectSetMap    _glBufferObjectSetMap; 
     455 
     456        unsigned int            _frameNumber; 
     457 
     458        unsigned int            _numFrames; 
     459        unsigned int            _numDeleted; 
     460        double                  _deleteTime; 
     461 
     462        unsigned int            _numGenerated; 
     463        double                  _generateTime; 
     464 
     465        unsigned int            _numApplied; 
     466        double                  _applyTime; 
     467 
     468}; 
     469 
    283470 
    284471class OSG_EXPORT BufferObject : public Object 
     
    295482        virtual const char* className() const { return "BufferObject"; } 
    296483 
    297         void setTarget(GLenum target) { _target = target; } 
    298         GLenum getTarget() const { return _target; } 
     484        void setTarget(GLenum target) { _profile._target = target; } 
     485        GLenum getTarget() const { return _profile._target; } 
    299486 
    300487        /** Set what type of usage the buffer object will have. Options are: 
     
    303490          *          GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY. 
    304491          */ 
    305         void setUsage(GLenum usage) { _usage = usage; } 
     492        void setUsage(GLenum usage) { _profile._usage = usage; } 
    306493 
    307494        /** Get the type of usage the buffer object has been set up for.*/ 
    308         GLenum getUsage() const { return _usage; } 
     495        GLenum getUsage() const { return _profile._usage; } 
     496 
     497        BufferObjectProfile& getProfile() { return _profile; } 
     498        const BufferObjectProfile& getProfile() const { return _profile; } 
    309499 
    310500        void dirty(); 
     
    327517 
    328518        unsigned int getNumBufferData() const { return _bufferDataList.size(); } 
     519 
     520        void setGLBufferObject(unsigned int contextID, GLBufferObject* glbo) { _glBufferObjects[contextID] = glbo; } 
    329521 
    330522        GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _glBufferObjects[contextID].get(); } 
     
    336528        } 
    337529 
     530        unsigned int computeRequiredBufferSize() const; 
     531 
    338532    protected: 
    339533 
     
    343537        typedef osg::buffered_object< osg::ref_ptr<GLBufferObject> > GLBufferObjects; 
    344538 
    345         GLenum                  _target; 
    346         GLenum                  _usage; 
     539        BufferObjectProfile     _profile; 
     540 
    347541        BufferDataList          _bufferDataList; 
    348542 
     
    488682 
    489683        //! Set new size of the buffer object. This will reallocate the memory on the next compile 
    490         inline void setDataSize(unsigned int size) { _dataSize = size; dirty(); } 
     684        inline void setDataSize(unsigned int size) { _profile._size = size; dirty(); } 
    491685 
    492686        //! Get data size of the used buffer  
    493         inline unsigned int getDataSize() const { return _dataSize; } 
     687        inline unsigned int getDataSize() const { return _profile._size; } 
    494688 
    495689        //! Compile the buffer (reallocate the memory if buffer is dirty) 
     
    526720        virtual ~PixelDataBufferObject(); 
    527721 
    528         unsigned int _dataSize; 
    529  
    530722        typedef osg::buffered_value<unsigned int> ModeList; 
    531723