Added support for releasing GLObjects, and renamed DisplayListVisitor the

GLObjectVisitor to better fit its function, and added support for releasing
objects as well as compiling them.
This commit is contained in:
Robert Osfield
2004-07-20 05:37:59 +00:00
parent 12a315ec1d
commit aa833acfd3
21 changed files with 214 additions and 73 deletions

View File

@@ -254,8 +254,11 @@ class SG_EXPORT Drawable : public Object
/** Immediately compile this drawable into an OpenGL Display List.
Note I, operation is ignored if _useDisplayList to false.
Note II, compile is not intended to be overridden in subclasses.*/
virtual void compile(State& state) const;
virtual void compileGLObjects(State& state) const;
/** release any OpenGL display lists associated with graphics context specified
in osg::State object is supplied, or release all display lists for all graphics contexts if state pointer is NULL*/
virtual void releaseGLObjects(State* state=0) const;
struct UpdateCallback : public virtual osg::Object
{

View File

@@ -201,7 +201,12 @@ class SG_EXPORT FragmentProgram : public StateAttribute
virtual void apply(State& state) const;
virtual void compile(State& state) const { apply(state); }
virtual void compileGLObjects(State& state) const { apply(state); }
/** release an OpenGL objects in specified graphics context if State
object is passed, otherwise release OpenGL objexts for all graphics context if
State object pointer NULL.*/
virtual void releaseGLObjects(State* state=0) const;
/** Extensions class which encapsulates the querring of extensions and
* associated function pointers, and provide convinience wrappers to

View File

@@ -229,7 +229,13 @@ class SG_EXPORT StateAttribute : public Object
virtual void apply(State&) const = 0;
/** default to nothing to compile - all state is applied immediately. */
virtual void compile(State&) const {}
virtual void compileGLObjects(State&) const {}
/** release an OpenGL objects in specified graphics context if State
object is passed, otherwise release OpenGL objexts for all graphics context if
State object pointer NULL.*/
virtual void releaseGLObjects(State* =0) const {}
protected:

View File

@@ -221,7 +221,10 @@ class SG_EXPORT StateSet : public Object
/** call compile on all StateAttributes contained within this StateSet.*/
void compile(State& state) const;
void compileGLObjects(State& state) const;
/** call release on all StateAttributes contained within this StateSet.*/
virtual void releaseGLObjects(State* state=0) const;
protected :

View File

@@ -319,7 +319,12 @@ class SG_EXPORT Texture : public osg::StateAttribute
virtual void apply(State& state) const = 0;
/** Calls apply(state) to compile the texture. */
virtual void compile(State& state) const;
virtual void compileGLObjects(State& state) const;
/** release an OpenGL objects in specified graphics context if State
object is passed, otherwise release OpenGL objexts for all graphics context if
State object pointer NULL.*/
virtual void releaseGLObjects(State* state=0) const;
/** Extensions class which encapsulates the querring of extensions and
* associated function pointers, and provide convinience wrappers to

View File

@@ -193,7 +193,12 @@ class SG_EXPORT VertexProgram : public StateAttribute
virtual void apply(State& state) const;
virtual void compile(State& state) const { apply(state); }
virtual void compileGLObjects(State& state) const { apply(state); }
/** release an OpenGL objects in specified graphics context if State
object is passed, otherwise release OpenGL objexts for all graphics context if
State object pointer NULL.*/
virtual void releaseGLObjects(State* state=0) const;
/** Extensions class which encapsulates the querring of extensions and
* associated function pointers, and provide convinience wrappers to

View File

@@ -140,6 +140,21 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
/** get whether the removed subgraphs should be deleted in the database thread or not.*/
bool getDeleteRemovedSubgraphsInDatabaseThread() const { return _deleteRemovedSubgraphsInDatabaseThread; }
/** set whether newly loaded textures should have their UnrefImageDataAfterApply set to a specified value.*/
void setUnrefImageDataAfterApplyPolicy(bool changeAutoUnRef, bool valueAutoUnRef) { _changeAutoUnRef = changeAutoUnRef; _valueAutoUnRef = valueAutoUnRef; }
/** get whether newly loaded textures should have their UnrefImageDataAfterApply set to a specified value.*/
void getUnrefImageDataAfterApplyPolicy(bool& changeAutoUnRef, bool& valueAutoUnRef) const { changeAutoUnRef = _changeAutoUnRef; valueAutoUnRef = _valueAutoUnRef; }
/** set whether newly loaded textures should have their MaxAnisotopy set to a specified value.*/
void setMaxAnisotropyPolicy(bool changeAnisotropy, float valueAnisotropy) { _changeAnisotropy = changeAnisotropy; _valueAnisotropy = valueAnisotropy; }
/** set whether newly loaded textures should have their MaxAnisotopy set to a specified value.*/
void getMaxAnisotropyPolicy(bool& changeAnisotropy, float& valueAnisotropy) const { changeAnisotropy = _changeAnisotropy; valueAnisotropy = _valueAnisotropy; }
/** Iterate through the active PagedLOD nodes children removing
* children which havn't been visited since specified expiryTime.
* note, should be only be called from the update thread. */
@@ -220,7 +235,11 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
DatabaseRequestList _dataToCompileList;
OpenThreads::Mutex _dataToCompileListMutex;
bool _changeAutoUnRef;
bool _valueAutoUnRef;
bool _changeAnisotropy;
float _valueAnisotropy;
bool _deleteRemovedSubgraphsInDatabaseThread;
ObjectList _childrenToDeleteList;

View File

@@ -86,7 +86,12 @@ class OSGGL2_EXPORT ProgramObject : public osg::StateAttribute
* be pending. */
virtual void apply(osg::State& state) const;
virtual void compile(osg::State& state) const { apply(state); }
virtual void compileGLObjects(osg::State& state) const { apply(state); }
/** release an OpenGL objects in specified graphics context if State
object is passed, otherwise release OpenGL objexts for all graphics context if
State object pointer NULL.*/
virtual void releaseGLObjects(osg::State* state=0) const;
// data access methods.

View File

@@ -25,8 +25,6 @@
#include <string>
//#define OSG_FONT_USE_LUMINANCE_ALPHA
namespace osgText {
class Font;

View File

@@ -11,8 +11,8 @@
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGUTIL_DISPLAYLISTVISITOR
#define OSGUTIL_DISPLAYLISTVISITOR 1
#ifndef OSGUTIL_GLOBJECTSVISITOR
#define OSGUTIL_GLOBJECTSVISITOR 1
#include <osg/NodeVisitor>
#include <osg/Geode>
@@ -26,7 +26,7 @@ namespace osgUtil {
* with option to immediately compile osg::Drawable OpenGL Display lists and
* osg::StateAttribute's.
*/
class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor
class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor
{
public:
@@ -36,7 +36,9 @@ class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor
SWITCH_ON_DISPLAY_LISTS = 0x1,
SWITCH_OFF_DISPLAY_LISTS = 0x2,
COMPILE_DISPLAY_LISTS = 0x4,
COMPILE_STATE_ATTRIBUTES = 0x8
COMPILE_STATE_ATTRIBUTES = 0x8,
RELEASE_DISPLAY_LISTS = 0x10,
RELEASE_STATE_ATTRIBUTES = 0x20
};
typedef unsigned int Mode;
@@ -45,7 +47,7 @@ class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor
* with set specified display list mode. Default mode is to
* gset->setUseDisplayList(true).
*/
DisplayListVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES);
GLObjectsVisitor(Mode mode=COMPILE_DISPLAY_LISTS|COMPILE_STATE_ATTRIBUTES);
/** Set the operational mode of how the visitor should set up osg::Drawable's.*/
void setMode(Mode mode) { _mode = mode; }
@@ -74,6 +76,9 @@ class OSGUTIL_EXPORT DisplayListVisitor : public osg::NodeVisitor
*/
virtual void apply(osg::Geode& node);
void apply(osg::Drawable& drawable);
void apply(osg::StateSet& stateset);
protected:
Mode _mode;

View File

@@ -199,7 +199,7 @@ void Drawable::dirtyBound()
}
}
void Drawable::compile(State& state) const
void Drawable::compileGLObjects(State& state) const
{
if (!_useDisplayList) return;
@@ -216,12 +216,6 @@ void Drawable::compile(State& state) const
glDeleteLists( globj, 1 );
}
if (_stateset.valid())
{
_stateset->compile(state);
}
globj = glGenLists( 1 );
glNewList( globj, GL_COMPILE );
@@ -234,6 +228,32 @@ void Drawable::compile(State& state) const
}
void Drawable::releaseGLObjects(State* state) const
{
if (!_useDisplayList) return;
if (state)
{
// get the contextID (user defined ID of 0 upwards) for the
// current OpenGL context.
unsigned int contextID = state->getContextID();
// get the globj for the current contextID.
GLuint& globj = _globjList[contextID];
// call the globj if already set otherwise comple and execute.
if( globj != 0 )
{
glDeleteLists( globj, 1 );
globj = 0;
}
}
else
{
const_cast<Drawable*>(this)->dirtyDisplayList();
}
}
void Drawable::setSupportsDisplayList(bool flag)
{
// if value unchanged simply return.

View File

@@ -177,6 +177,11 @@ void FragmentProgram::apply(State& state) const
}
}
void FragmentProgram::releaseGLObjects(State* state) const
{
const_cast<FragmentProgram*>(this)->dirtyFragmentProgramObject();
}
typedef buffered_value< ref_ptr<FragmentProgram::Extensions> > BufferedExtensions;
static BufferedExtensions s_extensions;

