| | 109 | class 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 |
| | 164 | class GLBufferObjectSet; |
| | 165 | class GLBufferObjectManager; |
| | 166 | |
| 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); |
| | 345 | |
| | 346 | typedef std::list< ref_ptr<GLBufferObject> > GLBufferObjectList; |
| | 347 | |
| | 348 | class 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 | |
| | 392 | class 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 | |