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/src/osg/BufferObject.cpp

    r10600 r10601  
    3838static DeletedBufferObjectCache s_deletedBufferObjectCache; 
    3939 
     40unsigned int s_minimumNumberOfGLBufferObjectsToRetainInCache = 1000; 
     41 
    4042////////////////////////////////////////////////////////////////////////////////////////////////////// 
    4143// 
     
    4547    _contextID(contextID), 
    4648    _glObjectID(0), 
    47     _target(0), 
    48     _usage(0), 
     49    _profile(0,0,0), 
     50    _allocatedSize(0), 
    4951    _dirty(true), 
    50     _totalSize(0), 
    5152    _bufferObject(0), 
     53    _set(0), 
     54    _previous(0), 
     55    _next(0), 
    5256    _extensions(0) 
    5357{ 
     
    5963GLBufferObject::~GLBufferObject() 
    6064{ 
    61     if (_glObjectID!=0) GLBufferObject::deleteBufferObject(_contextID, _glObjectID); 
    62  
     65} 
     66 
     67void GLBufferObject::bindBuffer() 
     68{ 
     69    _extensions->glBindBuffer(_profile._target,_glObjectID); 
     70    if (_set) _set->moveToBack(this); 
     71} 
     72 
     73void GLBufferObject::setBufferObject(BufferObject* bufferObject) 
     74{ 
     75    assign(bufferObject); 
    6376} 
    6477 
     
    6982    if (_bufferObject) 
    7083    { 
    71         _target = bufferObject->getTarget(); 
    72         _usage = bufferObject->getUsage(); 
    73  
    74         _totalSize = 0; 
     84        _profile = bufferObject->getProfile(); 
    7585 
    7686        _dirty = true; 
     
    8090    else 
    8191    { 
    82         _target = 0; 
    83         _usage = 0; 
    84  
    85         _totalSize = 0; 
     92        _profile.setProfile(0,0,0); 
    8693 
    8794        // clear all previous entries; 
     
    101108 
    102109    _bufferEntries.reserve(_bufferObject->getNumBufferData()); 
    103  
    104     _totalSize = 0; 
    105110 
    106111    bool compileAll = false; 
     
    156161    } 
    157162 
     163 
    158164    if (i<_bufferEntries.size()) 
    159165    { 
     
    162168    } 
    163169 
    164     _extensions->glBindBuffer(_target, _glObjectID); 
    165  
    166     if (newTotalSize != _totalSize) 
    167     { 
    168         _totalSize = newTotalSize; 
    169         _extensions->glBufferData(_target, _totalSize, NULL, _usage); 
     170    _extensions->glBindBuffer(_profile._target, _glObjectID); 
     171 
     172    if (newTotalSize > _profile._size) 
     173    { 
     174        osg::notify(osg::NOTICE)<<"newTotalSize="<<newTotalSize<<", _profile._size="<<_profile._size<<std::endl; 
     175 
     176        _profile._size = newTotalSize; 
     177        if (_set) 
     178        { 
     179            // remove self from original set 
     180            _set->remove(this); 
     181 
     182            // get the new set for the new profile 
     183            _set = _set->getParent()->getGLBufferObjectSet(_profile); 
     184 
     185            // register self with new set. 
     186            _set->addToBack(this); 
     187        } 
     188 
     189    } 
     190 
     191    if (_allocatedSize != _profile._size) 
     192    { 
     193        _allocatedSize = _profile._size; 
     194        _extensions->glBufferData(_profile._target, _profile._size, NULL, _profile._usage); 
    170195    } 
    171196 
     
    189214                memcpy(vboMemory + (GLsizeiptrARB)entry.offset, entry.dataSource->getDataPointer(), entry.dataSize); 
    190215            else 
    191                 _extensions->glBufferSubData(_target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer()); 
     216                _extensions->glBufferSubData(_profile._target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer()); 
    192217 
    193218        } 
     
    195220 
    196221    // Unmap the texture image buffer 
    197     if (vboMemory) _extensions->glUnmapBuffer(_target); 
    198 } 
    199  
    200 GLBufferObject* GLBufferObject::createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject) 
    201 { 
    202     return new GLBufferObject(contextID, const_cast<BufferObject*>(bufferObject)); 
     222    if (vboMemory) _extensions->glUnmapBuffer(_profile._target); 
     223 
     224 
    203225} 
    204226 
     
    210232        _glObjectID = 0; 
    211233 
    212         _totalSize = 0; 
     234        _allocatedSize = 0; 
    213235        _bufferEntries.clear(); 
    214236    } 
    215237} 
    216238 
    217  
    218239void GLBufferObject::deleteBufferObject(unsigned int contextID,GLuint globj) 
    219240{ 
    220     if (globj!=0) 
    221     { 
    222         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache); 
    223  
    224         // insert the globj into the cache for the appropriate context. 
    225         s_deletedBufferObjectCache[contextID].insert(BufferObjectMap::value_type(0,globj)); 
    226     } 
    227 } 
     241    osg::notify(osg::NOTICE)<<"GLBufferObject::deleteBufferObject("<<std::endl; 
     242} 
     243#if 0 
    228244 
    229245void GLBufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime) 
     
    269285    dll.clear(); 
    270286} 
    271  
     287#endif 
    272288////////////////////////////////////////////////////////////////////////////// 
    273289// 
     
    420436} 
    421437 
    422 #if 1 
    423  
    424438////////////////////////////////////////////////////////////////////////////////////////////////////// 
    425439// 
     440// GLBufferObjectSet 
     441// 
     442GLBufferObjectSet::GLBufferObjectSet(GLBufferObjectManager* parent, const BufferObjectProfile& profile): 
     443    _parent(parent), 
     444    _contextID(parent->getContextID()), 
     445    _profile(profile), 
     446    _numOfGLBufferObjects(0), 
     447    _head(0), 
     448    _tail(0) 
     449{ 
     450    osg::notify(osg::NOTICE)<<"GLBufferObjectSet::GLBufferObjectSet _profile._size="<<_profile._size<<std::endl; 
     451} 
     452 
     453GLBufferObjectSet::~GLBufferObjectSet() 
     454{ 
     455#if 0 
     456    osg::notify(osg::NOTICE)<<"GLBufferObjectSet::~GLBufferObjectSet(), _numOfGLBufferObjects="<<_numOfGLBufferObjects<<std::endl; 
     457    osg::notify(osg::NOTICE)<<"     _orphanedGLBufferObjects = "<<_orphanedGLBufferObjects.size()<<std::endl; 
     458    osg::notify(osg::NOTICE)<<"     _head = "<<_head<<std::endl; 
     459    osg::notify(osg::NOTICE)<<"     _tail = "<<_tail<<std::endl; 
     460#endif 
     461} 
     462 
     463bool GLBufferObjectSet::checkConsistency() const 
     464{ 
     465    return true; 
     466 
     467    // osg::notify(osg::NOTICE)<<"GLBufferObjectSet::checkConsistency()"<<std::endl; 
     468    // check consistency of linked list. 
     469    unsigned int numInList = 0; 
     470    GLBufferObject* to = _head; 
     471    while(to!=0) 
     472    { 
     473        ++numInList; 
     474 
     475        if (to->_next) 
     476        { 
     477            if ((to->_next)->_previous != to) 
     478            { 
     479                osg::notify(osg::NOTICE)<<"Error (to->_next)->_previous != to "<<std::endl; 
     480                throw "Error (to->_next)->_previous != to "; 
     481            } 
     482        } 
     483        else 
     484        { 
     485            if (_tail != to) 
     486            { 
     487                osg::notify(osg::NOTICE)<<"Error _trail != to"<<std::endl; 
     488                throw "Error _trail != to"; 
     489            } 
     490        } 
     491 
     492        to = to->_next; 
     493    } 
     494 
     495    unsigned int totalNumber = numInList + _orphanedGLBufferObjects.size(); 
     496    if (totalNumber != _numOfGLBufferObjects) 
     497    { 
     498        osg::notify(osg::NOTICE)<<"Error numInList + _orphanedGLBufferObjects.size() != _numOfGLBufferObjects"<<std::endl; 
     499        osg::notify(osg::NOTICE)<<"    numInList = "<<numInList<<std::endl; 
     500        osg::notify(osg::NOTICE)<<"    _orphanedGLBufferObjects.size() = "<<_orphanedGLBufferObjects.size()<<std::endl; 
     501        osg::notify(osg::NOTICE)<<"    _pendingOrphanedGLBufferObjects.size() = "<<_pendingOrphanedGLBufferObjects.size()<<std::endl; 
     502        osg::notify(osg::NOTICE)<<"    _numOfGLBufferObjects = "<<_numOfGLBufferObjects<<std::endl; 
     503        throw "Error numInList + _orphanedGLBufferObjects.size() != _numOfGLBufferObjects"; 
     504    } 
     505 
     506    return true; 
     507} 
     508 
     509void GLBufferObjectSet::handlePendingOrphandedGLBufferObjects() 
     510{ 
     511//    osg::notify(osg::NOTICE)<<"handlePendingOrphandedGLBufferObjects()"<<_pendingOrphanedGLBufferObjects.size()<<std::endl; 
     512 
     513    if (_pendingOrphanedGLBufferObjects.empty()) return; 
     514 
     515    unsigned int numOrphaned = _pendingOrphanedGLBufferObjects.size(); 
     516 
     517    for(GLBufferObjectList::iterator itr = _pendingOrphanedGLBufferObjects.begin(); 
     518        itr != _pendingOrphanedGLBufferObjects.end(); 
     519        ++itr) 
     520    { 
     521        GLBufferObject* to = itr->get(); 
     522 
     523        _orphanedGLBufferObjects.push_back(to); 
     524 
     525        remove(to); 
     526 
     527#if 0 
     528        osg::notify(osg::NOTICE)<<"  HPOTO  after  _head = "<<_head<<std::endl; 
     529        osg::notify(osg::NOTICE)<<"  HPOTO  after _tail = "<<_tail<<std::endl; 
     530        osg::notify(osg::NOTICE)<<"  HPOTO  after to->_previous = "<<to->_previous<<std::endl; 
     531        osg::notify(osg::NOTICE)<<"  HPOTO  after to->_next = "<<to->_next<<std::endl; 
     532#endif 
     533 
     534    } 
     535 
     536 
     537    // update the GLBufferObjectManager's running total of active + orphaned GLBufferObjects 
     538    _parent->getNumberOrphanedGLBufferObjects() += numOrphaned; 
     539    _parent->getNumberActiveGLBufferObjects() -= numOrphaned; 
     540 
     541    _pendingOrphanedGLBufferObjects.clear(); 
     542 
     543    checkConsistency(); 
     544} 
     545 
     546void GLBufferObjectSet::flushAllDeletedGLBufferObjects() 
     547{ 
     548    for(GLBufferObjectList::iterator itr = _orphanedGLBufferObjects.begin(); 
     549        itr != _orphanedGLBufferObjects.end(); 
     550        ++itr) 
     551    { 
     552 
     553        (*itr)->deleteGLObject(); 
     554 
     555        osg::notify(osg::NOTICE)<<"Deleting textureobject id="<<(*itr)->getGLObjectID()<<std::endl; 
     556    } 
     557 
     558    unsigned int numDeleted = _orphanedGLBufferObjects.size(); 
     559    _numOfGLBufferObjects -= numDeleted; 
     560 
     561    // update the GLBufferObjectManager's running total of current pool size 
     562    _parent->getCurrGLBufferObjectPoolSize() -= numDeleted*_profile._size; 
     563    _parent->getNumberOrphanedGLBufferObjects() -= numDeleted; 
     564    _parent->getNumberDeleted() += numDeleted; 
     565 
     566    _orphanedGLBufferObjects.clear(); 
     567} 
     568 
     569void GLBufferObjectSet::discardAllDeletedGLBufferObjects() 
     570{ 
     571    unsigned int numDiscarded = _orphanedGLBufferObjects.size(); 
     572 
     573    _numOfGLBufferObjects -= numDiscarded; 
     574 
     575    // update the GLBufferObjectManager's running total of current pool size 
     576    _parent->setCurrGLBufferObjectPoolSize( _parent->getCurrGLBufferObjectPoolSize() - numDiscarded*_profile._size ); 
     577 
     578    // update the number of active and orphaned TextureOjects 
     579    _parent->getNumberOrphanedGLBufferObjects() -= 1; 
     580    _parent->getNumberActiveGLBufferObjects() += 1; 
     581    _parent->getNumberDeleted() += 1; 
     582 
     583 
     584    // just clear the list as there is nothing else we can do with them when discarding them 
     585    _orphanedGLBufferObjects.clear(); 
     586} 
     587 
     588void GLBufferObjectSet::flushDeletedGLBufferObjects(double currentTime, double& availableTime) 
     589{ 
     590    // if nothing to delete return 
     591    if (_orphanedGLBufferObjects.empty()) return; 
     592 
     593    // if no time available don't try to flush objects. 
     594    if (availableTime<=0.0) return; 
     595 
     596    // if we don't have too many orphaned texture objects then don't bother deleting them, as we can potentially reuse them later. 
     597    if (_parent->getNumberOrphanedGLBufferObjects()<=s_minimumNumberOfGLBufferObjectsToRetainInCache) return; 
     598 
     599    unsigned int numDeleted = 0; 
     600    unsigned int maxNumObjectsToDelete = _parent->getNumberOrphanedGLBufferObjects()-s_minimumNumberOfGLBufferObjectsToRetainInCache; 
     601    if (maxNumObjectsToDelete>4) maxNumObjectsToDelete = 4; 
     602 
     603    ElapsedTime timer; 
     604 
     605    GLBufferObjectList::iterator itr = _orphanedGLBufferObjects.begin(); 
     606    for(; 
     607        itr != _orphanedGLBufferObjects.end() && timer.elapsedTime()<availableTime && numDeleted<maxNumObjectsToDelete; 
     608        ++itr) 
     609    { 
     610 
     611        osg::notify(osg::NOTICE)<<"Deleting textureobject id="<<itr->get()<<std::endl; 
     612 
     613         (*itr)->deleteGLObject(); 
     614 
     615        ++numDeleted; 
     616    } 
     617 
     618    // osg::notify(osg::NOTICE)<<"Size before = "<<_orphanedGLBufferObjects.size(); 
     619    _orphanedGLBufferObjects.erase(_orphanedGLBufferObjects.begin(), itr); 
     620    //osg::notify(osg::NOTICE)<<", after = "<<_orphanedGLBufferObjects.size()<<" numDeleted = "<<numDeleted<<std::endl; 
     621 
     622    // update the number of TO's in this GLBufferObjectSet 
     623    _numOfGLBufferObjects -= numDeleted; 
     624 
     625    _parent->setCurrGLBufferObjectPoolSize( _parent->getCurrGLBufferObjectPoolSize() - numDeleted*_profile._size ); 
     626 
     627    // update the number of active and orphaned TextureOjects 
     628    _parent->getNumberOrphanedGLBufferObjects() -= numDeleted; 
     629    _parent->getNumberActiveGLBufferObjects() += numDeleted; 
     630    _parent->getNumberDeleted() += numDeleted; 
     631 
     632    availableTime -= timer.elapsedTime(); 
     633} 
     634 
     635bool GLBufferObjectSet::makeSpace(unsigned int& size) 
     636{ 
     637    if (!_orphanedGLBufferObjects.empty()) 
     638    { 
     639        unsigned int sizeAvailable = _orphanedGLBufferObjects.size() * _profile._size; 
     640        if (size>sizeAvailable) size -= sizeAvailable; 
     641        else size = 0; 
     642 
     643        flushAllDeletedGLBufferObjects(); 
     644    } 
     645 
     646    return size==0; 
     647} 
     648 
     649GLBufferObject* GLBufferObjectSet::takeFromOrphans(BufferObject* bufferObject) 
     650{ 
     651    // take front of orphaned list. 
     652    ref_ptr<GLBufferObject> glbo = _orphanedGLBufferObjects.front(); 
     653 
     654    // remove from orphan list. 
     655    _orphanedGLBufferObjects.pop_front(); 
     656 
     657    // assign to new texture 
     658    glbo->assign(bufferObject); 
     659    glbo->setProfile(_profile); 
     660 
     661    // update the number of active and orphaned TextureOjects 
     662    _parent->getNumberOrphanedGLBufferObjects() -= 1; 
     663    _parent->getNumberActiveGLBufferObjects() += 1; 
     664 
     665    // place at back of active list 
     666    addToBack(glbo.get()); 
     667 
     668    // osg::notify(osg::NOTICE)<<"Reusing orhpahned GLBufferObject, _numOfGLBufferObjects="<<_numOfGLBufferObjects<<std::endl; 
     669 
     670    return glbo.release(); 
     671} 
     672 
     673 
     674GLBufferObject* GLBufferObjectSet::takeOrGenerate(BufferObject* bufferObject) 
     675{ 
     676    // see if we can recyle GLBufferObject from the orphane list 
     677    if (!_pendingOrphanedGLBufferObjects.empty()) 
     678    { 
     679        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     680        handlePendingOrphandedGLBufferObjects(); 
     681        return takeFromOrphans(bufferObject); 
     682    } 
     683    else if (!_orphanedGLBufferObjects.empty()) 
     684    { 
     685        return takeFromOrphans(bufferObject); 
     686    } 
     687 
     688    unsigned int minFrameNumber = _parent->getFrameNumber(); 
     689 
     690    // see if we can reuse GLBufferObject by taking the least recently used active GLBufferObject 
     691    if ((_parent->getMaxGLBufferObjectPoolSize()!=0) && 
     692        (!_parent->hasSpace(_profile._size)) && 
     693        (_numOfGLBufferObjects>1) && 
     694        (_head != 0) && 
     695        (_head->_frameLastUsed<minFrameNumber)) 
     696    { 
     697 
     698        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     699 
     700        ref_ptr<GLBufferObject> glbo = _head; 
     701 
     702        ref_ptr<BufferObject> original_BufferObject = glbo->getBufferObject(); 
     703 
     704        if (original_BufferObject.valid()) 
     705        { 
     706            original_BufferObject->setGLBufferObject(_contextID,0); 
     707            // osg::notify(osg::NOTICE)<<"GLBufferObjectSet="<<this<<": Reusing an active GLBufferObject "<<glbo.get()<<" _numOfGLBufferObjects="<<_numOfGLBufferObjects<<" size="<<_profile._size<<std::endl; 
     708        } 
     709        else 
     710        { 
     711            // osg::notify(osg::NOTICE)<<"Reusing a recently orphaned active GLBufferObject "<<glbo.get()<<std::endl; 
     712        } 
     713 
     714        moveToBack(glbo.get()); 
     715 
     716        // assign to new texture 
     717        glbo->setBufferObject(bufferObject); 
     718        glbo->setProfile(_profile); 
     719 
     720        return glbo.release(); 
     721    } 
     722 
     723    // 
     724    GLBufferObject* glbo = new GLBufferObject(_contextID, const_cast<BufferObject*>(bufferObject)); 
     725    glbo->setProfile(_profile); 
     726    glbo->_set = this; 
     727    ++_numOfGLBufferObjects; 
     728 
     729    // update the current texture pool size 
     730    _parent->getCurrGLBufferObjectPoolSize() += _profile._size; 
     731    _parent->getNumberActiveGLBufferObjects() += 1; 
     732 
     733    addToBack(glbo); 
     734 
     735    // osg::notify(osg::NOTICE)<<"Created new GLBufferObject, _numOfGLBufferObjects "<<_numOfGLBufferObjects<<std::endl; 
     736 
     737    return glbo; 
     738} 
     739 
     740void GLBufferObjectSet::moveToBack(GLBufferObject* to) 
     741{ 
     742#if 0 
     743    osg::notify(osg::NOTICE)<<"GLBufferObjectSet::moveToBack("<<to<<")"<<std::endl; 
     744    osg::notify(osg::NOTICE)<<"    before _head = "<<_head<<std::endl; 
     745    osg::notify(osg::NOTICE)<<"    before _tail = "<<_tail<<std::endl; 
     746    osg::notify(osg::NOTICE)<<"    before to->_previous = "<<to->_previous<<std::endl; 
     747    osg::notify(osg::NOTICE)<<"    before to->_next = "<<to->_next<<std::endl; 
     748#endif 
     749 
     750    to->_frameLastUsed = _parent->getFrameNumber(); 
     751 
     752    // nothing to do if we are already tail 
     753    if (to==_tail) return; 
     754 
     755    // if no tail exists then assign 'to' as tail and head 
     756    if (_tail==0) 
     757    { 
     758        osg::notify(osg::NOTICE)<<"Error ***************** Should not get here !!!!!!!!!"<<std::endl; 
     759        _head = to; 
     760        _tail = to; 
     761        return; 
     762    } 
     763 
     764    if (to->_next==0) 
     765    { 
     766        osg::notify(osg::NOTICE)<<"Error ***************** Should not get here either !!!!!!!!!"<<std::endl; 
     767        return; 
     768    } 
     769 
     770 
     771    if (to->_previous) 
     772    { 
     773        (to->_previous)->_next = to->_next; 
     774    } 
     775    else 
     776    { 
     777        // 'to' is the head, so moving it to the back will mean we need a new head 
     778        if (to->_next) 
     779        { 
     780            _head = to->_next; 
     781        } 
     782    } 
     783 
     784    (to->_next)->_previous = to->_previous; 
     785 
     786    _tail->_next = to; 
     787 
     788    to->_previous = _tail; 
     789    to->_next = 0; 
     790 
     791    _tail = to; 
     792 
     793#if 0 
     794    osg::notify(osg::NOTICE)<<"  m2B   after  _head = "<<_head<<std::endl; 
     795    osg::notify(osg::NOTICE)<<"  m2B   after _tail = "<<_tail<<std::endl; 
     796    osg::notify(osg::NOTICE)<<"  m2B   after to->_previous = "<<to->_previous<<std::endl; 
     797    osg::notify(osg::NOTICE)<<"  m2B   after to->_next = "<<to->_next<<std::endl; 
     798#endif 
     799    checkConsistency(); 
     800} 
     801 
     802void GLBufferObjectSet::addToBack(GLBufferObject* to) 
     803{ 
     804#if 0 
     805    osg::notify(osg::NOTICE)<<"GLBufferObjectSet::addToBack("<<to<<")"<<std::endl; 
     806    osg::notify(osg::NOTICE)<<"    before _head = "<<_head<<std::endl; 
     807    osg::notify(osg::NOTICE)<<"    before _tail = "<<_tail<<std::endl; 
     808    osg::notify(osg::NOTICE)<<"    before to->_previous = "<<to->_previous<<std::endl; 
     809    osg::notify(osg::NOTICE)<<"    before to->_next = "<<to->_next<<std::endl; 
     810#endif 
     811 
     812    if (to->_previous !=0 || to->_next !=0) 
     813    { 
     814        moveToBack(to); 
     815    } 
     816    else 
     817    { 
     818        to->_frameLastUsed = _parent->getFrameNumber(); 
     819 
     820        if (_tail) _tail->_next = to; 
     821        to->_previous = _tail; 
     822 
     823        if (!_head) _head = to; 
     824        _tail = to; 
     825    } 
     826#if 0 
     827    osg::notify(osg::NOTICE)<<"  a2B  after  _head = "<<_head<<std::endl; 
     828    osg::notify(osg::NOTICE)<<"  a2B   after _tail = "<<_tail<<std::endl; 
     829    osg::notify(osg::NOTICE)<<"  a2B   after to->_previous = "<<to->_previous<<std::endl; 
     830    osg::notify(osg::NOTICE)<<"  a2B   after to->_next = "<<to->_next<<std::endl; 
     831#endif 
     832    checkConsistency(); 
     833} 
     834 
     835void GLBufferObjectSet::orphan(GLBufferObject* to) 
     836{ 
     837    // osg::notify(osg::NOTICE)<<"GLBufferObjectSet::orphan("<<to<<")"<<std::endl; 
     838 
     839    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 
     840 
     841    // disconnect from original texture 
     842    to->setBufferObject(0); 
     843 
     844    // add orphan 'to' to the pending list of orphans, these will then be 
     845    // handled in the handlePendingOrphandedGLBufferObjects() where the TO's 
     846    // will be removed from the active list, and then placed in the orhpanGLBufferObject 
     847    // list.  This double buffered approach to handling orphaned TO's is used 
     848    // to avoid having to mutex the process of appling active TO's. 
     849    _pendingOrphanedGLBufferObjects.push_back(to); 
     850 
     851#if 0 
     852    osg::notify(osg::NOTICE)<<"GLBufferObjectSet::orphan("<<to<<")  _pendingOrphanedGLBufferObjects.size()="<<_pendingOrphanedGLBufferObjects.size()<<std::endl; 
     853    osg::notify(osg::NOTICE)<<"                                    _orphanedGLBufferObjects.size()="<<_orphanedGLBufferObjects.size()<<std::endl; 
     854#endif 
     855} 
     856 
     857void GLBufferObjectSet::remove(GLBufferObject* to) 
     858{ 
     859    if (to->_previous!=0) 
     860    { 
     861        (to->_previous)->_next = to->_next; 
     862    } 
     863    else 
     864    { 
     865        // 'to' was head so assign _head to the next in list 
     866        _head = to->_next; 
     867    } 
     868 
     869    if (to->_next!=0) 
     870    { 
     871        (to->_next)->_previous = to->_previous; 
     872    } 
     873    else 
     874    { 
     875        // 'to' was tail so assing tail to the previous in list 
     876        _tail = to->_previous; 
     877    } 
     878 
     879    // reset the 'to' list pointers as it's no longer in the active list. 
     880    to->_next = 0; 
     881    to->_previous = 0; 
     882} 
     883 
     884 
     885GLBufferObjectManager::GLBufferObjectManager(unsigned int contextID): 
     886    _contextID(contextID), 
     887    _numActiveGLBufferObjects(0), 
     888    _numOrphanedGLBufferObjects(0), 
     889    _currGLBufferObjectPoolSize(0), 
     890    _maxGLBufferObjectPoolSize(0), 
     891    _frameNumber(0), 
     892    _numFrames(0), 
     893    _numDeleted(0), 
     894    _deleteTime(0.0), 
     895    _numGenerated(0), 
     896    _generateTime(0.0), 
     897    _numApplied(0), 
     898    _applyTime(0.0) 
     899{ 
     900} 
     901 
     902void GLBufferObjectManager::setMaxGLBufferObjectPoolSize(unsigned int size) 
     903{ 
     904    if (_maxGLBufferObjectPoolSize == size) return; 
     905 
     906    if (size<_currGLBufferObjectPoolSize) 
     907    { 
     908        osg::notify(osg::NOTICE)<<"Warning: new MaxGLBufferObjectPoolSize="<<size<<" is smaller than current GLBufferObjectPoolSize="<<_currGLBufferObjectPoolSize<<std::endl; 
     909    } 
     910 
     911    _maxGLBufferObjectPoolSize = size; 
     912} 
     913 
     914bool GLBufferObjectManager::makeSpace(unsigned int size) 
     915{ 
     916    for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin(); 
     917        itr != _glBufferObjectSetMap.end() && size>0; 
     918        ++itr) 
     919    { 
     920        if ((*itr).second->makeSpace(size)) return true; 
     921    } 
     922 
     923    return size==0; 
     924} 
     925 
     926 
     927GLBufferObject* GLBufferObjectManager::generateGLBufferObject(const BufferObject* bufferObject) 
     928{ 
     929    ElapsedTime elapsedTime(&(getGenerateTime())); 
     930    ++getNumberGenerated(); 
     931 
     932    BufferObjectProfile profile(bufferObject->getTarget(), bufferObject->getUsage(), bufferObject->computeRequiredBufferSize()); 
     933 
     934    // osg::notify(osg::NOTICE)<<"GLBufferObjectManager::generateGLBufferObject size="<<bufferObject->computeRequiredBufferSize()<<std::endl; 
     935 
     936    GLBufferObjectSet* glbos = getGLBufferObjectSet(profile); 
     937    return glbos->takeOrGenerate(const_cast<BufferObject*>(bufferObject)); 
     938} 
     939 
     940GLBufferObjectSet* GLBufferObjectManager::getGLBufferObjectSet(const BufferObjectProfile& profile) 
     941{ 
     942    osg::ref_ptr<GLBufferObjectSet>& tos = _glBufferObjectSetMap[profile]; 
     943    if (!tos) tos = new GLBufferObjectSet(this, profile); 
     944    return tos.get(); 
     945} 
     946 
     947void GLBufferObjectManager::handlePendingOrphandedGLBufferObjects() 
     948{ 
     949    for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin(); 
     950        itr != _glBufferObjectSetMap.end(); 
     951        ++itr) 
     952    { 
     953        (*itr).second->handlePendingOrphandedGLBufferObjects(); 
     954    } 
     955} 
     956 
     957void GLBufferObjectManager::flushAllDeletedGLBufferObjects() 
     958{ 
     959    ElapsedTime elapsedTime(&(getDeleteTime())); 
     960 
     961    for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin(); 
     962        itr != _glBufferObjectSetMap.end(); 
     963        ++itr) 
     964    { 
     965        (*itr).second->flushAllDeletedGLBufferObjects(); 
     966    } 
     967} 
     968 
     969void GLBufferObjectManager::discardAllDeletedGLBufferObjects() 
     970{ 
     971    for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin(); 
     972        itr != _glBufferObjectSetMap.end(); 
     973        ++itr) 
     974    { 
     975        (*itr).second->discardAllDeletedGLBufferObjects(); 
     976    } 
     977} 
     978 
     979void GLBufferObjectManager::flushDeletedGLBufferObjects(double currentTime, double& availableTime) 
     980{ 
     981    ElapsedTime elapsedTime(&(getDeleteTime())); 
     982 
     983    for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin(); 
     984        (itr != _glBufferObjectSetMap.end()) && (availableTime > 0.0); 
     985        ++itr) 
     986    { 
     987        (*itr).second->flushDeletedGLBufferObjects(currentTime, availableTime); 
     988    } 
     989} 
     990 
     991void GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to) 
     992{ 
     993    if (to->_set) to->_set->orphan(to); 
     994    else osg::notify(osg::NOTICE)<<"GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to) Not implemented yet"<<std::endl; 
     995} 
     996 
     997 
     998void GLBufferObjectManager::newFrame(osg::FrameStamp* fs) 
     999{ 
     1000    if (fs) _frameNumber = fs->getFrameNumber(); 
     1001    else ++_frameNumber; 
     1002 
     1003    ++_numFrames; 
     1004} 
     1005 
     1006void GLBufferObjectManager::reportStats() 
     1007{ 
     1008    double numFrames(_numFrames==0 ? 1.0 : _numFrames); 
     1009    osg::notify(osg::NOTICE)<<"GLBufferObjectMananger::reportStats()"<<std::endl; 
     1010    osg::notify(osg::NOTICE)<<"   total _numOfGLBufferObjects="<<_numActiveGLBufferObjects<<", _numOrphanedGLBufferObjects="<<_numOrphanedGLBufferObjects<<" _currGLBufferObjectPoolSize="<<_currGLBufferObjectPoolSize<<std::endl; 
     1011    osg::notify(osg::NOTICE)<<"   total _numGenerated="<<_numGenerated<<", _generateTime="<<_generateTime<<", averagePerFrame="<<_generateTime/numFrames*1000.0<<"ms"<<std::endl; 
     1012    osg::notify(osg::NOTICE)<<"   total _numDeleted="<<_numDeleted<<", _deleteTime="<<_deleteTime<<", averagePerFrame="<<_deleteTime/numFrames*1000.0<<"ms"<<std::endl; 
     1013    osg::notify(osg::NOTICE)<<"   total _numApplied="<<_numApplied<<", _applyTime="<<_applyTime<<", averagePerFrame="<<_applyTime/numFrames*1000.0<<"ms"<<std::endl; 
     1014} 
     1015 
     1016void GLBufferObjectManager::resetStats() 
     1017{ 
     1018    _numFrames = 0; 
     1019    _numDeleted = 0; 
     1020    _deleteTime = 0; 
     1021 
     1022    _numGenerated = 0; 
     1023    _generateTime = 0; 
     1024 
     1025    _numApplied = 0; 
     1026    _applyTime = 0; 
     1027} 
     1028 
     1029 
     1030 
     1031osg::ref_ptr<GLBufferObjectManager>& GLBufferObjectManager::getGLBufferObjectManager(unsigned int contextID) 
     1032{ 
     1033    typedef osg::buffered_object< ref_ptr<GLBufferObjectManager> > GLBufferObjectManagerBuffer; 
     1034    static GLBufferObjectManagerBuffer s_GLBufferObjectManager; 
     1035    if (!s_GLBufferObjectManager[contextID]) s_GLBufferObjectManager[contextID] = new GLBufferObjectManager(contextID); 
     1036    return s_GLBufferObjectManager[contextID]; 
     1037} 
     1038 
     1039GLBufferObject* GLBufferObject::createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject) 
     1040{ 
     1041    return GLBufferObjectManager::getGLBufferObjectManager(contextID)->generateGLBufferObject(bufferObject); 
     1042} 
     1043 
     1044void GLBufferObject::flushAllDeletedBufferObjects(unsigned int contextID) 
     1045{ 
     1046    GLBufferObjectManager::getGLBufferObjectManager(contextID)->flushAllDeletedGLBufferObjects(); 
     1047} 
     1048 
     1049void GLBufferObject::discardAllDeletedBufferObjects(unsigned int contextID) 
     1050{ 
     1051    GLBufferObjectManager::getGLBufferObjectManager(contextID)->discardAllDeletedGLBufferObjects(); 
     1052} 
     1053 
     1054void GLBufferObject::flushDeletedBufferObjects(unsigned int contextID,double currentTime, double& availbleTime) 
     1055{ 
     1056    GLBufferObjectManager::getGLBufferObjectManager(contextID)->flushDeletedGLBufferObjects(currentTime, availbleTime); 
     1057} 
     1058 
     1059void GLBufferObject::releaseGLBufferObject(unsigned int contextID, GLBufferObject* to) 
     1060{ 
     1061    GLBufferObjectManager::getGLBufferObjectManager(contextID)->releaseGLBufferObject(to); 
     1062} 
     1063 
     1064 
     1065 
     1066////////////////////////////////////////////////////////////////////////////////////////////////////// 
     1067// 
    4261068// BufferObject 
    4271069// 
    428 BufferObject::BufferObject(): 
    429     _target(0), 
    430     _usage(0) 
     1070BufferObject::BufferObject() 
    4311071{ 
    4321072} 
     
    4421082} 
    4431083 
     1084 
    4441085void BufferObject::setBufferData(unsigned int index, BufferData* bd) 
    4451086{ 
     
    4651106    if (state) 
    4661107    { 
    467         _glBufferObjects[state->getContextID()] = 0; 
     1108        unsigned int contextID = state->getContextID(); 
     1109        if (_glBufferObjects[contextID].valid()) 
     1110        { 
     1111            GLBufferObject::releaseGLBufferObject(contextID, _glBufferObjects[contextID].get()); 
     1112            _glBufferObjects[contextID] = 0; 
     1113        } 
    4681114    } 
    4691115    else 
    4701116    { 
    471         _glBufferObjects.clear(); 
     1117        for(unsigned int i=0; i<_glBufferObjects.size();++i) 
     1118        { 
     1119            if (_glBufferObjects[i].valid()) 
     1120            { 
     1121                GLBufferObject::releaseGLBufferObject(i, _glBufferObjects[i].get()); 
     1122                _glBufferObjects[i] = 0; 
     1123            } 
     1124        } 
    4721125    } 
    4731126} 
     
    5291182} 
    5301183 
     1184unsigned int BufferObject::computeRequiredBufferSize() const 
     1185{ 
     1186    unsigned int newTotalSize = 0; 
     1187    for(BufferDataList::const_iterator itr = _bufferDataList.begin(); 
     1188        itr != _bufferDataList.end(); 
     1189        ++itr) 
     1190    { 
     1191        BufferData* bd = *itr; 
     1192        newTotalSize += bd->getTotalDataSize(); 
     1193    } 
     1194    return newTotalSize; 
     1195} 
     1196 
    5311197////////////////////////////////////////////////////////////////////////////////////////////////////// 
    5321198// 
     
    5571223VertexBufferObject::VertexBufferObject() 
    5581224{ 
    559     _target = GL_ARRAY_BUFFER_ARB; 
    560     _usage = GL_STATIC_DRAW_ARB; 
     1225    setTarget(GL_ARRAY_BUFFER_ARB); 
     1226    setUsage(GL_STATIC_DRAW_ARB); 
    5611227//    _usage = GL_DYNAMIC_DRAW_ARB; 
    5621228//    _usage = GL_STREAM_DRAW_ARB; 
     
    5961262    return dynamic_cast<const osg::Array*>(getBufferData(i)); 
    5971263} 
    598 #if 0 
    599 void VertexBufferObject::compileBuffer(State& state) const 
    600 { 
    601     unsigned int contextID = state.getContextID(); 
    602  
    603     _compiledList[contextID] = 1; 
    604  
    605     Extensions* extensions = getExtensions(contextID,true); 
    606  
    607     // osg::notify(osg::NOTICE)<<"VertexBufferObject::compileBuffer frameNumber="<<state.getFrameStamp()->getFrameNumber()<<std::endl; 
    608  
    609     unsigned int totalSizeRequired = 0; 
    610     unsigned int numNewArrays = 0; 
    611     for(BufferEntryArrayPairs::const_iterator itr = _bufferEntryArrayPairs.begin(); 
    612         itr != _bufferEntryArrayPairs.end(); 
    613         ++itr) 
    614     { 
    615         const BufferEntryArrayPair& bep = *itr; 
    616         if (bep.second) 
    617         { 
    618             totalSizeRequired += bep.second->getTotalDataSize(); 
    619             if (bep.first.dataSize == 0) ++numNewArrays; 
    620         } 
    621     } 
    622  
    623     bool copyAll = false; 
    624     GLuint& vbo = buffer(contextID); 
    625     if (vbo==0) 
    626     { 
    627         // building for the first time. 
    628  
    629         _totalSize = totalSizeRequired; 
    630  
    631         // don't generate buffer if size is zero. 
    632         if (_totalSize==0) return; 
    633  
    634         extensions->glGenBuffers(1, &vbo); 
    635         extensions->glBindBuffer(_target, vbo); 
    636         extensions->glBufferData(_target, _totalSize, NULL, _usage); 
    637  
    638         copyAll = true; 
    639     } 
    640     else 
    641     { 
    642         extensions->glBindBuffer(_target, vbo); 
    643  
    644         if (_totalSize != totalSizeRequired) 
    645         { 
    646             // resize vbo. 
    647             _totalSize = totalSizeRequired; 
    648             extensions->glBufferData(_target, _totalSize, NULL, _usage); 
    649  
    650             copyAll = true; 
    651         } 
    652     } 
    653  
    654     typedef std::map<unsigned int,std::vector<unsigned int> > SizePosMap_t; 
    655     SizePosMap_t freeList; 
    656     if (copyAll == false && numNewArrays > 0) 
    657     { 
    658         std::map<unsigned int,unsigned int> usedList; 
    659         for(BufferEntryArrayPairs::const_iterator itr = _bufferEntryArrayPairs.begin(); 
    660             itr != _bufferEntryArrayPairs.end(); 
    661             ++itr) 
    662         { 
    663             const BufferEntryArrayPair& bep = *itr; 
    664             if (bep.second==NULL) continue; 
    665             if (bep.first.dataSize == 0) continue; 
    666             usedList[bep.first.offset] = bep.first.dataSize; 
    667         } 
    668         unsigned int numFreeBlocks = 0; 
    669         unsigned int pos=0; 
    670  
    671         for (std::map<unsigned int,unsigned int>::const_iterator it=usedList.begin(); it!=usedList.end(); ++it) 
    672         { 
    673             unsigned int start = it->first; 
    674             unsigned int length = it->second; 
    675             if (pos < start) 
    676             { 
    677                 freeList[start-pos].push_back(pos); 
    678                 ++numFreeBlocks; 
    679             } 
    680             pos = start+length; 
    681         } 
    682         if (pos < totalSizeRequired) 
    683         { 
    684             freeList[totalSizeRequired-pos].push_back(pos); 
    685             ++numFreeBlocks; 
    686         } 
    687         if (numNewArrays < numFreeBlocks) 
    688         { 
    689             copyAll = true;     // too fragmented, fallback to copyAll 
    690             freeList.clear(); 
    691         } 
    692     } 
    693  
    694  
    695 //    osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    696  
    697  
    698     void* vboMemory = 0; 
    699  
    700 #if 0 
    701     vboMemory = extensions->glMapBuffer(_target, GL_WRITE_ONLY_ARB); 
    702 #endif 
    703  
    704     unsigned int offset = 0; 
    705     for(BufferEntryArrayPairs::const_iterator itr = _bufferEntryArrayPairs.begin(); 
    706         itr != _bufferEntryArrayPairs.end(); 
    707         ++itr) 
    708     { 
    709         const BufferEntryArrayPair& bep = *itr; 
    710         const Array* de = bep.second; 
    711         if (de) 
    712         { 
    713             const unsigned int arraySize = de->getTotalDataSize(); 
    714             if (copyAll || 
    715                 bep.first.modifiedCount[contextID] != bep.second->getModifiedCount() || 
    716                 bep.first.dataSize != arraySize) 
    717             { 
    718                 // copy data across 
    719                 unsigned int newOffset = bep.first.offset;               
    720                 if (copyAll) 
    721                 { 
    722                     newOffset = offset; 
    723                     offset += arraySize; 
    724                 } 
    725                 else if (bep.first.dataSize == 0) 
    726                 { 
    727                     SizePosMap_t::iterator findIt = freeList.lower_bound(arraySize); 
    728                     if (findIt==freeList.end()) 
    729                     { 
    730                         osg::notify(osg::FATAL)<<"No suitable Memory in VBO found!"<<std::endl; 
    731                         continue; 
    732                     } 
    733                     const unsigned int oldOffset = findIt->second.back(); 
    734                     newOffset = oldOffset; 
    735                     if (findIt->first > arraySize) // using larger block 
    736                     { 
    737                         freeList[findIt->first-arraySize].push_back(oldOffset+arraySize); 
    738                     } 
    739                     findIt->second.pop_back(); 
    740                     if (findIt->second.empty()) 
    741                     { 
    742                         freeList.erase(findIt); 
    743                     } 
    744                 } 
    745                 bep.first.dataSize = arraySize; 
    746                 bep.first.modifiedCount[contextID] = de->getModifiedCount(); 
    747                 bep.first.offset = newOffset; 
    748                 de->setVertexBufferObjectOffset((GLvoid*)newOffset); 
    749  
    750                 // osg::notify(osg::NOTICE)<<"   copying vertex buffer data "<<bep.first.dataSize<<" bytes"<<std::endl; 
    751  
    752                 if (vboMemory) 
    753                     memcpy((char*)vboMemory + bep.first.offset, de->getDataPointer(), bep.first.dataSize); 
    754                 else 
    755                     extensions->glBufferSubData(_target, bep.first.offset, bep.first.dataSize, de->getDataPointer()); 
    756  
    757             } 
    758         } 
    759     } 
    760  
    761  
    762     // Unmap the texture image buffer 
    763     if (vboMemory) extensions->glUnmapBuffer(_target); 
    764  
    765 //    osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl; 
    766 //    osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    767 } 
    768 #endif 
    7691264 
    7701265////////////////////////////////////////////////////////////////////////////////// 
     
    7741269ElementBufferObject::ElementBufferObject() 
    7751270{ 
    776     _target = GL_ELEMENT_ARRAY_BUFFER_ARB; 
    777     _usage = GL_STATIC_DRAW_ARB; 
     1271    setTarget(GL_ELEMENT_ARRAY_BUFFER_ARB); 
     1272    setUsage(GL_STATIC_DRAW_ARB); 
    7781273} 
    7791274 
     
    8131308 
    8141309 
    815 #if 0 
    816 void ElementBufferObject::compileBuffer(State& state) const 
    817 { 
    818     unsigned int contextID = state.getContextID(); 
    819  
    820     _compiledList[contextID] = 1; 
    821  
    822     // osg::notify(osg::NOTICE)<<"ElementBufferObject::compile"<<std::endl; 
    823  
    824     Extensions* extensions = getExtensions(contextID,true); 
    825  
    826     unsigned int totalSizeRequired = 0; 
    827 //    unsigned int numModified = 0; 
    828 //    unsigned int numNotModified = 0; 
    829     for(BufferEntryDrawElementsPairs::const_iterator itr = _bufferEntryDrawElementsPairs.begin(); 
    830         itr != _bufferEntryDrawElementsPairs.end(); 
    831         ++itr) 
    832     { 
    833         const BufferEntryDrawElementsPair& bep = *itr; 
    834         if (bep.second) 
    835         { 
    836             totalSizeRequired += bep.second->getTotalDataSize(); 
    837         } 
    838     } 
    839  
    840     bool copyAll = false; 
    841     GLuint& ebo = buffer(contextID); 
    842     if (ebo==0) 
    843     { 
    844         // building for the first time. 
    845  
    846         _totalSize = totalSizeRequired; 
    847  
    848         // don't generate buffer if size is zero. 
    849         if (_totalSize==0) return; 
    850  
    851         extensions->glGenBuffers(1, &ebo); 
    852         extensions->glBindBuffer(_target, ebo); 
    853         extensions->glBufferData(_target, _totalSize, NULL, _usage); 
    854  
    855         copyAll = true; 
    856     } 
    857     else 
    858     { 
    859         extensions->glBindBuffer(_target, ebo); 
    860  
    861         if (_totalSize != totalSizeRequired) 
    862         { 
    863             // resize EBO. 
    864             _totalSize = totalSizeRequired; 
    865             extensions->glBufferData(_target, _totalSize, NULL, _usage); 
    866  
    867             copyAll = true; 
    868         } 
    869     } 
    870  
    871 //    osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    872  
    873  
    874     void* eboMemory = 0; 
    875  
    876 #if 0 
    877     eboMemory = extensions->glMapBuffer(_target, GL_WRITE_ONLY_ARB); 
    878 #endif 
    879  
    880     size_t offset = 0; 
    881     for(BufferEntryDrawElementsPairs::const_iterator itr = _bufferEntryDrawElementsPairs.begin(); 
    882         itr != _bufferEntryDrawElementsPairs.end(); 
    883         ++itr) 
    884     { 
    885         const BufferEntryDrawElementsPair& bep = *itr; 
    886         const DrawElements* de = bep.second; 
    887         if (de) 
    888         { 
    889             if (copyAll || 
    890                 bep.first.modifiedCount[contextID] != bep.second->getModifiedCount() || 
    891                 bep.first.dataSize != bep.second->getTotalDataSize()) 
    892             { 
    893                 // copy data across 
    894                 bep.first.dataSize = bep.second->getTotalDataSize(); 
    895                 bep.first.modifiedCount[contextID] = de->getModifiedCount(); 
    896                 if (copyAll) 
    897                 { 
    898                     bep.first.offset = offset; 
    899                     de->setElementBufferObjectOffset((GLvoid*)offset); 
    900                     offset += bep.first.dataSize; 
    901                 } 
    902  
    903                 if (eboMemory) 
    904                     memcpy((char*)eboMemory + bep.first.offset, de->getDataPointer(), bep.first.dataSize); 
    905                 else 
    906                     extensions->glBufferSubData(_target, bep.first.offset, bep.first.dataSize, de->getDataPointer()); 
    907  
    908             } 
    909         } 
    910     } 
    911  
    912  
    913     // Unmap the texture image buffer 
    914     if (eboMemory) extensions->glUnmapBuffer(_target); 
    915  
    916 //    osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl; 
    917 //    osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    918 } 
    919 #endif 
    920  
    9211310////////////////////////////////////////////////////////////////////////////////// 
    9221311// 
     
    9261315    BufferObject() 
    9271316{ 
    928     _target = GL_PIXEL_UNPACK_BUFFER_ARB; 
    929     _usage = GL_STREAM_DRAW_ARB; 
     1317    setTarget(GL_PIXEL_UNPACK_BUFFER_ARB); 
     1318    setTarget(GL_STREAM_DRAW_ARB); 
    9301319 
    9311320    osg::notify(osg::NOTICE)<<"Constructing PixelBufferObject for image="<<image<<std::endl; 
     
    9581347} 
    9591348 
    960 #if 0 
    961 void PixelBufferObject::compileBuffer(State& state) const 
    962 { 
    963     unsigned int contextID = state.getContextID(); 
    964  
    965     _compiledList[contextID] = 1; 
    966  
    967     osg::Image* image = _bufferEntryImagePair.second; 
    968  
    969     _bufferEntryImagePair.first.modifiedCount[contextID] = image->getModifiedCount(); 
    970     if (!image->valid()) return; 
    971  
    972     Extensions* extensions = getExtensions(contextID,true); 
    973  
    974     GLuint& pbo = buffer(contextID); 
    975     if (pbo==0) 
    976     { 
    977         // building for the first time. 
    978  
    979         _totalSize = image->getTotalSizeInBytes(); 
    980  
    981         // don't generate buffer if size is zero. 
    982         if (_totalSize==0) return; 
    983  
    984         extensions->glGenBuffers(1, &pbo); 
    985         extensions->glBindBuffer(_target, pbo); 
    986         extensions->glBufferData(_target, _totalSize, NULL, _usage); 
    987  
    988     } 
    989     else 
    990     { 
    991         extensions->glBindBuffer(_target, pbo); 
    992  
    993         if (_totalSize != image->getTotalSizeInBytes()) 
    994         { 
    995             // resize PBO. 
    996             _totalSize = image->getTotalSizeInBytes(); 
    997             extensions->glBufferData(_target, _totalSize, NULL, _usage); 
    998         } 
    999     } 
    1000  
    1001 //    osg::Timer_t start_tick = osg::Timer::instance()->tick(); 
    1002  
    1003     void* pboMemory = extensions->glMapBuffer(_target, 
    1004                  GL_WRITE_ONLY_ARB); 
    1005  
    1006     // copy data across 
    1007     memcpy(pboMemory, image->data(), _totalSize); 
    1008  
    1009     // Unmap the texture image buffer 
    1010     extensions->glUnmapBuffer(_target); 
    1011  
    1012     _bufferEntryImagePair.first.modifiedCount[contextID] = image->getModifiedCount(); 
    1013  
    1014 //    osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl; 
    1015 //    osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    1016 } 
    1017 #endif 
    10181349 
    10191350////////////////////////////////////////////////////////////////////////////////// 
     
    10241355PixelDataBufferObject::PixelDataBufferObject() 
    10251356{ 
    1026     _target = GL_ARRAY_BUFFER_ARB; 
    1027     _usage = GL_DYNAMIC_DRAW_ARB; 
     1357    setTarget(GL_ARRAY_BUFFER_ARB); 
     1358    setTarget(GL_DYNAMIC_DRAW_ARB); 
    10281359} 
    10291360 
     
    10431374{ 
    10441375    unsigned int contextID = state.getContextID();     
    1045     if ( _dataSize == 0) return; 
     1376    if ( _profile._size == 0) return; 
    10461377 
    10471378    GLBufferObject* bo = getOrCreateGLBufferObject(contextID); 
    10481379    if (!bo || !bo->isDirty()) return; 
    10491380 
    1050     bo->_extensions->glBindBuffer(_target, bo->getGLObjectID()); 
    1051     bo->_extensions->glBufferData(_target, _dataSize, NULL, _usage); 
    1052     bo->_extensions->glBindBuffer(_target, 0); 
     1381    bo->_extensions->glBindBuffer(_profile._target, bo->getGLObjectID()); 
     1382    bo->_extensions->glBufferData(_profile._target, _profile._size, NULL, _profile._usage); 
     1383    bo->_extensions->glBindBuffer(_profile._target, 0); 
    10531384} 
    10541385 
     
    10971428            break; 
    10981429        default: 
    1099             extensions->glBindBuffer(_target,0); 
     1430            extensions->glBindBuffer(_profile._target,0); 
    11001431            break; 
    11011432    } 
     
    11111442    _mode.resize(maxSize); 
    11121443} 
    1113  
    1114  
    1115 #endif