View File

@@ -190,6 +190,6 @@ void Geode::compileDrawables(State& state)
itr!=_drawables.end();
++itr)
{
(*itr)->compile(state);
(*itr)->compileGLObjects(state);
}
}

View File

@@ -752,13 +752,13 @@ const StateSet::RefAttributePair* StateSet::getTextureAttributePair(unsigned int
}
void StateSet::compile(State& state) const
void StateSet::compileGLObjects(State& state) const
{
for(AttributeList::const_iterator itr = _attributeList.begin();
itr!=_attributeList.end();
++itr)
{
itr->second.first->compile(state);
itr->second.first->compileGLObjects(state);
}
for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin();
@@ -769,7 +769,29 @@ void StateSet::compile(State& state) const
itr!=taitr->end();
++itr)
{
itr->second.first->compile(state);
itr->second.first->compileGLObjects(state);
}
}
}
void StateSet::releaseGLObjects(State* state) const
{
for(AttributeList::const_iterator itr = _attributeList.begin();
itr!=_attributeList.end();
++itr)
{
itr->second.first->releaseGLObjects(state);
}
for(TextureAttributeList::const_iterator taitr=_textureAttributeList.begin();
taitr!=_textureAttributeList.end();
++taitr)
{
for(AttributeList::const_iterator itr = taitr->begin();
itr!=taitr->end();
++itr)
{
itr->second.first->releaseGLObjects(state);
}
}
}

