Implementated new dirty buffer mechansim for BufferObjects to make it more efficient

This commit is contained in:
Robert Osfield 2007-04-30 12:18:27 +00:00
parent efb52dfab9
commit d625a5e114
11 changed files with 104 additions and 37 deletions

View File

@ -108,7 +108,7 @@ class OSG_EXPORT Array : public Object
virtual void trim() {}
/** Dirty the primitive, which increments the modified count, to force buffer objects to update. */
inline void dirty() { ++_modifiedCount; }
inline void dirty() { ++_modifiedCount; if (_vbo.valid()) _vbo->dirty(); }
/** Set the modified count value.*/
inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }

View File

@ -122,9 +122,18 @@ class OSG_EXPORT BufferObject : public Object
extensions->glBindBuffer(_target,0);
}
inline void dirty() { _compiledList.setAllElementsTo(0); }
bool isDirty(unsigned int contextID) const { return _compiledList[contextID]==0; }
virtual bool needsCompile(unsigned int contextID) const = 0;
virtual void compileBuffer(State& state) const = 0;
inline void compileBuffer(unsigned int contextID, State& state) const
{
if (isDirty(contextID)) compileBufferImplementation(state);
}
virtual void compileBufferImplementation(State& state) const = 0;
void releaseBuffer(State* state) const;
@ -215,8 +224,10 @@ class OSG_EXPORT BufferObject : public Object
virtual ~BufferObject();
typedef osg::buffered_value<GLuint> GLObjectList;
typedef osg::buffered_value<unsigned int> CompiledList;
mutable GLObjectList _bufferObjectList;
mutable CompiledList _compiledList;
GLenum _target;
GLenum _usage;
@ -248,7 +259,7 @@ class OSG_EXPORT VertexBufferObject : public BufferObject
virtual bool needsCompile(unsigned int contextID) const;
virtual void compileBuffer(State& state) const;
virtual void compileBufferImplementation(State& state) const;
protected:
@ -282,7 +293,7 @@ class OSG_EXPORT ElementsBufferObject : public BufferObject
virtual bool needsCompile(unsigned int contextID) const;
virtual void compileBuffer(State& state) const;
virtual void compileBufferImplementation(State& state) const;
protected:
@ -314,7 +325,7 @@ class OSG_EXPORT PixelBufferObject : public BufferObject
virtual bool needsCompile(unsigned int contextID) const;
virtual void compileBuffer(State& state) const;
virtual void compileBufferImplementation(State& state) const;
protected:

View File

@ -201,7 +201,7 @@ class OSG_EXPORT Image : public Object
void ensureValidSizeForTexturing(GLint maxTextureSize);
/** Dirty the image, which increments the modified count, to force osg::Texture to reload the image. */
inline void dirty() { ++_modifiedCount; }
inline void dirty() { ++_modifiedCount; if (_bufferObject.valid()) _bufferObject->dirty(); }
/** Set the modified count value. Used by osg::Texture when using texture subloading. */
inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }

View File

