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

This commit is contained in:
Robert Osfield
2009-10-01 20:19:42 +00:00
parent cfac6a7809
commit f75013d534
24 changed files with 1067 additions and 842 deletions

View File

@@ -37,7 +37,185 @@ typedef osg::buffered_object<BufferObjectMap> DeletedBufferObjectCache;
static OpenThreads::Mutex s_mutex_deletedBufferObjectCache;
static DeletedBufferObjectCache s_deletedBufferObjectCache;
void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj)
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// GLBufferObject
//
GLBufferObject::GLBufferObject(unsigned int contextID, BufferObject* bufferObject):
_contextID(contextID),
_glObjectID(0),
_target(0),
_usage(0),
_dirty(true),
_totalSize(0),
_bufferObject(0),
_extensions(0)
{
assign(bufferObject);
_extensions = GLBufferObject::getExtensions(contextID, true);
_extensions->glGenBuffers(1, &_glObjectID);
}
GLBufferObject::~GLBufferObject()
{
if (_glObjectID!=0) GLBufferObject::deleteBufferObject(_contextID, _glObjectID);
}
void GLBufferObject::assign(BufferObject* bufferObject)
{
_bufferObject = bufferObject;
if (_bufferObject)
{
_target = bufferObject->getTarget();
_usage = bufferObject->getUsage();
_totalSize = 0;
_dirty = true;
_bufferEntries.clear();
}
else
{
_target = 0;
_usage = 0;
_totalSize = 0;
// clear all previous entries;
_bufferEntries.clear();
}
}
void GLBufferObject::clear()
{
_bufferEntries.clear();
_dirty = true;
}
void GLBufferObject::compileBuffer()
{
_dirty = false;
_bufferEntries.reserve(_bufferObject->getNumBufferData());
_totalSize = 0;
bool compileAll = false;
bool offsetChanged = false;
GLsizeiptrARB newTotalSize = 0;
unsigned int i=0;
for(; i<_bufferObject->getNumBufferData(); ++i)
{
BufferData* bd = _bufferObject->getBufferData(i);
if (i<_bufferEntries.size())
{
BufferEntry& entry = _bufferEntries[i];
if (offsetChanged ||
entry.dataSource != bd ||
entry.dataSize != bd->getTotalDataSize())
{
GLsizeiptrARB previousEndOfBufferDataMarker = GLsizeiptrARB(entry.offset) + entry.dataSize;
// osg::notify(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) updating BufferEntry"<<std::endl;
entry.offset = newTotalSize;
entry.modifiedCount = 0xffffff;
entry.dataSize = bd->getTotalDataSize();
entry.dataSource = bd;
newTotalSize += entry.dataSize;
if (previousEndOfBufferDataMarker==newTotalSize)
{
offsetChanged = true;
}
}
}
else
{
BufferEntry entry;
entry.offset = newTotalSize;
entry.modifiedCount = 0xffffff;
entry.dataSize = bd->getTotalDataSize();
entry.dataSource = bd;
#if 0
osg::notify(osg::NOTICE)<<"entry"<<std::endl;
osg::notify(osg::NOTICE)<<" offset "<<entry.offset<<std::endl;
osg::notify(osg::NOTICE)<<" dataSize "<<entry.dataSize<<std::endl;
osg::notify(osg::NOTICE)<<" dataSource "<<entry.dataSource<<std::endl;
osg::notify(osg::NOTICE)<<" modifiedCount "<<entry.modifiedCount<<std::endl;
#endif
newTotalSize += entry.dataSize;
_bufferEntries.push_back(entry);
}
}
if (i<_bufferEntries.size())
{
// triming end of bufferEntries as the source data is has less entries than the originally held.
_bufferEntries.erase(_bufferEntries.begin()+i, _bufferEntries.end());
}
_extensions->glBindBuffer(_target, _glObjectID);
if (newTotalSize != _totalSize)
{
_totalSize = newTotalSize;
_extensions->glBufferData(_target, _totalSize, NULL, _usage);
}
char* vboMemory = 0;
#if 0
vboMemory = extensions->glMapBuffer(_target, GL_WRITE_ONLY_ARB);
#endif
for(BufferEntries::iterator itr = _bufferEntries.begin();
itr != _bufferEntries.end();
++itr)
{
BufferEntry& entry = *itr;
if (compileAll || entry.modifiedCount != entry.dataSource->getModifiedCount())
{
// osg::notify(osg::NOTICE)<<"GLBufferObject::compileBuffer(..) downloading BufferEntry "<<&entry<<std::endl;
entry.modifiedCount = entry.dataSource->getModifiedCount();
if (vboMemory)
memcpy(vboMemory + (GLsizeiptrARB)entry.offset, entry.dataSource->getDataPointer(), entry.dataSize);
else
_extensions->glBufferSubData(_target, (GLintptrARB)entry.offset, (GLsizeiptrARB)entry.dataSize, entry.dataSource->getDataPointer());
}
}
// Unmap the texture image buffer
if (vboMemory) _extensions->glUnmapBuffer(_target);
}
GLBufferObject* GLBufferObject::createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject)
{
return new GLBufferObject(contextID, const_cast<BufferObject*>(bufferObject));
}
void GLBufferObject::deleteGLObject()
{
if (_glObjectID!=0)
{
_extensions->glDeleteBuffers(1, &_glObjectID);
_glObjectID = 0;
_totalSize = 0;
_bufferEntries.clear();
}
}
void GLBufferObject::deleteBufferObject(unsigned int contextID,GLuint globj)
{
if (globj!=0)
{
@@ -48,7 +226,7 @@ void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj)
}
}
void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime)
void GLBufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
@@ -84,85 +262,38 @@ void BufferObject::flushDeletedBufferObjects(unsigned int contextID,double /*cur
availableTime -= elapsedTime;
}
void BufferObject::discardDeletedBufferObjects(unsigned int contextID)
void GLBufferObject::discardDeletedBufferObjects(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedBufferObjectCache);
BufferObjectMap& dll = s_deletedBufferObjectCache[contextID];
dll.clear();
}
BufferObject::BufferObject():
_target(0),
_usage(0),
_totalSize(0)
{
}
BufferObject::BufferObject(const BufferObject& bo,const CopyOp& copyop):
Object(bo,copyop)
{
}
BufferObject::~BufferObject()
{
releaseGLObjects(0);
}
void BufferObject::resizeGLObjectBuffers(unsigned int maxSize)
{
_bufferObjectList.resize(maxSize);
}
void BufferObject::releaseGLObjects(State* state) const
{
if (state)
{
unsigned int contextID = state->getContextID();
if (_bufferObjectList[contextID])
{
deleteBufferObject(contextID,_bufferObjectList[contextID]);
_bufferObjectList[contextID] = 0;
}
}
else
{
for(unsigned int contextID=0;contextID<_bufferObjectList.size();++contextID)
{
if (_bufferObjectList[contextID])
{
deleteBufferObject(contextID,_bufferObjectList[contextID]);
_bufferObjectList[contextID] = 0;
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
//
// Extension support
//
typedef buffered_value< ref_ptr<BufferObject::Extensions> > BufferedExtensions;
typedef buffered_value< ref_ptr<GLBufferObject::Extensions> > BufferedExtensions;
static BufferedExtensions s_extensions;
BufferObject::Extensions* BufferObject::getExtensions(unsigned int contextID,bool createIfNotInitalized)
GLBufferObject::Extensions* GLBufferObject::getExtensions(unsigned int contextID,bool createIfNotInitalized)
{
if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new BufferObject::Extensions(contextID);
if (!s_extensions[contextID] && createIfNotInitalized) s_extensions[contextID] = new GLBufferObject::Extensions(contextID);
return s_extensions[contextID].get();
}
void BufferObject::setExtensions(unsigned int contextID,Extensions* extensions)
void GLBufferObject::setExtensions(unsigned int contextID,Extensions* extensions)
{
s_extensions[contextID] = extensions;
}
BufferObject::Extensions::Extensions(unsigned int contextID)
GLBufferObject::Extensions::Extensions(unsigned int contextID)
{
setupGLExtensions(contextID);
}
BufferObject::Extensions::Extensions(const Extensions& rhs):
GLBufferObject::Extensions::Extensions(const Extensions& rhs):
Referenced()
{
_glGenBuffers = rhs._glGenBuffers;
@@ -179,7 +310,7 @@ BufferObject::Extensions::Extensions(const Extensions& rhs):
}
void BufferObject::Extensions::lowestCommonDenominator(const Extensions& rhs)
void GLBufferObject::Extensions::lowestCommonDenominator(const Extensions& rhs)
{
if (!rhs._glGenBuffers) _glGenBuffers = rhs._glGenBuffers;
if (!rhs._glBindBuffer) _glBindBuffer = rhs._glBindBuffer;
@@ -194,7 +325,7 @@ void BufferObject::Extensions::lowestCommonDenominator(const Extensions& rhs)
if (!rhs._glGetBufferParameteriv) _glGetBufferPointerv = rhs._glGetBufferPointerv;
}
void BufferObject::Extensions::setupGLExtensions(unsigned int contextID)
void GLBufferObject::Extensions::setupGLExtensions(unsigned int contextID)
{
setGLExtensionFuncPtr(_glGenBuffers, "glGenBuffers","glGenBuffersARB");
setGLExtensionFuncPtr(_glBindBuffer, "glBindBuffer","glBindBufferARB");
@@ -210,37 +341,37 @@ void BufferObject::Extensions::setupGLExtensions(unsigned int contextID)
_isPBOSupported = osg::isGLExtensionSupported(contextID,"GL_ARB_pixel_buffer_object");
}
void BufferObject::Extensions::glGenBuffers(GLsizei n, GLuint *buffers) const
void GLBufferObject::Extensions::glGenBuffers(GLsizei n, GLuint *buffers) const
{
if (_glGenBuffers) _glGenBuffers(n, buffers);
else notify(WARN)<<"Error: glGenBuffers not supported by OpenGL driver"<<std::endl;
}
void BufferObject::Extensions::glBindBuffer(GLenum target, GLuint buffer) const
void GLBufferObject::Extensions::glBindBuffer(GLenum target, GLuint buffer) const
{
if (_glBindBuffer) _glBindBuffer(target, buffer);
else notify(WARN)<<"Error: glBindBuffer not supported by OpenGL driver"<<std::endl;
}
void BufferObject::Extensions::glBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const
void GLBufferObject::Extensions::glBufferData(GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const
{
if (_glBufferData) _glBufferData(target, size, data, usage);
else notify(WARN)<<"Error: glBufferData not supported by OpenGL driver"<<std::endl;
}
void BufferObject::Extensions::glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const
void GLBufferObject::Extensions::glBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const
{
if (_glBufferSubData) _glBufferSubData(target, offset, size, data);
else notify(WARN)<<"Error: glBufferData not supported by OpenGL driver"<<std::endl;
}
void BufferObject::Extensions::glDeleteBuffers(GLsizei n, const GLuint *buffers) const
void GLBufferObject::Extensions::glDeleteBuffers(GLsizei n, const GLuint *buffers) const
{
if (_glDeleteBuffers) _glDeleteBuffers(n, buffers);
else notify(WARN)<<"Error: glBufferData not supported by OpenGL driver"<<std::endl;
}
GLboolean BufferObject::Extensions::glIsBuffer (GLuint buffer) const
GLboolean GLBufferObject::Extensions::glIsBuffer (GLuint buffer) const
{
if (_glIsBuffer) return _glIsBuffer(buffer);
else
@@ -250,13 +381,13 @@ GLboolean BufferObject::Extensions::glIsBuffer (GLuint buffer) const
}
}
void BufferObject::Extensions::glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const
void GLBufferObject::Extensions::glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const
{
if (_glGetBufferSubData) _glGetBufferSubData(target,offset,size,data);
else notify(WARN)<<"Error: glGetBufferSubData not supported by OpenGL driver"<<std::endl;
}
GLvoid* BufferObject::Extensions::glMapBuffer (GLenum target, GLenum access) const
GLvoid* GLBufferObject::Extensions::glMapBuffer (GLenum target, GLenum access) const
{
if (_glMapBuffer) return _glMapBuffer(target,access);
else
@@ -266,7 +397,7 @@ GLvoid* BufferObject::Extensions::glMapBuffer (GLenum target, GLenum access) con
}
}
GLboolean BufferObject::Extensions::glUnmapBuffer (GLenum target) const
GLboolean GLBufferObject::Extensions::glUnmapBuffer (GLenum target) const
{
if (_glUnmapBuffer) return _glUnmapBuffer(target);
else
@@ -276,18 +407,149 @@ GLboolean BufferObject::Extensions::glUnmapBuffer (GLenum target) const
}
}
void BufferObject::Extensions::glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const
void GLBufferObject::Extensions::glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const
{
if (_glGetBufferParameteriv) _glGetBufferParameteriv(target,pname,params);
else notify(WARN)<<"Error: glGetBufferParameteriv not supported by OpenGL driver"<<std::endl;
}
void BufferObject::Extensions::glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const
void GLBufferObject::Extensions::glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const
{
if (_glGetBufferPointerv) _glGetBufferPointerv(target,pname,params);
else notify(WARN)<<"Error: glGetBufferPointerv not supported by OpenGL driver"<<std::endl;
}
#if 1
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// BufferObject
//
BufferObject::BufferObject():
_target(0),
_usage(0)
{
}
BufferObject::BufferObject(const BufferObject& bo,const CopyOp& copyop):
Object(bo,copyop)
{
}
BufferObject::~BufferObject()
{
releaseGLObjects(0);
}
void BufferObject::setBufferData(unsigned int index, BufferData* bd)
{
if (index>=_bufferDataList.size()) _bufferDataList.resize(index+1);
_bufferDataList[index] = bd;
}
void BufferObject::dirty()
{
for(unsigned int i=0; i<_glBufferObjects.size(); ++i)
{
if (_glBufferObjects[i].valid()) _glBufferObjects[i]->dirty();
}
}
void BufferObject::resizeGLObjectBuffers(unsigned int maxSize)
{
_glBufferObjects.resize(maxSize);
}
void BufferObject::releaseGLObjects(State* state) const
{
if (state)
{
_glBufferObjects[state->getContextID()] = 0;
}
else
{
_glBufferObjects.clear();
}
}
unsigned int BufferObject::addBufferData(BufferData* bd)
{
if (!bd) return 0;
// check to see if bd exists in BufferObject already, is so return without doing anything
for(BufferDataList::iterator itr = _bufferDataList.begin();
itr != _bufferDataList.end();
++itr)
{
if (*itr == bd) return bd->getBufferIndex();
}
// bd->setBufferIndex(_bufferDataList.size());
_bufferDataList.push_back(bd);
// osg::notify(osg::NOTICE)<<"BufferObject "<<this<<":"<<className()<<"::addBufferData("<<bd<<"), bufferIndex= "<<_bufferDataList.size()-1<<std::endl;
return _bufferDataList.size()-1;
}
void BufferObject::removeBufferData(unsigned int index)
{
if (index>=_bufferDataList.size())
{
osg::notify(osg::WARN)<<"Error "<<className()<<"::removeBufferData("<<index<<") out of range."<<std::endl;
return;
}
// osg::notify(osg::NOTICE)<<"BufferObject::"<<this<<":"<<className()<<"::removeBufferData("<<index<<"), size= "<<_bufferDataList.size()<<std::endl;
// alter the indices of the BufferData after the entry to be removed so their indices are correctly placed.
for(unsigned int i=index+1; i<_bufferDataList.size(); ++i)
{
_bufferDataList[i]->setBufferIndex(i-1);
}
// remove the entry
_bufferDataList.erase(_bufferDataList.begin() + index);
for(unsigned int i=0; i<_glBufferObjects.size(); ++i)
{
if (_glBufferObjects[i].valid()) _glBufferObjects[i]->clear();
}
}
void BufferObject::removeBufferData(BufferData* bd)
{
// osg::notify(osg::NOTICE)<<"BufferObject::"<<this<<":"<<className()<<"::removeBufferData("<<bd<<"), index="<<bd->getBufferIndex()<<" size= "<<_bufferDataList.size()<<std::endl;
if (!bd || bd->getBufferObject()!=this) return;
removeBufferData(bd->getBufferIndex());
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// BufferData
//
BufferData::~BufferData()
{
setBufferObject(0);
}
void BufferData::setBufferObject(BufferObject* bufferObject)
{
if (_bufferObject==bufferObject) return;
if (_bufferObject.valid())
{
_bufferObject->removeBufferData(_bufferIndex);
}
_bufferObject = bufferObject;
_bufferIndex = _bufferObject.valid() ? _bufferObject->addBufferData(this) : 0;
}
//////////////////////////////////////////////////////////////////////////////////
//
// VertexBufferObject
@@ -311,40 +573,29 @@ VertexBufferObject::~VertexBufferObject()
unsigned int VertexBufferObject::addArray(osg::Array* array)
{
unsigned int i = _bufferEntryArrayPairs.size();
_bufferEntryArrayPairs.resize(i+1);
_bufferEntryArrayPairs[i].second = array;
_bufferEntryArrayPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff);
_bufferEntryArrayPairs[i].first.offset = 0;
dirty();
return i;
return addBufferData(array);
}
void VertexBufferObject::removeArray(osg::Array* array)
{
BufferEntryArrayPairs::iterator itr;
for(itr = _bufferEntryArrayPairs.begin();
itr != _bufferEntryArrayPairs.end();
++itr)
{
if (itr->second == array) break;
}
if (itr != _bufferEntryArrayPairs.end()) _bufferEntryArrayPairs.erase(itr);
removeBufferData(array);
}
void VertexBufferObject::setArray(unsigned int i, Array* array)
{
if (i+1>=_bufferEntryArrayPairs.size()) _bufferEntryArrayPairs.resize(i+1);
_bufferEntryArrayPairs[i].second = array;
_bufferEntryArrayPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff);
_bufferEntryArrayPairs[i].first.offset = 0;
dirty();
setBufferData(i,array);
}
Array* VertexBufferObject::getArray(unsigned int i)
{
return dynamic_cast<osg::Array*>(getBufferData(i));
}
const Array* VertexBufferObject::getArray(unsigned int i) const
{
return dynamic_cast<const osg::Array*>(getBufferData(i));
}
#if 0
void VertexBufferObject::compileBuffer(State& state) const
{
unsigned int contextID = state.getContextID();
@@ -514,18 +765,7 @@ void VertexBufferObject::compileBuffer(State& state) const
// osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl;
// osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
}
void VertexBufferObject::resizeGLObjectBuffers(unsigned int maxSize)
{
BufferObject::resizeGLObjectBuffers(maxSize);
for(BufferEntryArrayPairs::iterator itr = _bufferEntryArrayPairs.begin();
itr != _bufferEntryArrayPairs.end();
++itr)
{
itr->first.modifiedCount.resize(maxSize);
}
}
#endif
//////////////////////////////////////////////////////////////////////////////////
//
@@ -548,36 +788,31 @@ ElementBufferObject::~ElementBufferObject()
unsigned int ElementBufferObject::addDrawElements(osg::DrawElements* drawElements)
{
unsigned int i = _bufferEntryDrawElementsPairs.size();
_bufferEntryDrawElementsPairs.resize(i+1);
_bufferEntryDrawElementsPairs[i].second = drawElements;
_bufferEntryDrawElementsPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff);
_bufferEntryDrawElementsPairs[i].first.dataSize = 0;
return i;
return addBufferData(drawElements);
}
void ElementBufferObject::removeDrawElements(osg::DrawElements* drawElements)
{
BufferEntryDrawElementsPairs::iterator itr;
for(itr = _bufferEntryDrawElementsPairs.begin();
itr != _bufferEntryDrawElementsPairs.end();
++itr)
{
if (itr->second == drawElements) break;
}
if (itr != _bufferEntryDrawElementsPairs.end()) _bufferEntryDrawElementsPairs.erase(itr);
removeBufferData(drawElements);
}
void ElementBufferObject::setDrawElements(unsigned int i, DrawElements* drawElements)
{
if (i+1>=_bufferEntryDrawElementsPairs.size()) _bufferEntryDrawElementsPairs.resize(i+1);
_bufferEntryDrawElementsPairs[i].second = drawElements;
_bufferEntryDrawElementsPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff);
_bufferEntryDrawElementsPairs[i].first.dataSize = 0;
setBufferData(i,drawElements);
}
DrawElements* ElementBufferObject::getDrawElements(unsigned int i)
{
return dynamic_cast<DrawElements*>(getBufferData(i));
}
const DrawElements* ElementBufferObject::getDrawElements(unsigned int i) const
{
return dynamic_cast<const DrawElements*>(getBufferData(i));
}
#if 0
void ElementBufferObject::compileBuffer(State& state) const
{
unsigned int contextID = state.getContextID();
@@ -681,18 +916,7 @@ void ElementBufferObject::compileBuffer(State& state) const
// osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl;
// osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
}
void ElementBufferObject::resizeGLObjectBuffers(unsigned int maxSize)
{
BufferObject::resizeGLObjectBuffers(maxSize);
for(BufferEntryDrawElementsPairs::iterator itr = _bufferEntryDrawElementsPairs.begin();
itr != _bufferEntryDrawElementsPairs.end();
++itr)
{
itr->first.modifiedCount.resize(maxSize);
}
}
#endif
//////////////////////////////////////////////////////////////////////////////////
//
@@ -703,13 +927,14 @@ PixelBufferObject::PixelBufferObject(osg::Image* image):
{
_target = GL_PIXEL_UNPACK_BUFFER_ARB;
_usage = GL_STREAM_DRAW_ARB;
_bufferEntryImagePair.second = image;
osg::notify(osg::NOTICE)<<"Constructing PixelBufferObject for image="<<image<<std::endl;
setBufferData(0, image);
}
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
PixelBufferObject::PixelBufferObject(const PixelBufferObject& buffer,const CopyOp& copyop):
BufferObject(buffer,copyop),
_bufferEntryImagePair(buffer._bufferEntryImagePair)
BufferObject(buffer,copyop)
{
}
@@ -719,12 +944,20 @@ PixelBufferObject::~PixelBufferObject()
void PixelBufferObject::setImage(osg::Image* image)
{
if (_bufferEntryImagePair.second == image) return;
_bufferEntryImagePair.second = image;
dirty();
setBufferData(0, image);
}
Image* PixelBufferObject::getImage()
{
return dynamic_cast<Image*>(getBufferData(0));
}
const Image* PixelBufferObject::getImage() const
{
return dynamic_cast<const Image*>(getBufferData(0));
}
#if 0
void PixelBufferObject::compileBuffer(State& state) const
{
unsigned int contextID = state.getContextID();
@@ -781,14 +1014,7 @@ void PixelBufferObject::compileBuffer(State& state) const
// osg::notify(osg::NOTICE)<<"pbo _totalSize="<<_totalSize<<std::endl;
// osg::notify(osg::NOTICE)<<"pbo "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
}
void PixelBufferObject::resizeGLObjectBuffers(unsigned int maxSize)
{
BufferObject::resizeGLObjectBuffers(maxSize);
_bufferEntryImagePair.first.modifiedCount.resize(maxSize);
}
#endif
//////////////////////////////////////////////////////////////////////////////////
//
@@ -799,13 +1025,11 @@ PixelDataBufferObject::PixelDataBufferObject()
{
_target = GL_ARRAY_BUFFER_ARB;
_usage = GL_DYNAMIC_DRAW_ARB;
_bufferData.dataSize = 0;
}
//--------------------------------------------------------------------------------
PixelDataBufferObject::PixelDataBufferObject(const PixelDataBufferObject& buffer,const CopyOp& copyop):
BufferObject(buffer,copyop),
_bufferData(buffer._bufferData)
BufferObject(buffer,copyop)
{
}
@@ -818,32 +1042,28 @@ PixelDataBufferObject::~PixelDataBufferObject()
void PixelDataBufferObject::compileBuffer(State& state) const
{
unsigned int contextID = state.getContextID();
if (!isDirty(contextID) || _bufferData.dataSize == 0) return;
if ( _dataSize == 0) return;
Extensions* extensions = getExtensions(contextID,true);
GLBufferObject* bo = getOrCreateGLBufferObject(contextID);
if (!bo || !bo->isDirty()) return;
GLuint& pbo = buffer(contextID);
if (pbo == 0)
{
extensions->glGenBuffers(1, &pbo);
}
extensions->glBindBuffer(_target, pbo);
extensions->glBufferData(_target, _bufferData.dataSize, NULL, _usage);
extensions->glBindBuffer(_target, 0);
_compiledList[contextID] = 1;
bo->_extensions->glBindBuffer(_target, bo->getGLObjectID());
bo->_extensions->glBufferData(_target, _dataSize, NULL, _usage);
bo->_extensions->glBindBuffer(_target, 0);
}
//--------------------------------------------------------------------------------
void PixelDataBufferObject::bindBufferInReadMode(State& state)
{
unsigned int contextID = state.getContextID();
if (isDirty(contextID)) compileBuffer(state);
Extensions* extensions = getExtensions(contextID,true);
GLBufferObject* bo = getOrCreateGLBufferObject(contextID);
if (!bo) return;
if (bo->isDirty()) compileBuffer(state);
bo->_extensions->glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, bo->getGLObjectID());
extensions->glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, buffer(contextID));
_mode[contextID] = READ;
}
@@ -851,18 +1071,21 @@ void PixelDataBufferObject::bindBufferInReadMode(State& state)
void PixelDataBufferObject::bindBufferInWriteMode(State& state)
{
unsigned int contextID = state.getContextID();
if (isDirty(contextID)) compileBuffer(state);
Extensions* extensions = getExtensions(contextID,true);
GLBufferObject* bo = getOrCreateGLBufferObject(contextID);
if (!bo) return;
if (bo->isDirty()) compileBuffer(state);
bo->_extensions->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, bo->getGLObjectID());
extensions->glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, buffer(contextID));
_mode[contextID] = WRITE;
}
//--------------------------------------------------------------------------------
void PixelDataBufferObject::unbindBuffer(unsigned int contextID) const
{
Extensions* extensions = getExtensions(contextID,true);
GLBufferObject::Extensions* extensions = GLBufferObject::getExtensions(contextID,true);
switch(_mode[contextID])
{
@@ -888,3 +1111,5 @@ void PixelDataBufferObject::resizeGLObjectBuffers(unsigned int maxSize)
_mode.resize(maxSize);
}
#endif

View File

@@ -23,7 +23,7 @@
void osg::flushDeletedGLObjects(unsigned int contextID, double currentTime, double& availableTime)
{
osg::BufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
osg::GLBufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
osg::Drawable::flushDeletedDisplayLists(contextID,availableTime);
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
@@ -39,7 +39,7 @@ void osg::flushAllDeletedGLObjects(unsigned int contextID)
{
double currentTime = DBL_MAX;
double availableTime = DBL_MAX;
osg::BufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
osg::GLBufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
osg::Drawable::flushAllDeletedDisplayLists(contextID);
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
@@ -53,7 +53,7 @@ void osg::flushAllDeletedGLObjects(unsigned int contextID)
void osg::discardAllDeletedGLObjects(unsigned int contextID)
{
osg::BufferObject::discardDeletedBufferObjects(contextID);
osg::GLBufferObject::discardDeletedBufferObjects(contextID);
osg::Drawable::discardAllDeletedDisplayLists(contextID);
osg::FragmentProgram::discardDeletedFragmentProgramObjects(contextID);
osg::FrameBufferObject::discardDeletedFrameBufferObjects(contextID);

View File

@@ -1374,6 +1374,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
//
if (usingVertexBufferObjects)
{
// osg::notify(osg::NOTICE)<<"Geometry::drawImplementation() Using VertexBufferObjects"<<std::endl;
//
// Vertex Buffer Object path for defining vertex arrays.
@@ -1416,7 +1417,6 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
}
}
state.disableVertexAttribPointersAboveAndIncluding( index );
}
else if (vertexVertexAttributesSupported)
{
@@ -1429,7 +1429,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
}
else
{
//std::cout << "none VertexBuffer path"<<std::endl;
// osg::notify(osg::NOTICE)<<"none VertexBuffer path"<<std::endl;
//
// Non Vertex Buffer Object path for defining vertex arrays.

View File

@@ -33,7 +33,7 @@ using namespace osg;
using namespace std;
Image::Image()
:Object(true),
:BufferData(),
_fileName(""),
_writeHint(NO_PREFERENCE),
_origin(BOTTOM_LEFT),
@@ -44,14 +44,13 @@ Image::Image()
_packing(4),
_pixelAspectRatio(1.0),
_allocationMode(USE_NEW_DELETE),
_data(0L),
_modifiedCount(0)
_data(0L)
{
setDataVariance(STATIC);
}
Image::Image(const Image& image,const CopyOp& copyop):
Object(image,copyop),
BufferData(image,copyop),
_fileName(image._fileName),
_writeHint(image._writeHint),
_origin(image._origin),
@@ -62,7 +61,6 @@ Image::Image(const Image& image,const CopyOp& copyop):
_packing(image._packing),
_pixelAspectRatio(image._pixelAspectRatio),
_data(0L),
_modifiedCount(image._modifiedCount),
_mipmapData(image._mipmapData)
{
if (image._data)

View File

@@ -126,12 +126,12 @@ void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
{
if (useVertexBufferObjects)
{
const ElementBufferObject* ebo = getElementBufferObject();
GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
state.bindElementBufferObject(ebo);
if (ebo)
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, getElementBufferObjectOffset());
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
}
else
{
@@ -176,12 +176,12 @@ void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
{
if (useVertexBufferObjects)
{
const ElementBufferObject* ebo = getElementBufferObject();
GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
state.bindElementBufferObject(ebo);
if (ebo)
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_SHORT, getElementBufferObjectOffset(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, getElementBufferObjectOffset());
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
}
else
{
@@ -226,12 +226,12 @@ void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
{
if (useVertexBufferObjects)
{
const ElementBufferObject* ebo = getElementBufferObject();
GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
state.bindElementBufferObject(ebo);
if (ebo)
{
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_INT, getElementBufferObjectOffset(), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, getElementBufferObjectOffset());
if (_numInstances>=1) state.glDrawElementsInstanced(_mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
else glDrawElements(_mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
}
else
{

View File

@@ -46,7 +46,7 @@
#define GL_STORAGE_SHARED_APPLE 0x85BF
#endif
//#define DO_TIMING
// #define DO_TIMING
namespace osg {
@@ -1777,15 +1777,12 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
bool useHardwareMipMapGeneration = mipmappingRequired && (!image->isMipmap() && isHardwareMipmapGenerationEnabled(state));
bool useGluBuildMipMaps = mipmappingRequired && (!useHardwareMipMapGeneration && !image->isMipmap());
unsigned char* dataMinusOffset = 0;
unsigned char* dataPlusOffset = 0;
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID) && !needImageRescale && !useGluBuildMipMaps)
const unsigned char* dataPtr = image->data();
GLBufferObject* pbo = image->getOrCreateGLBufferObject(contextID);
if (pbo && !needImageRescale && !useGluBuildMipMaps)
{
state.bindPixelBufferObject(pbo);
dataMinusOffset = data;
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset());
dataPtr = reinterpret_cast<const unsigned char*>(pbo->getOffset(image->getBufferIndex()));
#ifdef DO_TIMING
osg::notify(osg::NOTICE)<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
#endif
@@ -1808,7 +1805,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
inwidth, inheight, _borderWidth,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
data -dataMinusOffset+dataPlusOffset);
dataPtr);
}
else if (extensions->isCompressedTexImage2DSupported())
@@ -1821,7 +1818,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
extensions->glCompressedTexImage2D(target, 0, _internalFormat,
inwidth, inheight,0,
size,
data-dataMinusOffset+dataPlusOffset);
dataPtr);
}
mipmapAfterTexImage(state, mipmapResult);
@@ -1853,7 +1850,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
width, height, _borderWidth,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
image->getMipmapData(k)-dataMinusOffset+dataPlusOffset);
dataPtr + image->getMipmapOffset(k));
width >>= 1;
height >>= 1;
@@ -1874,7 +1871,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
extensions->glCompressedTexImage2D(target, k, _internalFormat,
width, height, _borderWidth,
size, image->getMipmapData(k)-dataMinusOffset+dataPlusOffset);
size, dataPtr + image->getMipmapOffset(k));
width >>= 1;
height >>= 1;
@@ -2027,12 +2024,12 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
unsigned char* dataMinusOffset = 0;
unsigned char* dataPlusOffset = 0;
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID) && !needImageRescale && !useGluBuildMipMaps)
const unsigned char* dataPtr = image->data();
GLBufferObject* pbo = image->getOrCreateGLBufferObject(contextID);
if (pbo && !needImageRescale && !useGluBuildMipMaps)
{
state.bindPixelBufferObject(pbo);
dataMinusOffset = data;
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset());
dataPtr = reinterpret_cast<unsigned char*>(pbo->getOffset(image->getBufferIndex()));
#ifdef DO_TIMING
osg::notify(osg::NOTICE)<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
#endif

View File

@@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@@ -290,19 +290,12 @@ void TextureRectangle::applyTexImage_load(GLenum target, Image* image, State& st
#endif
}
unsigned char* dataMinusOffset = 0;
unsigned char* dataPlusOffset = 0;
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID))
const unsigned char* dataPtr = image->data();
GLBufferObject* pbo = image->getOrCreateGLBufferObject(contextID);
if (pbo)
{
state.bindPixelBufferObject(pbo);
dataMinusOffset = image->data();
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset());
}
else
{
pbo = 0;
dataPtr = reinterpret_cast<unsigned char*>(pbo->getOffset(image->getBufferIndex()));
}
if(isCompressedInternalFormat(_internalFormat) && extensions->isCompressedTexImage2DSupported())
@@ -310,7 +303,7 @@ void TextureRectangle::applyTexImage_load(GLenum target, Image* image, State& st
extensions->glCompressedTexImage2D(target, 0, _internalFormat,
image->s(), image->t(), 0,
image->getImageSizeInBytes(),
image->data() - dataMinusOffset + dataPlusOffset);
dataPtr);
}
else
{
@@ -318,7 +311,7 @@ void TextureRectangle::applyTexImage_load(GLenum target, Image* image, State& st
image->s(), image->t(), 0,
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
image->data() - dataMinusOffset + dataPlusOffset );
dataPtr );
}
@@ -365,26 +358,21 @@ void TextureRectangle::applyTexImage_subload(GLenum target, Image* image, State&
#ifdef DO_TIMING
osg::Timer_t start_tick = osg::Timer::instance()->tick();
osg::notify(osg::NOTICE)<<"glTexSubImage2D pixelFormat = "<<std::hex<<image->getPixelFormat()<<std::dec<<std::endl;
osg::notify(osg::NOTICE)<<"TextureRectangle::apply pixelFormat = "<<std::hex<<image->getPixelFormat()<<std::dec<<std::endl;
#endif
unsigned char* dataMinusOffset = 0;
unsigned char* dataPlusOffset = 0;
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID))
const unsigned char* dataPtr = image->data();
GLBufferObject* pbo = image->getOrCreateGLBufferObject(contextID);
if (pbo)
{
state.bindPixelBufferObject(pbo);
dataMinusOffset = image->data();
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset()); // -dataMinusOffset+dataPlusOffset
dataPtr = reinterpret_cast<unsigned char*>(pbo->getOffset(image->getBufferIndex()));
#ifdef DO_TIMING
osg::notify(osg::NOTICE)<<"after PBO "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
#endif
}
else
{
pbo = 0;
osg::notify(osg::NOTICE)<<" no PixelBufferObject "<<image->getBufferObject()<<", "<<image->getPixelBufferObject()<<" pbo="<<pbo<<std::endl;
}
@@ -395,7 +383,7 @@ void TextureRectangle::applyTexImage_subload(GLenum target, Image* image, State&
image->s(), image->t(),
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
image->data() - dataMinusOffset + dataPlusOffset);
dataPtr);
}
else
{
@@ -404,7 +392,7 @@ void TextureRectangle::applyTexImage_subload(GLenum target, Image* image, State&
image->s(), image->t(),
(GLenum)image->getPixelFormat(),
(GLenum)image->getDataType(),
image->data() - dataMinusOffset + dataPlusOffset );
dataPtr);
}
if (pbo)
@@ -415,7 +403,6 @@ void TextureRectangle::applyTexImage_subload(GLenum target, Image* image, State&
#ifdef DO_TIMING
osg::notify(osg::NOTICE)<<"glTexSubImage2D "<<osg::Timer::instance()->delta_m(start_tick,osg::Timer::instance()->tick())<<"ms"<<std::endl;
#endif
}
void TextureRectangle::computeInternalFormat() const