View File

@@ -1046,11 +1046,15 @@ void Texture::applyTexImage2D_subload(State& state, GLenum target, const Image*
#include <set>
void Texture::compile(State& state) const
void Texture::compileGLObjects(State& state) const
{
apply(state);
}
void Texture::releaseGLObjects(State* state) const
{
const_cast<Texture*>(this)->dirtyTextureObject();
}
typedef buffered_value< ref_ptr<Texture::Extensions> > BufferedExtensions;
static BufferedExtensions s_extensions;

View File

@@ -177,6 +177,11 @@ void VertexProgram::apply(State& state) const
}
}
void VertexProgram::releaseGLObjects(State* state) const
{
const_cast<VertexProgram*>(this)->dirtyVertexProgramObject();
}
typedef buffered_value< ref_ptr<VertexProgram::Extensions> > BufferedExtensions;
static BufferedExtensions s_extensions;

View File

@@ -28,6 +28,12 @@ DatabasePager::DatabasePager()
_threadPriorityDuringFrame = PRIORITY_MIN;
_threadPriorityOutwithFrame = PRIORITY_MIN;
_changeAutoUnRef = false;
_valueAutoUnRef = false;
_changeAnisotropy = false;
_valueAnisotropy = 1.0f;
#if 1
_deleteRemovedSubgraphsInDatabaseThread = true;
#else
@@ -209,11 +215,13 @@ void DatabasePager::signalEndFrame()
class FindCompileableGLObjectsVisitor : public osg::NodeVisitor
{
public:
FindCompileableGLObjectsVisitor(DatabasePager::DataToCompile& dataToCompile, bool unrefImageOnApply, bool clientStorageHint):
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_dataToCompile(dataToCompile),
_unrefImageOnApply(unrefImageOnApply),
_clientStorageHint(clientStorageHint)
FindCompileableGLObjectsVisitor(DatabasePager::DataToCompile& dataToCompile,
bool changeAutoUnRef, bool valueAutoUnRef,
bool changeAnisotropy, float valueAnisotropy):
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
_dataToCompile(dataToCompile),
_changeAutoUnRef(changeAutoUnRef), _valueAutoUnRef(valueAutoUnRef),
_changeAnisotropy(changeAnisotropy), _valueAnisotropy(valueAnisotropy)
{
}
@@ -247,8 +255,8 @@ public:
osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
if (texture)
{
texture->setUnRefImageDataAfterApply(_unrefImageOnApply);
//texture->setClientStorageHint(_clientStorageHint);
if (_changeAutoUnRef) texture->setUnRefImageDataAfterApply(_valueAutoUnRef);
if (_changeAnisotropy) texture->setMaxAnisotropy(_valueAnisotropy);
foundTextureState = true;
}
}
@@ -274,8 +282,10 @@ public:
}
DatabasePager::DataToCompile& _dataToCompile;
bool _unrefImageOnApply;
bool _clientStorageHint;
bool _changeAutoUnRef;
bool _valueAutoUnRef;
bool _changeAnisotropy;
float _valueAnisotropy;
};
@@ -367,7 +377,10 @@ void DatabasePager::run()
++itr;
// find all the compileable rendering objects
FindCompileableGLObjectsVisitor frov(dtc, true, true);
FindCompileableGLObjectsVisitor frov(dtc,
_changeAutoUnRef, _valueAutoUnRef,
_changeAnisotropy, _valueAnisotropy);
databaseRequest->_loadedModel->accept(frov);
if (!dtc.first.empty() || !dtc.second.empty())
@@ -499,7 +512,7 @@ public:
if ((*titr)->referenceCount()==1)
{
osg::Texture* texture = const_cast<osg::Texture*>(titr->get());
texture->dirtyTextureObject();
texture->releaseGLObjects();
objectsToDelete.push_back(texture);
}
}
@@ -511,7 +524,7 @@ public:
if ((*ditr)->referenceCount()==1)
{
osg::Drawable* drawable = const_cast<osg::Drawable*>(ditr->get());
drawable->dirtyDisplayList();
drawable->releaseGLObjects();
objectsToDelete.push_back(drawable);
}
}
@@ -725,7 +738,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
++itr)
{
//osg::notify(osg::INFO)<<" Compiling stateset "<<(*itr).get()<<std::endl;
(*itr)->compile(state);
(*itr)->compileGLObjects(state);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
// remove the compiled stateset from the list.
@@ -742,7 +755,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
++itr)
{
//osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl;
(*itr)->compile(state);
(*itr)->compileGLObjects(state);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
// remove the compiled drawables from the list.

View File

@@ -183,6 +183,11 @@ void ProgramObject::dirtyShaderObjects()
}
}
void ProgramObject::releaseGLObjects(osg::State* state) const
{
const_cast<ProgramObject*>(this)->dirtyShaderObjects();
}
void ProgramObject::addShader( ShaderObject* shadObj )
{

View File

@@ -10,13 +10,13 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgUtil/DisplayListVisitor>
#include <osgUtil/GLObjectsVisitor>
#include <osg/Drawable>
using namespace osg;
using namespace osgUtil;
DisplayListVisitor::DisplayListVisitor(Mode mode)
GLObjectsVisitor::GLObjectsVisitor(Mode mode)
{
setTraversalMode(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN);
@@ -26,55 +26,68 @@ DisplayListVisitor::DisplayListVisitor(Mode mode)
}
void DisplayListVisitor::apply(osg::Node& node)
void GLObjectsVisitor::apply(osg::Node& node)
{
if ((_mode&COMPILE_STATE_ATTRIBUTES) && node.getStateSet() && _state.valid())
if (node.getStateSet())
{
node.getStateSet()->compile(*_state);
apply(*(node.getStateSet()));
}
traverse(node);
}
void DisplayListVisitor::apply(osg::Geode& node)
void GLObjectsVisitor::apply(osg::Geode& node)
{
if (_mode&COMPILE_STATE_ATTRIBUTES && _state.valid())
if (node.getStateSet())
{
if (node.getStateSet())
{
node.getStateSet()->compile(*_state);
}
apply(*(node.getStateSet()));
}
for(unsigned int i=0;i<node.getNumDrawables();++i)
for(unsigned int i=0;i<node.getNumDrawables();++i)
{
Drawable* drawable = node.getDrawable(i);
if (drawable)
{
Drawable* drawable = node.getDrawable(i);
apply(*drawable);
if (drawable->getStateSet())
{
drawable->getStateSet()->compile(*_state);
apply(*(drawable->getStateSet()));
}
}
}
}
void GLObjectsVisitor::apply(osg::Drawable& drawable)
{
if (_mode&SWITCH_OFF_DISPLAY_LISTS)
{
for(unsigned int i=0;i<node.getNumDrawables();++i)
{
node.getDrawable(i)->setUseDisplayList(false);
}
drawable.setUseDisplayList(false);
}
if (_mode&SWITCH_ON_DISPLAY_LISTS)
{
for(unsigned int i=0;i<node.getNumDrawables();++i)
{
node.getDrawable(i)->setUseDisplayList(true);
}
drawable.setUseDisplayList(true);
}
if (_mode&COMPILE_DISPLAY_LISTS && _state.valid())
{
for(unsigned int i=0;i<node.getNumDrawables();++i)
{
node.getDrawable(i)->compile(*_state);
}
drawable.compileGLObjects(*_state);
}
if (_mode&RELEASE_DISPLAY_LISTS)
{
drawable.releaseGLObjects(_state.get());
}
}
void GLObjectsVisitor::apply(osg::StateSet& stateset)
{
if (_mode&COMPILE_STATE_ATTRIBUTES && _state.valid())
{
stateset.compileGLObjects(*_state);
}
if (_mode&RELEASE_STATE_ATTRIBUTES)
{
stateset.releaseGLObjects(_state.get());
}
}

View File

@@ -6,7 +6,7 @@ CXXFILES = \
CubeMapGenerator.cpp\
CullVisitor.cpp\
DelaunayTriangulator.cpp\
DisplayListVisitor.cpp\
GLObjectsVisitor.cpp\
DisplayRequirementsVisitor.cpp\
HalfWayMapGenerator.cpp\
HighlightMapGenerator.cpp\

View File

@@ -12,7 +12,7 @@
*/
#include <osgUtil/SceneView>
#include <osgUtil/UpdateVisitor>
#include <osgUtil/DisplayListVisitor>
#include <osgUtil/GLObjectsVisitor>
#include <osg/Timer>
#include <osg/Notify>
@@ -82,17 +82,17 @@ void SceneView::setDefaults()
_renderStage = new RenderStage;
DisplayListVisitor::Mode dlvMode = DisplayListVisitor::COMPILE_DISPLAY_LISTS|DisplayListVisitor::COMPILE_STATE_ATTRIBUTES;
GLObjectsVisitor::Mode dlvMode = GLObjectsVisitor::COMPILE_DISPLAY_LISTS|GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
#ifdef __sgi
dlvMode = DisplayListVisitor::COMPILE_STATE_ATTRIBUTES;
dlvMode = GLObjectsVisitor::COMPILE_STATE_ATTRIBUTES;
#endif
// sgi's IR graphics has a problem with lighting and display lists, as it seems to store
// lighting state with the display list, and the display list visitor doesn't currently apply
// state before creating display lists. So will disable the init visitor default, this won't
// affect functionality since the display lists will be created as and when needed.
DisplayListVisitor* dlv = new DisplayListVisitor(dlvMode);
GLObjectsVisitor* dlv = new GLObjectsVisitor(dlvMode);
dlv->setNodeMaskOverride(0xffffffff);
_initVisitor = dlv;
@@ -139,7 +139,7 @@ void SceneView::init()
_initVisitor->reset();
_initVisitor->setFrameStamp(_frameStamp.get());
DisplayListVisitor* dlv = dynamic_cast<DisplayListVisitor*>(_initVisitor.get());
GLObjectsVisitor* dlv = dynamic_cast<GLObjectsVisitor*>(_initVisitor.get());
if (dlv) dlv->setState(_state.get());
if (_frameStamp.valid())