@ -241,7 +241,7 @@ class OSG_EXPORT PrimitiveSet : public Object
virtual unsigned int getNumPrimitives() const;
/** Dirty the primitive, which increments the modified count, to force buffer objects to update. */
inline void dirty() { ++_modifiedCount; }
virtual void dirty() { ++_modifiedCount; }
/** Set the modified count value.*/
inline void setModifiedCount(unsigned int value) { _modifiedCount=value; }
@ -423,6 +423,8 @@ class DrawElements : public PrimitiveSet
virtual DrawElements* getDrawElements() { return this; }
virtual const DrawElements* getDrawElements() const { return this; }
virtual void dirty() { ++_modifiedCount; if (_ebo.valid()) _ebo->dirty(); }
/** Set the ElementsBufferObject.*/
inline void setElementsBufferObject(osg::ElementsBufferObject* ebo)
{

View File

@ -308,6 +308,8 @@ unsigned int VertexBufferObject::addArray(osg::Array* array)
_bufferEntryArrayPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff);
_bufferEntryArrayPairs[i].first.offset = 0;
dirty();
return i;
}
@ -318,11 +320,13 @@ void VertexBufferObject::setArray(unsigned int i, Array* array)
_bufferEntryArrayPairs[i].second = array;
_bufferEntryArrayPairs[i].first.modifiedCount.setAllElementsTo(0xffffffff);
_bufferEntryArrayPairs[i].first.offset = 0;
dirty();
}
bool VertexBufferObject::needsCompile(unsigned int contextID) const
{
// return true;
if (isDirty(contextID)) return true;
unsigned int numValidArray = 0;
for(BufferEntryArrayPairs::const_iterator itr = _bufferEntryArrayPairs.begin();
@ -353,10 +357,11 @@ bool VertexBufferObject::needsCompile(unsigned int contextID) const
return false;
}
void VertexBufferObject::compileBuffer(State& state) const
void VertexBufferObject::compileBufferImplementation(State& state) const
{
unsigned int contextID = state.getContextID();
if (!needsCompile(contextID)) return;
_compiledList[contextID] = 1;
Extensions* extensions = getExtensions(contextID,true);
@ -500,6 +505,8 @@ void ElementsBufferObject::setDrawElements(unsigned int i, DrawElements* drawEle
bool ElementsBufferObject::needsCompile(unsigned int contextID) const
{
if (isDirty(contextID)) return true;
#if 1
unsigned int numValidDrawElements = 0;
for(BufferEntryDrawElementsPairs::const_iterator itr = _bufferEntryDrawElementsPairs.begin();
@ -531,10 +538,11 @@ bool ElementsBufferObject::needsCompile(unsigned int contextID) const
return false;
}
void ElementsBufferObject::compileBuffer(State& state) const
void ElementsBufferObject::compileBufferImplementation(State& state) const
{
unsigned int contextID = state.getContextID();
if (!needsCompile(contextID)) return;
_compiledList[contextID] = 1;
osg::notify(osg::NOTICE)<<"ElementsBufferObject::compile"<<std::endl;
@ -660,11 +668,17 @@ PixelBufferObject::~PixelBufferObject()
void PixelBufferObject::setImage(osg::Image* image)
{
if (_bufferEntryImagePair.second == image) return;
_bufferEntryImagePair.second = image;
dirty();
}
bool PixelBufferObject::needsCompile(unsigned int contextID) const
{
if (isDirty(contextID)) return true;
if (!_bufferEntryImagePair.second)
return false;
@ -676,11 +690,12 @@ bool PixelBufferObject::needsCompile(unsigned int contextID) const
return false;
}
void PixelBufferObject::compileBuffer(State& state) const
void PixelBufferObject::compileBufferImplementation(State& state) const
{
unsigned int contextID = state.getContextID();
if (!needsCompile(contextID)) return;
_compiledList[contextID] = 1;
osg::Image* image = _bufferEntryImagePair.second;
_bufferEntryImagePair.first.modifiedCount[contextID] = image->getModifiedCount();

View File

@ -1135,7 +1135,7 @@ osg::ElementsBufferObject* Geometry::getOrCreateElementsBufferObject()
void Geometry::setUseVertexBufferObjects(bool flag)
{
// flag = true;
flag = true;
// osg::notify(osg::NOTICE)<<"Geometry::setUseVertexBufferObjects("<<flag<<")"<<std::endl;
@ -1421,26 +1421,26 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
const VertexBufferObject* new_vbo = 0;
new_vbo = _vertexData.array.valid() ? _vertexData.array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
new_vbo = (_normalData.binding==BIND_PER_VERTEX && _normalData.array.valid()) ? _normalData.array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
new_vbo = (_colorData.binding==BIND_PER_VERTEX && _colorData.array.valid()) ? _colorData.array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
new_vbo = (_secondaryColorData.binding==BIND_PER_VERTEX && _secondaryColorData.array.valid()) ? _secondaryColorData.array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
new_vbo = (_fogCoordData.binding==BIND_PER_VERTEX && _fogCoordData.array.valid()) ? _fogCoordData.array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
unsigned int unit;
for(unit=0;unit<_texCoordList.size();++unit)
{
const Array* array = _texCoordList[unit].array.get();
new_vbo = array ? array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
}
if( handleVertexAttributes )
@ -1450,7 +1450,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
{
const Array* array = _vertexAttribList[index].array.get();
new_vbo = (_vertexAttribList[index].binding==BIND_PER_VERTEX && array) ? array->getVertexBufferObject() : 0;
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(state); prev_vbo = new_vbo; }
if (new_vbo && new_vbo!=prev_vbo) { new_vbo->compileBuffer(contextID, state); prev_vbo = new_vbo; }
}
}
@ -1531,7 +1531,7 @@ void Geometry::drawImplementation(RenderInfo& renderInfo) const
new_ebo = de->getElementsBufferObject();
if (new_ebo && new_ebo!=prev_ebo)
{
new_ebo->compileBuffer(state);
new_ebo->compileBuffer(contextID, state);
prev_ebo = new_ebo;
}
}

View File

@ -907,7 +907,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID) && !needImageRescale)
{
pbo->compileBuffer(state);
pbo->compileBuffer(contextID, state);
pbo->bindBuffer(contextID);
dataMinusOffset = data;
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset());
@ -1159,7 +1159,7 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID) && !needImageRescale)
{
pbo->compileBuffer(state);
pbo->compileBuffer(contextID, state);
pbo->bindBuffer(contextID);
dataMinusOffset = data;
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset());

