Implementated new dirty buffer mechansim for BufferObjects to make it more efficient
This commit is contained in:
parent
efb52dfab9
commit
d625a5e114
@ -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; }
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,10 +690,11 @@ 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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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. ",
|
||||
"");
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user