Show
Ignore:
Timestamp:
10/01/09 22:19:42 (5 years ago)
Author:
robert
Message:

Introduced new BufferObject? design + implementation in preperation of implementing a pool system for buffer objects

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osg/BufferObject.cpp

    r9362 r10600  
    3838static DeletedBufferObjectCache s_deletedBufferObjectCache; 
    3939 
    40 void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj) 
     40////////////////////////////////////////////////////////////////////////////////////////////////////// 
     41// 
     42// GLBufferObject 
     43// 
     44GLBufferObject::GLBufferObject(unsigned int contextID, BufferObject* bufferObject): 
     45    _contextID(contextID), 
     46    _glObjectID(0), 
     47    _target(0), 
     48    _usage(0), 
     49    _dirty(true), 
     50    _totalSize(0), 
     51    _bufferObject(0), 
     52    _extensions(0) 
     53{ 
     54    assign(bufferObject); 
     55    _extensions = GLBufferObject::getExtensions(contextID, true); 
     56    _extensions->glGenBuffers(1, &_glObjectID); 
     57} 
     58 
     59GLBufferObject::~GLBufferObject() 
     60{ 
     61    if (_glObjectID!=0) GLBufferObject::deleteBufferObject(_contextID, _glObjectID); 
     62 
     63} 
     64 
     65void GLBufferObject::assign(BufferObject* bufferObject) 
     66{ 
     67    _bufferObject = bufferObject; 
     68 
     69    if (_bufferObject) 
     70    { 
     71        _target = bufferObject->getTarget(); 
     72        _usage = bufferObject->getUsage(); 
     73 
     74        _totalSize = 0; 
     75 
     76        _dirty = true; 
     77 
     78        _bufferEntries.clear(); 
     79    } 
     80    else 
     81    { 
     82        _target = 0; 
     83        _usage = 0; 
     84 
     85        _totalSize = 0; 
     86 
     87        // clear all previous entries; 
     88        _bufferEntries.clear(); 
     89    } 
     90} 
     91 
     92void GLBufferObject::clear() 
     93{ 
     94    _bufferEntries.clear(); 
     95    _dirty = true; 
     96} 
     97 
     98void GLBufferObject::compileBuffer() 
     99{ 
     100    _dirty = false; 
     101 
     102    _bufferEntries.reserve(_bufferObject->getNumBufferData()); 
     103 
     104    _totalSize = 0; 
     105 
     106    bool compileAll = false; 
     107    bool offsetChanged = false; 
     108 
     109    GLsizeiptrARB newTotalSize = 0; 
     110    unsigned int i=0; 
     111    for(; i<_bufferObject->getNumBufferData(); ++i) 
     112    { 
     113        BufferData* bd = _bufferObject->getBufferData(i); 
     114        if (i<_bufferEntries.size()) 
     115        { 
     116            BufferEntry& entry = _bufferEntries[i]; 
     117            if (offsetChanged || 
     118                entry.dataSource != bd || 
     119                entry.dataSize != bd->getTotalDataSize()) 
     120            { 
     121                GLsizeiptrARB previousEndOfBufferDataMarker = GLsizeiptrARB(entry.offset) + entry.dataSize; 
     122 
     123                // osg::notify(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) updating BufferEntry"<<std::endl; 
     124 
     125 
     126                entry.offset = newTotalSize; 
     127                entry.modifiedCount = 0xffffff; 
     128                entry.dataSize = bd->getTotalDataSize(); 
     129                entry.dataSource = bd; 
     130 
     131                newTotalSize += entry.dataSize; 
     132                if (previousEndOfBufferDataMarker==newTotalSize) 
     133                { 
     134                    offsetChanged = true; 
     135                } 
     136            } 
     137        } 
     138        else 
     139        { 
     140            BufferEntry entry; 
     141            entry.offset = newTotalSize; 
     142            entry.modifiedCount = 0xffffff; 
     143            entry.dataSize = bd->getTotalDataSize(); 
     144            entry.dataSource = bd; 
     145#if 0 
     146            osg::notify(osg::NOTICE)<<"entry"<<std::endl; 
     147            osg::notify(osg::NOTICE)<<"   offset "<<entry.offset<<std::endl; 
     148            osg::notify(osg::NOTICE)<<"   dataSize "<<entry.dataSize<<std::endl; 
     149            osg::notify(osg::NOTICE)<<"   dataSource "<<entry.dataSource<<std::endl; 
     150            osg::notify(osg::NOTICE)<<"   modifiedCount "<<entry.modifiedCount<<std::endl; 
     151#endif 
     152            newTotalSize += entry.dataSize; 
     153 
     154            _bufferEntries.push_back(entry); 
     155        } 
     156    } 
     157 
     158    if (i<_bufferEntries.size()) 
     159    { 
     160        // triming end of bufferEntries as the source data is has less entries than the originally held. 
     161        _bufferEntries.erase(_bufferEntries.begin()+i, _bufferEntries.end()); 
     162    } 
     163 
     164    _extensions->glBindBuffer(_target, _glObjectID); 
     165 
     166    if (newTotalSize != _totalSize) 
     167    { 
     168        _totalSize = newTotalSize; 
     169        _extensions->glBufferData(_target, _totalSize, NULL, _usage); 
     170    } 
     171 
     172    char* vboMemory = 0; 
     173 
     174#if 0 
     175    vboMemory = extensions->glMapBuffer(_target, GL_WRITE_ONLY_ARB); 
     176#endif 
     177 
     178    for(BufferEntries::iterator itr = _bufferEntries.begin(); 
     179        itr != _bufferEntries.end(); 
     180        ++itr) 
     181    { 
     182        BufferEntry& entry = *itr; 
     183        if (compileAll || entry.modifiedCount != entry.dataSource->getModifiedCount()) 
     184        { 
     185            // osg::notify(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) downloading BufferEntry "<<&entry<<std::endl; 
     186            entry.modifiedCount = entry.dataSource->getModifiedCount(); 
     187 
     188            if (vboMemory) 
     189                memcpy(vboMemory + (GLsizeiptrARB)entry.offset, entry.dataSource->getDataPointer(), entry.dataSize); 
     190            else 
     191                _extensions->glBufferSubData(_target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer()); 
     192 
     193        } 
     194    } 
     195 
     196    // Unmap the texture image buffer 
     197    if (vboMemory) _extensions->glUnmapBuffer(_target); 
     198} 
     199 
     200GLBufferObject* GLBufferObject::createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject) 
     201{ 
     202    return new GLBufferObject(contextID, const_cast<BufferObject*>(bufferObject)); 
     203} 
     204 
     205void GLBufferObject::deleteGLObject() 
     206{ 
     207    if (_glObjectID!=0) 
     208    { 
     209        _extensions->glDeleteBuffers(1, &_glObjectID); 
     210        _glObjectID = 0; 
     211 
     212        _totalSize = 0; 
     213        _bufferEntries.clear(); 
     214    } 
     215} 
     216 
     217 
     218void GLBufferObject::deleteBufferObject(unsigned int contextID,GLuint globj) 
    41219{ 
    42220    if (globj!=0) 
     
    49227} 
    50228 
    51 void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime) 
     229void GLBufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime) 
    52230{ 
    53231    // if no time available don't try to flush objects. 
     
    85263} 
    86264 
    87 void BufferObject::discardDeletedBufferObjects(unsigned int contextID) 
     265void GLBufferObject::discardDeletedBufferObjects(unsigned int contextID) 
    88266{ 
    89267    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache); 
     
    92270} 
    93271 
    94  
    95 BufferObject::BufferObject(): 
    96     _target(0), 
    97     _usage(0), 
    98     _totalSize(0) 
    99 { 
    100 } 
    101  
    102 BufferObject::BufferObject(const BufferObject& bo,const CopyOp& copyop): 
    103     Object(bo,copyop) 
    104 { 
    105 } 
    106  
    107 BufferObject::~BufferObject() 
    108 { 
    109     releaseGLObjects(0); 
    110 } 
    111  
    112 void BufferObject::resizeGLObjectBuffers(unsigned int maxSize) 
    113 { 
    114     _bufferObjectList.resize(maxSize); 
    115 } 
    116  
    117 void BufferObject::releaseGLObjects(State* state) const 
    118 { 
    119     if (state) 
    120     { 
    121         unsigned int contextID = state->getContextID(); 
    122         if (_bufferObjectList[contextID]) 
    123         { 
    124              deleteBufferObject(contextID,_bufferObjectList[contextID]); 
    125             _bufferObjectList[contextID] = 0; 
    126         } 
    127     } 
    128     else 
    129     { 
    130         for(unsigned int contextID=0;contextID<_bufferObjectList.size();++contextID) 
    131         { 
    132             if (_bufferObjectList[contextID]) 
    133             { 
    134                  deleteBufferObject(contextID,_bufferObjectList[contextID]); 
    135                 _bufferObjectList[contextID] = 0; 
    136             } 
    137         } 
    138     } 
    139 } 
    140  
    141272////////////////////////////////////////////////////////////////////////////// 
    142273// 
     
    144275// 
    145276 
    146 typedef buffered_value< ref_ptr<BufferObject::Extensions> > BufferedExtensions; 
     277typedef buffered_value< ref_ptr<GLBufferObject::Extensions> > BufferedExtensions; 
    147278static BufferedExtensions s_extensions; 
    148279 
    149 BufferObject::Extensions* BufferObject::getExtensions(unsigned int contextID,bool createIfNotInitalized) 
    150 { 
    151     if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new BufferObject::Extensions(contextID); 
     280GLBufferObject::Extensions* GLBufferObject::getExtensions(unsigned int contextID,bool createIfNotInitalized) 
     281{ 
     282    if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new GLBufferObject::Extensions(contextID); 
    152283    return s_extensions[contextID].get(); 
    153284} 
    154285 
    155 void BufferObject::setExtensions(unsigned int contextID,Extensions* extensions) 
     286void GLBufferObject::setExtensions(unsigned int contextID,Extensions* extensions) 
    156287{ 
    157288    s_extensions[contextID] = extensions; 
    158289} 
    159290 
    160 BufferObject::Extensions::Extensions(unsigned int contextID) 
     291GLBufferObject::Extensions::Extensions(unsigned int contextID) 
    161292{ 
    162293    setupGLExtensions(contextID); 
    163294} 
    164295 
    165 BufferObject::Extensions::Extensions(const Extensions& rhs): 
     296GLBufferObject::Extensions::Extensions(const Extensions& rhs): 
    166297    Referenced() 
    167298{ 
     
    180311 
    181312 
    182 void BufferObject::Extensions::lowestCommonDenominator(const Extensions& rhs) 
     313void GLBufferObject::Extensions::lowestCommonDenominator(const Extensions& rhs) 
    183314{ 
    184315    if (!rhs._glGenBuffers) _glGenBuffers = rhs._glGenBuffers; 
     
    195326} 
    196327 
    197 void BufferObject::Extensions::setupGLExtensions(unsigned int contextID) 
     328void GLBufferObject::Extensions::setupGLExtensions(unsigned int contextID) 
    198329{ 
    199330    setGLExtensionFuncPtr(_glGenBuffers, "glGenBuffers","glGenBuffersARB"); 
     
    211342} 
    212343 
    213 void BufferObject::Extensions::glGenBuffers(GLsizei n, GLuint *buffers) const 
     344void GLBufferObject::Extensions::glGenBuffers(GLsizei n, GLuint *buffers) const 
    214345{ 
    215346    if (_glGenBuffers) _glGenBuffers(n, buffers); 
     
    217348} 
    218349 
    219 void BufferObject::Extensions::glBindBuffer(GLenum target, GLuint buffer) const 
     350void GLBufferObject::Extensions::glBindBuffer(GLenum target, GLuint buffer) const 
    220351{ 
    221352    if (_glBindBuffer) _glBindBuffer(target, buffer); 
     
    223354} 
    224355 
    225 void BufferObject::Extensions::glBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const 
     356void GLBufferObject::Extensions::glBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const 
    226357{ 
    227358    if (_glBufferData) _glBufferData(target, size, data, usage); 
     
    229360} 
    230361 
    231 void BufferObject::Extensions::glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const 
     362void GLBufferObject::Extensions::glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const 
    232363{ 
    233364    if (_glBufferSubData) _glBufferSubData(target, offset, size, data); 
     
    235366} 
    236367 
    237 void BufferObject::Extensions::glDeleteBuffers(GLsizei n, const GLuint *buffers) const 
     368void GLBufferObject::Extensions::glDeleteBuffers(GLsizei n, const GLuint *buffers) const 
    238369{ 
    239370    if (_glDeleteBuffers) _glDeleteBuffers(n, buffers); 
     
    241372} 
    242373 
    243 GLboolean BufferObject::Extensions::glIsBuffer (GLuint buffer) const 
     374GLboolean GLBufferObject::Extensions::glIsBuffer (GLuint buffer) const 
    244375{ 
    245376    if (_glIsBuffer) return _glIsBuffer(buffer); 
     
    251382} 
    252383 
    253 void BufferObject::Extensions::glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const 
     384void GLBufferObject::Extensions::glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const 
    254385{ 
    255386    if (_glGetBufferSubData) _glGetBufferSubData(target,offset,size,data); 
     
    257388} 
    258389 
    259 GLvoid* BufferObject::Extensions::glMapBuffer (GLenum target, GLenum access) const 
     390GLvoid* GLBufferObject::Extensions::glMapBuffer (GLenum target, GLenum access) const 
    260391{ 
    261392    if (_glMapBuffer) return _glMapBuffer(target,access); 
     
    267398} 
    268399 
    269 GLboolean BufferObject::Extensions::glUnmapBuffer (GLenum target) const 
     400GLboolean GLBufferObject::Extensions::glUnmapBuffer (GLenum target) const 
    270401{ 
    271402    if (_glUnmapBuffer) return _glUnmapBuffer(target); 
     
    277408} 
    278409 
    279 void BufferObject::Extensions::glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const 
     410void GLBufferObject::Extensions::glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const 
    280411{ 
    281412    if (_glGetBufferParameteriv) _glGetBufferParameteriv(target,pname,params); 
     
    283414} 
    284415 
    285 void BufferObject::Extensions::glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const 
     416void GLBufferObject::Extensions::glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const 
    286417{ 
    287418    if (_glGetBufferPointerv) _glGetBufferPointerv(target,pname,params); 
    288419    else notify(WARN)<<"Error: glGetBufferPointerv not supported by OpenGL driver"<<std::endl; 
     420} 
     421 
     422#if 1 
     423 
     424////////////////////////////////////////////////////////////////////////////////////////////////////// 
     425// 
     426// BufferObject 
     427// 
     428BufferObject::BufferObject(): 
     429    _target(0), 
     430    _usage(0) 
     431{ 
     432} 
     433 
     434BufferObject::BufferObject(const BufferObject& bo,const CopyOp& copyop): 
     435    Object(bo,copyop) 
     436{ 
     437} 
     438 
     439BufferObject::~BufferObject() 
     440{ 
     441    releaseGLObjects(0); 
     442} 
     443 
     444void BufferObject::setBufferData(unsigned int index, BufferData* bd) 
     445{ 
     446    if (index>=_bufferDataList.size()) _bufferDataList.resize(index+1); 
     447    _bufferDataList[index] = bd; 
     448} 
     449 
     450void BufferObject::dirty() 
     451{ 
     452    for(unsigned int i=0; i<_glBufferObjects.size(); ++i) 
     453    { 
     454        if (_glBufferObjects[i].valid()) _glBufferObjects[i]->dirty(); 
     455    } 
     456} 
     457 
     458void BufferObject::resizeGLObjectBuffers(unsigned int maxSize) 
     459{ 
     460    _glBufferObjects.resize(maxSize); 
     461} 
     462 
     463void BufferObject::releaseGLObjects(State* state) const 
     464{ 
     465    if (state) 
     466    { 
     467        _glBufferObjects[state->getContextID()] = 0; 
     468    } 
     469    else 
     470    { 
     471        _glBufferObjects.clear(); 
     472    } 
     473} 
     474 
     475unsigned int BufferObject::addBufferData(BufferData* bd) 
     476{ 
     477    if (!bd) return 0; 
     478 
     479    // check to see if bd exists in BufferObject already, is so return without doing anything 
     480    for(BufferDataList::iterator itr = _bufferDataList.begin(); 
     481        itr != _bufferDataList.end(); 
     482        ++itr) 
     483    { 
     484        if (*itr == bd) return bd->getBufferIndex(); 
     485    } 
     486 
     487    // bd->setBufferIndex(_bufferDataList.size()); 
     488 
     489    _bufferDataList.push_back(bd); 
     490 
     491    // osg::notify(osg::NOTICE)<<"BufferObject "<<this<<":"<<className()<<"::addBufferData("<<bd<<"), bufferIndex= "<<_bufferDataList.size()-1<<std::endl; 
     492 
     493    return _bufferDataList.size()-1; 
     494} 
     495 
     496void BufferObject::removeBufferData(unsigned int index) 
     497{ 
     498    if (index>=_bufferDataList.size()) 
     499    { 
     500        osg::notify(osg::WARN)<<"Error "<<className()<<"::removeBufferData("<<index<<") out of range."<<std::endl; 
     501        return; 
     502    } 
     503 
     504    // osg::notify(osg::NOTICE)<<"BufferObject::"<<this<<":"<<className()<<"::removeBufferData("<<index<<"), size= "<<_bufferDataList.size()<<std::endl; 
     505 
     506    // alter the indices of the BufferData after the entry to be removed so their indices are correctly placed. 
     507    for(unsigned int i=index+1; i<_bufferDataList.size(); ++i) 
     508    { 
     509        _bufferDataList[i]->setBufferIndex(i-1); 
     510    } 
     511 
     512    // remove the entry 
     513    _bufferDataList.erase(_bufferDataList.begin() + index); 
     514 
     515    for(unsigned int i=0; i<_glBufferObjects.size(); ++i) 
     516    { 
     517        if (_glBufferObjects[i].valid()) _glBufferObjects[i]->clear(); 
     518    } 
     519 
     520} 
     521 
     522void BufferObject::removeBufferData(BufferData* bd) 
     523{ 
     524    // osg::notify(osg::NOTICE)<<"BufferObject::"<<this<<":"<<className()<<"::removeBufferData("<<bd<<"), index="<<bd->getBufferIndex()<<" size= "<<_bufferDataList.size()<<std::endl; 
     525 
     526    if (!bd || bd->getBufferObject()!=this) return; 
     527 
     528    removeBufferData(bd->getBufferIndex()); 
     529} 
     530 
     531////////////////////////////////////////////////////////////////////////////////////////////////////// 
     532// 
     533// BufferData 
     534// 
     535BufferData::~BufferData() 
     536{ 
     537    setBufferObject(0); 
     538} 
     539 
     540void BufferData::setBufferObject(BufferObject* bufferObject) 
     541{ 
     542    if (_bufferObject==bufferObject) return; 
     543 
     544    if (_bufferObject.valid()) 
     545    { 
     546        _bufferObject->removeBufferData(_bufferIndex); 
     547    } 
     548 
     549    _bufferObject = bufferObject; 
     550    _bufferIndex = _bufferObject.valid() ? _bufferObject->addBufferData(this) : 0; 
    289551} 
    290552 
     
    312574unsigned int VertexBufferObject::addArray(osg::Array* array) 
    313575{ 
    314     unsigned int i = _bufferEntryArrayPairs.size(); 
    315  
    316     _bufferEntryArrayPairs.resize(i+1); 
    317     _bufferEntryArrayPairs[i].second = array; 
    318     _bufferEntryArrayPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff); 
    319     _bufferEntryArrayPairs[i].first.offset = 0; 
    320  
    321     dirty(); 
    322  
    323     return i; 
     576    return addBufferData(array); 
    324577} 
    325578 
    326579void VertexBufferObject::removeArray(osg::Array* array) 
    327580{ 
    328     BufferEntryArrayPairs::iterator itr; 
    329     for(itr = _bufferEntryArrayPairs.begin(); 
    330         itr != _bufferEntryArrayPairs.end(); 
    331         ++itr) 
    332     { 
    333         if (itr->second == array) break; 
    334     } 
    335     if (itr != _bufferEntryArrayPairs.end()) _bufferEntryArrayPairs.erase(itr); 
     581    removeBufferData(array); 
    336582} 
    337583 
    338584void VertexBufferObject::setArray(unsigned int i, Array* array) 
    339585{ 
    340     if (i+1>=_bufferEntryArrayPairs.size()) _bufferEntryArrayPairs.resize(i+1); 
    341  
    342     _bufferEntryArrayPairs[i].second = array; 
    343     _bufferEntryArrayPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff); 
    344     _bufferEntryArrayPairs[i].first.offset = 0; 
    345  
    346     dirty(); 
    347 } 
     586    setBufferData(i,array); 
     587} 
     588 
     589Array* VertexBufferObject::getArray(unsigned int i) 
     590{ 
     591    return dynamic_cast<osg::Array*>(getBufferData(i)); 
     592} 
     593 
     594const Array* VertexBufferObject::getArray(unsigned int i) const 
     595{ 
     596    return dynamic_cast<const osg::Array*>(getBufferData(i)); 
     597} 
     598#if 0 
    348599void VertexBufferObject::compileBuffer(State& state) const 
    349600{ 
     
    515766//    osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    516767} 
    517  
    518 void VertexBufferObject::resizeGLObjectBuffers(unsigned int maxSize) 
    519 { 
    520     BufferObject::resizeGLObjectBuffers(maxSize); 
    521  
    522     for(BufferEntryArrayPairs::iterator itr = _bufferEntryArrayPairs.begin(); 
    523         itr != _bufferEntryArrayPairs.end(); 
    524         ++itr) 
    525     { 
    526         itr->first.modifiedCount.resize(maxSize); 
    527     } 
    528 } 
     768#endif 
    529769 
    530770////////////////////////////////////////////////////////////////////////////////// 
     
    549789unsigned int ElementBufferObject::addDrawElements(osg::DrawElements* drawElements) 
    550790{ 
    551     unsigned int i = _bufferEntryDrawElementsPairs.size(); 
    552     _bufferEntryDrawElementsPairs.resize(i+1); 
    553     _bufferEntryDrawElementsPairs[i].second = drawElements; 
    554     _bufferEntryDrawElementsPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff); 
    555     _bufferEntryDrawElementsPairs[i].first.dataSize = 0; 
    556  
    557     return i; 
     791    return addBufferData(drawElements); 
    558792} 
    559793 
    560794void ElementBufferObject::removeDrawElements(osg::DrawElements* drawElements) 
    561795{ 
    562     BufferEntryDrawElementsPairs::iterator itr; 
    563     for(itr = _bufferEntryDrawElementsPairs.begin(); 
    564         itr != _bufferEntryDrawElementsPairs.end(); 
    565         ++itr) 
    566     { 
    567         if (itr->second == drawElements) break; 
    568     } 
    569     if (itr != _bufferEntryDrawElementsPairs.end()) _bufferEntryDrawElementsPairs.erase(itr); 
     796    removeBufferData(drawElements); 
    570797} 
    571798 
    572799void ElementBufferObject::setDrawElements(unsigned int i, DrawElements* drawElements) 
    573800{ 
    574     if (i+1>=_bufferEntryDrawElementsPairs.size()) _bufferEntryDrawElementsPairs.resize(i+1); 
    575  
    576     _bufferEntryDrawElementsPairs[i].second = drawElements; 
    577     _bufferEntryDrawElementsPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff); 
    578     _bufferEntryDrawElementsPairs[i].first.dataSize = 0; 
    579 } 
    580  
     801    setBufferData(i,drawElements); 
     802} 
     803 
     804DrawElements* ElementBufferObject::getDrawElements(unsigned int i) 
     805{ 
     806    return dynamic_cast<DrawElements*>(getBufferData(i)); 
     807} 
     808 
     809const DrawElements* ElementBufferObject::getDrawElements(unsigned int i) const 
     810{ 
     811    return dynamic_cast<const DrawElements*>(getBufferData(i)); 
     812} 
     813 
     814 
     815#if 0 
    581816void ElementBufferObject::compileBuffer(State& state) const 
    582817{ 
     
    682917//    osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    683918} 
    684  
    685 void ElementBufferObject::resizeGLObjectBuffers(unsigned int maxSize) 
    686 { 
    687     BufferObject::resizeGLObjectBuffers(maxSize); 
    688  
    689     for(BufferEntryDrawElementsPairs::iterator itr = _bufferEntryDrawElementsPairs.begin(); 
    690         itr != _bufferEntryDrawElementsPairs.end(); 
    691         ++itr) 
    692     { 
    693         itr->first.modifiedCount.resize(maxSize); 
    694     } 
    695 } 
     919#endif 
    696920 
    697921////////////////////////////////////////////////////////////////////////////////// 
     
    704928    _target = GL_PIXEL_UNPACK_BUFFER_ARB; 
    705929    _usage = GL_STREAM_DRAW_ARB; 
    706     _bufferEntryImagePair.second = image; 
    707 } 
    708  
    709 /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ 
     930 
     931    osg::notify(osg::NOTICE)<<"Constructing PixelBufferObject for image="<<image<<std::endl; 
     932 
     933    setBufferData(0, image); 
     934} 
     935 
    710936PixelBufferObject::PixelBufferObject(const PixelBufferObject& buffer,const CopyOp& copyop): 
    711     BufferObject(buffer,copyop), 
    712     _bufferEntryImagePair(buffer._bufferEntryImagePair) 
     937    BufferObject(buffer,copyop) 
    713938{ 
    714939} 
     
    720945void PixelBufferObject::setImage(osg::Image* image) 
    721946{ 
    722     if (_bufferEntryImagePair.second == image) return; 
    723  
    724     _bufferEntryImagePair.second = image; 
    725  
    726     dirty(); 
    727 } 
     947    setBufferData(0, image); 
     948} 
     949 
     950Image* PixelBufferObject::getImage() 
     951{ 
     952    return dynamic_cast<Image*>(getBufferData(0)); 
     953} 
     954 
     955const Image* PixelBufferObject::getImage() const 
     956{ 
     957    return dynamic_cast<const Image*>(getBufferData(0)); 
     958} 
     959 
     960#if 0 
    728961void PixelBufferObject::compileBuffer(State& state) const 
    729962{ 
     
    7821015//    osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl; 
    7831016} 
    784  
    785 void PixelBufferObject::resizeGLObjectBuffers(unsigned int maxSize) 
    786 { 
    787     BufferObject::resizeGLObjectBuffers(maxSize); 
    788  
    789     _bufferEntryImagePair.first.modifiedCount.resize(maxSize); 
    790 } 
    791  
     1017#endif 
    7921018 
    7931019////////////////////////////////////////////////////////////////////////////////// 
     
    8001026    _target = GL_ARRAY_BUFFER_ARB; 
    8011027    _usage = GL_DYNAMIC_DRAW_ARB; 
    802     _bufferData.dataSize = 0; 
    8031028} 
    8041029 
    8051030//-------------------------------------------------------------------------------- 
    8061031PixelDataBufferObject::PixelDataBufferObject(const PixelDataBufferObject& buffer,const CopyOp& copyop): 
    807     BufferObject(buffer,copyop), 
    808     _bufferData(buffer._bufferData) 
     1032    BufferObject(buffer,copyop) 
    8091033{ 
    8101034} 
     
    8191043{ 
    8201044    unsigned int contextID = state.getContextID();     
    821     if (!isDirty(contextID) || _bufferData.dataSize == 0) return; 
    822  
    823     Extensions* extensions = getExtensions(contextID,true); 
    824  
    825     GLuint& pbo = buffer(contextID); 
    826     if (pbo == 0) 
    827     { 
    828         extensions->glGenBuffers(1, &pbo); 
    829     } 
    830  
    831     extensions->glBindBuffer(_target, pbo); 
    832     extensions->glBufferData(_target, _bufferData.dataSize, NULL, _usage); 
    833     extensions->glBindBuffer(_target, 0); 
    834  
    835     _compiledList[contextID] = 1; 
     1045    if ( _dataSize == 0) return; 
     1046 
     1047    GLBufferObject* bo = getOrCreateGLBufferObject(contextID); 
     1048    if (!bo || !bo->isDirty()) return; 
     1049 
     1050    bo->_extensions->glBindBuffer(_target, bo->getGLObjectID()); 
     1051    bo->_extensions->glBufferData(_target, _dataSize, NULL, _usage); 
     1052    bo->_extensions->glBindBuffer(_target, 0); 
    8361053} 
    8371054 
     
    8401057{ 
    8411058    unsigned int contextID = state.getContextID();     
    842     if (isDirty(contextID)) compileBuffer(state); 
    843  
    844     Extensions* extensions = getExtensions(contextID,true); 
    845  
    846     extensions->glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, buffer(contextID)); 
     1059 
     1060    GLBufferObject* bo = getOrCreateGLBufferObject(contextID); 
     1061    if (!bo) return; 
     1062 
     1063    if (bo->isDirty()) compileBuffer(state); 
     1064 
     1065    bo->_extensions->glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, bo->getGLObjectID()); 
     1066 
    8471067    _mode[contextID] = READ; 
    8481068} 
     
    8521072{ 
    8531073    unsigned int contextID = state.getContextID();     
    854     if (isDirty(contextID)) compileBuffer(state); 
    855  
    856     Extensions* extensions = getExtensions(contextID,true); 
    857  
    858     extensions->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer(contextID)); 
     1074 
     1075    GLBufferObject* bo = getOrCreateGLBufferObject(contextID); 
     1076    if (!bo) return; 
     1077 
     1078    if (bo->isDirty()) compileBuffer(state); 
     1079 
     1080    bo->_extensions->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, bo->getGLObjectID()); 
     1081 
    8591082    _mode[contextID] = WRITE; 
    8601083} 
     
    8631086void PixelDataBufferObject::unbindBuffer(unsigned int contextID) const 
    8641087{  
    865     Extensions* extensions = getExtensions(contextID,true); 
     1088    GLBufferObject::Extensions* extensions = GLBufferObject::getExtensions(contextID,true); 
    8661089 
    8671090    switch(_mode[contextID]) 
     
    8891112} 
    8901113 
     1114 
     1115#endif