View File

@ -285,7 +285,7 @@ void TextureRectangle::applyTexImage_load(GLenum target, Image* image, State& st
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID))
{
pbo->compileBuffer(state);
pbo->compileBuffer(contextID, state);
pbo->bindBuffer(contextID);
dataMinusOffset = image->data();
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset());
@ -352,7 +352,7 @@ void TextureRectangle::applyTexImage_subload(GLenum target, Image* image, State&
const PixelBufferObject* pbo = image->getPixelBufferObject();
if (pbo && pbo->isPBOSupported(contextID))
{
pbo->compileBuffer(state);
pbo->compileBuffer(contextID, state);
pbo->bindBuffer(contextID);
dataMinusOffset = image->data();
dataPlusOffset = reinterpret_cast<unsigned char*>(pbo->offset()); // -dataMinusOffset+dataPlusOffset

View File

@ -75,14 +75,29 @@ BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::BufferObject)
__void__unbindBuffer__unsigned_int,
"",
"");
I_Method0(void, dirty,
Properties::NON_VIRTUAL,
__void__dirty,
"",
"");
I_Method1(bool, isDirty, IN, unsigned int, contextID,
Properties::NON_VIRTUAL,
__bool__isDirty__unsigned_int,
"",
"");
I_Method1(bool, needsCompile, IN, unsigned int, contextID,
Properties::PURE_VIRTUAL,
__bool__needsCompile__unsigned_int,
"",
"");
I_Method1(void, compileBuffer, IN, osg::State &, state,
I_Method2(void, compileBuffer, IN, unsigned int, contextID, IN, osg::State &, state,
Properties::NON_VIRTUAL,
__void__compileBuffer__unsigned_int__State_R1,
"",
"");
I_Method1(void, compileBufferImplementation, IN, osg::State &, state,
Properties::PURE_VIRTUAL,
__void__compileBuffer__State_R1,
__void__compileBufferImplementation__State_R1,
"",
"");
I_Method1(void, releaseBuffer, IN, osg::State *, state,
@ -289,9 +304,9 @@ BEGIN_OBJECT_REFLECTOR(osg::ElementsBufferObject)
__bool__needsCompile__unsigned_int,
"",
"");
I_Method1(void, compileBuffer, IN, osg::State &, state,
I_Method1(void, compileBufferImplementation, IN, osg::State &, state,
Properties::VIRTUAL,
__void__compileBuffer__State_R1,
__void__compileBufferImplementation__State_R1,
"",
"");
I_IndexedProperty(osg::DrawElements *, DrawElements,
@ -363,9 +378,9 @@ BEGIN_OBJECT_REFLECTOR(osg::PixelBufferObject)
__bool__needsCompile__unsigned_int,
"",
"");
I_Method1(void, compileBuffer, IN, osg::State &, state,
I_Method1(void, compileBufferImplementation, IN, osg::State &, state,
Properties::VIRTUAL,
__void__compileBuffer__State_R1,
__void__compileBufferImplementation__State_R1,
"",
"");
I_SimpleProperty(osg::Image *, Image,
@ -441,9 +456,9 @@ BEGIN_OBJECT_REFLECTOR(osg::VertexBufferObject)
__bool__needsCompile__unsigned_int,
"",
"");
I_Method1(void, compileBuffer, IN, osg::State &, state,
I_Method1(void, compileBufferImplementation, IN, osg::State &, state,
Properties::VIRTUAL,
__void__compileBuffer__State_R1,
__void__compileBufferImplementation__State_R1,
"",
"");
I_IndexedProperty(osg::Array *, Array,

View File

@ -251,6 +251,11 @@ BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::DrawElements)
__C5_DrawElements_P1__getDrawElements,
"",
"");
I_Method0(void, dirty,
Properties::VIRTUAL,
__void__dirty,
"Dirty the primitive, which increments the modified count, to force buffer objects to update. ",
"");
I_Method1(void, setElementsBufferObject, IN, osg::ElementsBufferObject *, ebo,
Properties::NON_VIRTUAL,
__void__setElementsBufferObject__osg_ElementsBufferObject_P1,
@ -892,7 +897,7 @@ BEGIN_ABSTRACT_OBJECT_REFLECTOR(osg::PrimitiveSet)
"",
"");
I_Method0(void, dirty,
Properties::NON_VIRTUAL,
Properties::VIRTUAL,
__void__dirty,
"Dirty the primitive, which increments the modified count, to force buffer objects to update. ",
"");

View File

@ -28,6 +28,11 @@
#undef OUT
#endif
BEGIN_ENUM_REFLECTOR(osgTerrain::TerrainNode::Filter)
I_EnumLabel(osgTerrain::TerrainNode::NEAREST);
I_EnumLabel(osgTerrain::TerrainNode::LINEAR);
END_REFLECTOR
BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainNode)
I_BaseType(osg::Group);
I_Constructor0(____TerrainNode,
@ -147,10 +152,20 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainNode)
__C5_osg_TransferFunction_P1__getColorTransferFunction__unsigned_int,
"Get const color transfer function with specified layer number. ",
"");
I_Method2(void, setColorFilter, IN, unsigned int, i, IN, osgTerrain::TerrainNode::Filter, filter,
Properties::NON_VIRTUAL,
__void__setColorFilter__unsigned_int__Filter,
"Set a color filter with specified layer number. ",
"");
I_Method1(osgTerrain::TerrainNode::Filter, getColorFilter, IN, unsigned int, i,
Properties::NON_VIRTUAL,
__Filter__getColorFilter__unsigned_int,
"Set const color filter with specified layer number. ",
"");
I_Method0(unsigned int, getNumColorLayers,
Properties::NON_VIRTUAL,
__unsigned_int__getNumColorLayers,
"",
"Get the number of colour layers. ",
"");
I_Method1(void, setRequiresNormals, IN, bool, flag,
Properties::NON_VIRTUAL,
@ -167,6 +182,10 @@ BEGIN_OBJECT_REFLECTOR(osgTerrain::TerrainNode)
__osg_BoundingSphere__computeBound,
"Compute the bounding volume of the terrain by computing the union of the bounding volumes of all layers. ",
"");
I_IndexedProperty(osgTerrain::TerrainNode::Filter, ColorFilter,
__Filter__getColorFilter__unsigned_int,
__void__setColorFilter__unsigned_int__Filter,
0);
I_ArrayProperty(osgTerrain::Layer *, ColorLayer,
__Layer_P1__getColorLayer__unsigned_int,
__void__setColorLayer__unsigned_int__osgTerrain_Layer_P1,