Refactored the GL object deletion management to use new osg::GraphicsObjectManager/GLObjectManager base classes, and osg::ContextData container.

This approach unifies much of the code handling the clean up of OpenGL graphics data, avoids lots of local mutexes and static variables that were previously required,
and enables the clean up scheme to be easily extended by users providing their own GraphicsObjectManager subclasses.


git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@15130 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
Robert Osfield 2015-09-23 09:47:34 +00:00
parent cb3396b0e5
commit 161246d864
37 changed files with 1339 additions and 1374 deletions

View File

@ -20,6 +20,8 @@
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/ContextData>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgDB/FileNameUtils>
@ -504,7 +506,7 @@ protected:
optimizeVertexOrder = false;
reallocateMemory = false;
modifyTextureSettings = false;
buildImageMipmaps = false;
compressImages = false;
@ -524,21 +526,21 @@ protected:
bool optimizeVertexOrder;
bool reallocateMemory;
bool modifyTextureSettings;
bool buildImageMipmaps;
bool compressImages;
bool disableMipmaps;
};
//
//
class DatabasePagingOperation : public osg::Operation, public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
{
public:
DatabasePagingOperation(const std::string& filename,
const std::string& outputFilename,
SceneGraphProcessor* sceneGraphProcessor,
SceneGraphProcessor* sceneGraphProcessor,
osgUtil::IncrementalCompileOperation* ico):
osg::Referenced(true),
Operation("DatabasePaging Operation", false),
@ -570,7 +572,7 @@ public:
if (!_outputFilename.empty())
{
OSG_NOTICE<<"Writing out file "<<_outputFilename<<std::endl;
osgDB::writeNodeFile(*_loadedModel, _outputFilename);
}
@ -618,8 +620,7 @@ public:
{
if (ea.getKey()=='r')
{
osg::Texture::getTextureObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
osg::GLBufferObjectManager::getGLBufferObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
osg::getOrCreateContextData(0)->reportStats(osg::notify(osg::NOTICE));
}
}
return false;
@ -631,8 +632,7 @@ struct ReportStatsAnimationCompletedCallback : public osgGA::AnimationPathManipu
virtual void completed(const osgGA::AnimationPathManipulator*)
{
OSG_NOTICE<<"Animation completed"<<std::endl;
osg::Texture::getTextureObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
osg::GLBufferObjectManager::getGLBufferObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
osg::getOrCreateContextData(0)->reportStats(osg::notify(osg::NOTICE));
}
};
@ -664,7 +664,7 @@ int main(int argc, char** argv)
{
apm->setTimeScale(animationSpeed);
apm->setAnimationCompletedCallback(new ReportStatsAnimationCompletedCallback());
unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
keyswitchManipulator->selectMatrixManipulator(num);
@ -675,7 +675,7 @@ int main(int argc, char** argv)
viewer.setCameraManipulator( keyswitchManipulator.get() );
}
// set up event handlers
// set up event handlers
{
viewer.addEventHandler( new osgViewer::StatsHandler());
viewer.addEventHandler( new osgViewer::WindowSizeHandler() );
@ -797,7 +797,7 @@ int main(int argc, char** argv)
if (databasePagingOperation.get() && databasePagingOperation->_modelReadyToMerge)
{
OSG_NOTICE<<"Merging subgraph"<<std::endl;
timeOfLastMerge = currentTime;
group->removeChildren(0,group->getNumChildren());

View File

@ -28,6 +28,7 @@
#include <osg/Projection>
#include <osg/Switch>
#include <osg/Texture2D>
#include <osg/ContextData>
#include <osgDB/ReadFile>
#include <osgGA/GUIEventHandler>
@ -313,12 +314,9 @@ void destroyFBO(GraphicsContext* gc, FboData &data)
data.fb = 0;
data.resolveFB = 0;
State& state = *gc->getState();
double availableTime = 100.0;
RenderBuffer::flushDeletedRenderBuffers(state.getContextID(), 0.0,
availableTime);
availableTime = 100.0;
FrameBufferObject::flushDeletedFrameBufferObjects(state.getContextID(),
0.0, availableTime);
osg::get<GLRenderBufferManager>(state.getContextID())->flushAllDeletedGLObjects();
osg::get<GLFrameBufferObjectManager>(state.getContextID())->flushAllDeletedGLObjects();
}
void setAttachmentsFromConfig(Camera* camera, const FboConfig& config);

View File

@ -20,6 +20,7 @@
#include <osg/Object>
#include <osg/buffered_value>
#include <osg/FrameStamp>
#include <osg/GLObjects>
#include <iosfwd>
#include <list>
@ -151,7 +152,7 @@ class BufferObjectProfile
class GLBufferObjectSet;
class GLBufferObjectManager;
class OSG_EXPORT GLBufferObject : public Referenced
class OSG_EXPORT GLBufferObject : public GraphicsObject
{
public:
@ -207,6 +208,9 @@ class OSG_EXPORT GLBufferObject : public Referenced
_extensions->glBindBuffer(_profile._target,0);
}
/** release GLBufferObject to the orphan list to be reused or deleted.*/
void release();
inline bool isDirty() const { return _dirty; }
void dirty() { _dirty = true; }
@ -221,15 +225,6 @@ class OSG_EXPORT GLBufferObject : public Referenced
bool isPBOSupported() const { return _extensions->isPBOSupported; }
static osg::ref_ptr<GLBufferObject> createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject);
static void deleteAllBufferObjects(unsigned int contextID);
static void discardAllBufferObjects(unsigned int contextID);
static void flushAllDeletedBufferObjects(unsigned int contextID);
static void discardAllDeletedBufferObjects(unsigned int contextID);
static void flushDeletedBufferObjects(unsigned int contextID,double currentTime, double& availbleTime);
static void releaseGLBufferObject(unsigned int contextID, GLBufferObject* to);
bool hasAllBufferDataBeenRead() const;
void setBufferDataHasBeenRead(const osg::BufferData* bd);
@ -327,14 +322,11 @@ class OSG_EXPORT GLBufferObjectSet : public Referenced
GLBufferObject* _tail;
};
class OSG_EXPORT GLBufferObjectManager : public osg::Referenced
class OSG_EXPORT GLBufferObjectManager : public GraphicsObjectManager
{
public:
GLBufferObjectManager(unsigned int contextID);
unsigned int getContextID() const { return _contextID; }
void setNumberActiveGLBufferObjects(unsigned int size) { _numActiveGLBufferObjects = size; }
unsigned int& getNumberActiveGLBufferObjects() { return _numActiveGLBufferObjects; }
unsigned int getNumberActiveGLBufferObjects() const { return _numActiveGLBufferObjects; }
@ -357,12 +349,11 @@ class OSG_EXPORT GLBufferObjectManager : public osg::Referenced
void handlePendingOrphandedGLBufferObjects();
void deleteAllGLBufferObjects();
void discardAllGLBufferObjects();
void flushAllDeletedGLBufferObjects();
void discardAllDeletedGLBufferObjects();
void flushDeletedGLBufferObjects(double currentTime, double& availableTime);
void releaseGLBufferObject(GLBufferObject* to);
void deleteAllGLObjects();
void discardAllGLObjects();
void flushAllDeletedGLObjects();
void discardAllDeletedGLObjects();
void flushDeletedGLObjects(double currentTime, double& availableTime);
GLBufferObjectSet* getGLBufferObjectSet(const BufferObjectProfile& profile);
@ -383,12 +374,12 @@ class OSG_EXPORT GLBufferObjectManager : public osg::Referenced
unsigned int& getNumberApplied() { return _numApplied; }
double& getApplyTime() { return _applyTime; }
static osg::ref_ptr<GLBufferObjectManager>& getGLBufferObjectManager(unsigned int contextID);
protected:
virtual ~GLBufferObjectManager();
typedef std::map< BufferObjectProfile, osg::ref_ptr<GLBufferObjectSet> > GLBufferObjectSetMap;
unsigned int _contextID;
unsigned int _numActiveGLBufferObjects;
unsigned int _numOrphanedGLBufferObjects;
unsigned int _currGLBufferObjectPoolSize;
@ -471,11 +462,7 @@ class OSG_EXPORT BufferObject : public Object
GLBufferObject* getGLBufferObject(unsigned int contextID) const { return _glBufferObjects[contextID].get(); }
GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const
{
if (!_glBufferObjects[contextID]) _glBufferObjects[contextID] = GLBufferObject::createGLBufferObject(contextID, this);
return _glBufferObjects[contextID].get();
}
GLBufferObject* getOrCreateGLBufferObject(unsigned int contextID) const;
unsigned int computeRequiredBufferSize() const;

163
include/osg/ContextData Normal file
View File

@ -0,0 +1,163 @@
/* -*-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
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_CONTEXTDATA
#define OSG_CONTEXTDATA 1
#include <osg/GraphicsContext>
namespace osg {
class OSG_EXPORT ContextData : public GraphicsObjectManager
{
public:
ContextData(unsigned int contextID);
void incrementUsageCount() { ++_numContexts; }
void decrementUsageCount() { --_numContexts; }
void setNumContexts(unsigned int numContexts) { _numContexts = numContexts; }
unsigned int getNumContexts() const { return _numContexts; }
void setCompileContext(osg::GraphicsContext* gc) { _compileContext = gc; }
osg::GraphicsContext* getCompileContext() { return _compileContext.get(); }
/** Get a specific GL extensions object or GraphicsObjectManager, initialize if not already present.
* Note, must only be called from a the graphics context thread associated with this osg::State. */
template<typename T>
T* get()
{
const std::type_info* id(&typeid(T));
osg::ref_ptr<osg::Referenced>& ptr = _managerMap[id];
if (!ptr)
{
ptr = new T(_contextID);
}
return static_cast<T*>(ptr.get());
}
/** Get a specific GL extensions object or GraphicsObjectManager if it already exists in the extension map.
* Note, safe to call outwith a the graphics context thread associated with this osg::State.
* Returns NULL if the desired extension object has not been created yet.*/
template<typename T>
const T* get() const
{
const std::type_info* id(&typeid(T));
ManagerMap::const_iterator itr = _managerMap.find(id);
if (itr==_managerMap.end()) return 0;
else return itr->second.get();
}
/** Set a specific GL extensions object pr GraphicsObjectManager. */
template<typename T>
void set(T* ptr)
{
const std::type_info* id(&typeid(T));
_managerMap[id] = ptr;
}
/** Signal that a new frame has started.*/
virtual void newFrame(osg::FrameStamp*);
virtual void resetStats();
virtual void reportStats(std::ostream& out);
virtual void recomputeStats(std::ostream& out) const;
/** Flush all deleted OpenGL objects within the specified availableTime.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
virtual void flushDeletedGLObjects(double currentTime, double& availableTime);
/** Flush all deleted OpenGL objects.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
virtual void flushAllDeletedGLObjects();
/** Do a GL delete all OpenGL objects.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
virtual void deleteAllGLObjects();
/** Discard all OpenGL objects.
* Note, unlike deleteAllGLjects discard does not
* do any OpenGL calls so can be called from any thread, but as a consequence it
* also doesn't remove the associated OpenGL resource so discard should only be
* called when the associated graphics context is being/has been closed. */
virtual void discardAllGLObjects();
public:
/** Create a contextID for a new graphics context, this contextID is used to set up the osg::State associate with context.
* Automatically increments the usage count of the contextID to 1.*/
static unsigned int createNewContextID();
/** Get the current max ContextID.*/
static unsigned int getMaxContextID();
/** Increment the usage count associate with a contextID. The usage count specifies how many graphics contexts a specific contextID is shared between.*/
static void incrementContextIDUsageCount(unsigned int contextID);
/** Decrement the usage count associate with a contextID. Once the contextID goes to 0 the contextID is then free to be reused.*/
static void decrementContextIDUsageCount(unsigned int contextID);
typedef GraphicsContext::GraphicsContexts GraphicsContexts;
/** Get all the registered graphics contexts.*/
static GraphicsContexts getAllRegisteredGraphicsContexts();
/** Get all the registered graphics contexts associated with a specific contextID.*/
static GraphicsContexts getRegisteredGraphicsContexts(unsigned int contextID);
/** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
static void setCompileContext(unsigned int contextID, GraphicsContext* gc);
/** Get existing or create a new GraphicsContext to do background compilation for GraphicsContexts associated with specified contextID.*/
static GraphicsContext* getOrCreateCompileContext(unsigned int contextID);
/** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
static GraphicsContext* getCompileContext(unsigned int contextID);
/** Register a GraphicsContext.*/
static void registerGraphicsContext(GraphicsContext* gc);
/** Unregister a GraphicsContext.*/
static void unregisterGraphicsContext(GraphicsContext* gc);
protected:
virtual ~ContextData();
unsigned int _numContexts;
osg::ref_ptr<osg::GraphicsContext> _compileContext;
// ManagerMap contains GL Extentsions objects used by StateAttribue to call OpenGL extensions/advanced features
typedef std::map<const std::type_info*, osg::ref_ptr<osg::Referenced> > ManagerMap;
ManagerMap _managerMap;
};
/** Get the ContextData for a specific contextID.*/
extern ContextData* getContextData(unsigned int contextID);
/** Get or create the ContextData for a specific contextID.*/
extern ContextData* getOrCreateContextData(unsigned int contextID);
template<typename T>
inline T* get(unsigned int contextID)
{
ContextData* gc = getOrCreateContextData(contextID);
return gc->get<T>();
}
// specialize for ContextData to avoid ContextData being nested within itself.
template<> inline ContextData* get<ContextData>(unsigned int contextID) { return getOrCreateContextData(contextID); }
}
#endif

View File

@ -95,10 +95,6 @@ class OSG_EXPORT Drawable : public Node
{
public:
static unsigned int s_numberDrawablesReusedLastInLastFrame;
static unsigned int s_numberNewDrawablesInLastFrame;
static unsigned int s_numberDeletedDrawablesInLastFrame;
Drawable();
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
@ -355,31 +351,19 @@ class OSG_EXPORT Drawable : public Node
/** Return a OpenGL display list handle a newly generated or reused from display list cache. */
static GLuint generateDisplayList(unsigned int contextID, unsigned int sizeHint = 0);
/** Set the minimum number of display lists to retain in the deleted display list cache. */
static void setMinimumNumberOfDisplayListsToRetainInCache(unsigned int minimum);
/** Get the minimum number of display lists to retain in the deleted display list cache. */
static unsigned int getMinimumNumberOfDisplayListsToRetainInCache();
/** Use deleteDisplayList instead of glDeleteList to allow
* OpenGL display list to be cached until they can be deleted
* by the OpenGL context in which they were created, specified
* by contextID.*/
static void deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int sizeHint = 0);
/** Flush all the cached display list which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushAllDeletedDisplayLists(unsigned int contextID);
/** Set the minimum number of display lists to retain in the deleted display list cache. */
static void setMinimumNumberOfDisplayListsToRetainInCache(unsigned int minimum);
/** Get the minimum number of display lists to retain in the deleted display list cache. */
static unsigned int getMinimumNumberOfDisplayListsToRetainInCache();
/** Flush all the cached display list which need to be deleted
* in the OpenGL context related to contextID.
* Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
* this call is useful for when an OpenGL context has been destroyed. */
static void discardAllDeletedDisplayLists(unsigned int contextID);
/** Flush the cached display list which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedDisplayLists(unsigned int contextID,double& availableTime);
typedef unsigned int AttributeType;

View File

@ -202,26 +202,9 @@ class OSG_EXPORT FragmentProgram : public StateAttribute
/** Get list of Matrices */
inline const MatrixList& getMatrices() const { return _matrixList; }
/** Force a recompile on next apply() of associated OpenGL vertex program objects.*/
void dirtyFragmentProgramObject();
/** use deleteFragmentProgramObject instead of glDeletePrograms to allow
* OpenGL Fragment Program objects to be cached until they can be deleted
* by the OpenGL context in which they were created, specified
* by contextID.*/
static void deleteFragmentProgramObject(unsigned int contextID,GLuint handle);
/** flush all the cached fragment programs which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedFragmentProgramObjects(unsigned int contextID,double currentTime, double& availableTime);
/** discard all the cached fragment programs which need to be deleted
* in the OpenGL context related to contextID.
* Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
* this call is useful for when an OpenGL context has been destroyed. */
static void discardDeletedFragmentProgramObjects(unsigned int contextID);
virtual void apply(State& state) const;
virtual void compileGLObjects(State& state) const { apply(state); }

View File

@ -147,20 +147,6 @@ class OSG_EXPORT RenderBuffer: public Object
GLuint getObjectID(unsigned int contextID, const GLExtensions *ext) const;
inline int compare(const RenderBuffer &rb) const;
/** Mark internal RenderBuffer for deletion.
* Deletion requests are queued until they can be executed
* in the proper GL context. */
static void deleteRenderBuffer(unsigned int contextID, GLuint rb);
/** flush all the cached RenderBuffers which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedRenderBuffers(unsigned int contextID,double currentTime, double& availableTime);
/** discard all the cached RenderBuffers which need to be deleted in the OpenGL context related to contextID.
* Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
* this call is useful for when an OpenGL context has been destroyed. */
static void discardDeletedRenderBuffers(unsigned int contextID);
static int getMaxSamples(unsigned int contextID, const GLExtensions* ext);
/** Resize any per context GLObject buffers to specified size. */
@ -372,19 +358,6 @@ class OSG_EXPORT FrameBufferObject: public StateAttribute
/** Bind the FBO as either the read or draw target, or both. */
void apply(State &state, BindTarget target) const;
/** Mark internal FBO for deletion.
* Deletion requests are queued until they can be executed
* in the proper GL context. */
static void deleteFrameBufferObject(unsigned int contextID, GLuint program);
/** flush all the cached FBOs which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedFrameBufferObjects(unsigned int contextID,double currentTime, double& availableTime);
/** discard all the cached FBOs which need to be deleted
* in the OpenGL context related to contextID.*/
static void discardDeletedFrameBufferObjects(unsigned int contextID);
/** Resize any per context GLObject buffers to specified size. */
virtual void resizeGLObjectBuffers(unsigned int maxSize);
@ -413,30 +386,43 @@ class OSG_EXPORT FrameBufferObject: public StateAttribute
mutable buffered_value<int> _unsupported;
mutable buffered_value<GLuint> _fboID;
};
};
// INLINE METHODS
// INLINE METHODS
inline const FrameBufferObject::AttachmentMap &FrameBufferObject::getAttachmentMap() const
{
return _attachments;
}
inline const FrameBufferObject::AttachmentMap &FrameBufferObject::getAttachmentMap() const
{
return _attachments;
}
inline bool FrameBufferObject::hasAttachment(FrameBufferObject::BufferComponent attachment_point) const
{
return _attachments.find(attachment_point) != _attachments.end();
}
inline bool FrameBufferObject::hasAttachment(FrameBufferObject::BufferComponent attachment_point) const
{
return _attachments.find(attachment_point) != _attachments.end();
}
inline const FrameBufferAttachment &FrameBufferObject::getAttachment(FrameBufferObject::BufferComponent attachment_point) const
{
return _attachments.find(attachment_point)->second;
}
inline const FrameBufferAttachment &FrameBufferObject::getAttachment(FrameBufferObject::BufferComponent attachment_point) const
{
return _attachments.find(attachment_point)->second;
}
inline void FrameBufferObject::dirtyAll()
{
_dirtyAttachmentList.setAllElementsTo(1);
}
inline void FrameBufferObject::dirtyAll()
{
_dirtyAttachmentList.setAllElementsTo(1);
}
class OSG_EXPORT GLRenderBufferManager : public GLObjectManager
{
public:
GLRenderBufferManager(unsigned int contextID);
virtual void deleteGLObject(GLuint globj);
};
class OSG_EXPORT GLFrameBufferObjectManager : public GLObjectManager
{
public:
GLFrameBufferObjectManager(unsigned int contextID);
virtual void deleteGLObject(GLuint globj);
};
}

View File

@ -14,10 +14,16 @@
#ifndef OSG_GLOBJECTS
#define OSG_GLOBJECTS 1
#include <osg/Export>
#include <osg/Referenced>
#include <osg/GL>
#include <list>
#include <string>
namespace osg {
// forward declare
class FrameStamp;
/** Flush all deleted OpenGL objects within the specified availableTime.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
extern OSG_EXPORT void flushDeletedGLObjects(unsigned int contextID, double currentTime, double& availableTime);
@ -37,6 +43,90 @@ extern OSG_EXPORT void deleteAllGLObjects(unsigned int contextID);
* called when the associated graphics context is being/has been closed. */
extern OSG_EXPORT void discardAllGLObjects(unsigned int contextID);
class OSG_EXPORT GraphicsObject : public osg::Referenced
{
public:
GraphicsObject();
protected:
virtual ~GraphicsObject();
};
class OSG_EXPORT GraphicsObjectManager : public osg::Referenced
{
public:
GraphicsObjectManager(const std::string& name, unsigned int contextID);
unsigned int getContextID() const { return _contextID; }
/** Signal that a new frame has started.*/
virtual void newFrame(osg::FrameStamp* fs) {}
virtual void resetStats() {}
virtual void reportStats(std::ostream& out) {}
virtual void recomputeStats(std::ostream& out) const {}
/** Flush all deleted OpenGL objects within the specified availableTime.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
virtual void flushDeletedGLObjects(double currentTime, double& availableTime) = 0;
/** Flush all deleted OpenGL objects.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
virtual void flushAllDeletedGLObjects() = 0;
/** Do a GL delete all OpenGL objects.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
virtual void deleteAllGLObjects() = 0;
/** Discard all OpenGL objects.
* Note, unlike deleteAllGLjects discard does not
* do any OpenGL calls so can be called from any thread, but as a consequence it
* also doesn't remove the associated OpenGL resource so discard should only be
* called when the associated graphics context is being/has been closed. */
virtual void discardAllGLObjects() = 0;
protected:
virtual ~GraphicsObjectManager();
std::string _name;
unsigned int _contextID;
};
class OSG_EXPORT GLObjectManager : public GraphicsObjectManager
{
public:
GLObjectManager(const std::string& name, unsigned int contextID);
virtual void flushDeletedGLObjects(double currentTime, double& availableTime);
virtual void flushAllDeletedGLObjects();
virtual void deleteAllGLObjects();
virtual void discardAllGLObjects();
/** schedule a GL object for deletion by the graphics thread.*/
virtual void sheduleGLObjectForDeletion(GLuint globj);
/** implementation of the actual creation of an GL object - subclasses from GLObjectManager must implement the appropriate GL calls.*/
virtual GLuint createGLObject();
/** implementation of the actual deletion of an GL object - subclasses from GLObjectManager must implement the appropriate GL calls.*/
virtual void deleteGLObject(GLuint globj) = 0;
protected:
virtual ~GLObjectManager();
typedef std::list<GLuint> GLObjectHandleList;
OpenThreads::Mutex _mutex;
GLObjectHandleList _deleteGLObjectHandles;
};
}
#endif

View File

@ -228,21 +228,6 @@ class OSG_EXPORT Program : public osg::StateAttribute
/** Query InfoLog from a glProgram */
bool getGlProgramInfoLog(unsigned int contextID, std::string& log) const;
/** Mark internal glProgram for deletion.
* Deletion requests are queued until they can be executed
* in the proper GL context. */
static void deleteGlProgram(unsigned int contextID, GLuint program);
/** flush all the cached glPrograms which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedGlPrograms(unsigned int contextID,double currentTime, double& availableTime);
/** discard all the cached glPrograms which need to be deleted
* in the OpenGL context related to contextID.
* Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
* this call is useful for when an OpenGL context has been destroyed. */
static void discardDeletedGlPrograms(unsigned int contextID);
struct ActiveVarInfo {
ActiveVarInfo() : _location(-1), _type(Uniform::UNDEFINED), _size(-1) {}
ActiveVarInfo( GLint loc, GLenum type, GLint size ) : _location(loc), _type(type), _size(size) {}
@ -409,7 +394,7 @@ class OSG_EXPORT Program : public osg::StateAttribute
PerContextProgram& operator=(const PerContextProgram&); // disallowed
};
struct OSG_EXPORT ProgramObjects : public osg::Referenced
struct OSG_EXPORT ProgramObjects : public osg::GraphicsObject
{
typedef std::vector< osg::ref_ptr<PerContextProgram> > PerContextPrograms;

View File

@ -205,21 +205,6 @@ class OSG_EXPORT Shader : public osg::Object
/** If needed, compile the PCS's glShader */
void compileShader(osg::State& state) const;
/** Mark internal glShader for deletion.
* Deletion requests are queued until they can be executed
* in the proper GL context. */
static void deleteGlShader(unsigned int contextID, GLuint shader);
/** flush all the cached glShaders which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedGlShaders(unsigned int contextID,double currentTime, double& availableTime);
/** discard all the cached glShaders which need to be deleted in the OpenGL context related to contextID.
* Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
* this call is useful for when an OpenGL context has been destroyed. */
static void discardDeletedGlShaders(unsigned int contextID);
static Shader::Type getTypeId( const std::string& tname );
public:

View File

@ -155,7 +155,7 @@ class OSG_EXPORT State : public Referenced
typedef std::map<const std::type_info*, osg::ref_ptr<osg::Referenced> > ExtensionMap;
ExtensionMap _extensionMap;
/** Get a specific GL extensions object, initialize if not already present.
/** Get a specific GL extensions object or GraphicsObjectManager, initialize if not already present.
* Note, must only be called from a the graphics context thread associated with this osg::State. */
template<typename T>
T* get()
@ -169,7 +169,7 @@ class OSG_EXPORT State : public Referenced
return static_cast<T*>(ptr.get());
}
/** Get a specific GL extensions object if it already exists in the extension map.
/** Get a specific GL extensions object or GraphicsObjectManager if it already exists in the extension map.
* Note, safe to call outwith a the graphics context thread associated with this osg::State.
* Returns NULL if the desired extension object has not been created yet.*/
template<typename T>
@ -181,6 +181,13 @@ class OSG_EXPORT State : public Referenced
else return itr->second.get();
}
/** Set a specific GL extensions object pr GraphicsObjectManager. */
template<typename T>
void set(T* ptr)
{
const std::type_info* id(&typeid(T));
_extensionMap[id] = ptr;
}
/* Set whether shader composition is enabled.*/
void setShaderCompositionEnabled(bool flag) { _shaderCompositionEnabled = flag; }
@ -2945,6 +2952,7 @@ inline bool State::setActiveTextureUnit( unsigned int unit )
// forward declare speciailization of State::get() method
template<> inline GLExtensions* State::get<GLExtensions>() { return _glExtensions.get(); }
template<> inline const GLExtensions* State::get<GLExtensions>() const { return _glExtensions.get(); }
template<> inline void State::set<GLExtensions>(GLExtensions* ptr) { _glExtensions = ptr; }
}

View File

@ -405,9 +405,16 @@
#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
#endif
//#define OSG_COLLECT_TEXTURE_APPLIED_STATS 1
namespace osg {
// forward declare
class TextureObjectSet;
class TextureObjectManager;
/** Texture pure virtual base class that encapsulates OpenGL texture
* functionality common to the various types of OSG textures.
*/
@ -983,11 +990,7 @@ class OSG_EXPORT Texture : public osg::StateAttribute
unsigned int _size;
};
// forward declare
class TextureObjectSet;
class TextureObjectManager;
class OSG_EXPORT TextureObject : public osg::Referenced
class OSG_EXPORT TextureObject : public GraphicsObject
{
public:
@ -1068,6 +1071,8 @@ class OSG_EXPORT Texture : public osg::StateAttribute
inline bool isReusable() const { return _allocated && _profile._width!=0; }
/** release TextureObject to the orphan list to be reused or deleted.*/
void release();
GLuint _id;
TextureProfile _profile;
@ -1086,150 +1091,6 @@ class OSG_EXPORT Texture : public osg::StateAttribute
typedef std::list< ref_ptr<TextureObject> > TextureObjectList;
class OSG_EXPORT TextureObjectSet : public Referenced
{
public:
TextureObjectSet(TextureObjectManager* parent, const TextureProfile& profile);
const TextureProfile& getProfile() const { return _profile; }
void handlePendingOrphandedTextureObjects();
void deleteAllTextureObjects();
void discardAllTextureObjects();
void flushAllDeletedTextureObjects();
void discardAllDeletedTextureObjects();
void flushDeletedTextureObjects(double currentTime, double& availableTime);
osg::ref_ptr<TextureObject> takeFromOrphans(Texture* texture);
osg::ref_ptr<TextureObject> takeOrGenerate(Texture* texture);
void moveToBack(TextureObject* to);
void addToBack(TextureObject* to);
void orphan(TextureObject* to);
void remove(TextureObject* to);
void moveToSet(TextureObject* to, TextureObjectSet* set);
unsigned int size() const { return _profile._size * _numOfTextureObjects; }
bool makeSpace(unsigned int& size);
bool checkConsistency() const;
TextureObjectManager* getParent() { return _parent; }
unsigned int computeNumTextureObjectsInList() const;
unsigned int getNumOfTextureObjects() const { return _numOfTextureObjects; }
unsigned int getNumOrphans() const { return static_cast<unsigned int>(_orphanedTextureObjects.size()); }
unsigned int getNumPendingOrphans() const { return static_cast<unsigned int>(_pendingOrphanedTextureObjects.size()); }
protected:
virtual ~TextureObjectSet();
OpenThreads::Mutex _mutex;
TextureObjectManager* _parent;
unsigned int _contextID;
TextureProfile _profile;
unsigned int _numOfTextureObjects;
TextureObjectList _orphanedTextureObjects;
TextureObjectList _pendingOrphanedTextureObjects;
TextureObject* _head;
TextureObject* _tail;
};
class OSG_EXPORT TextureObjectManager : public osg::Referenced
{
public:
TextureObjectManager(unsigned int contextID);
unsigned int getContextID() const { return _contextID; }
void setNumberActiveTextureObjects(unsigned int size) { _numActiveTextureObjects = size; }
unsigned int& getNumberActiveTextureObjects() { return _numActiveTextureObjects; }
unsigned int getNumberActiveTextureObjects() const { return _numActiveTextureObjects; }
void setNumberOrphanedTextureObjects(unsigned int size) { _numOrphanedTextureObjects = size; }
unsigned int& getNumberOrphanedTextureObjects() { return _numOrphanedTextureObjects; }
unsigned int getNumberOrphanedTextureObjects() const { return _numOrphanedTextureObjects; }
void setCurrTexturePoolSize(unsigned int size) { _currTexturePoolSize = size; }
unsigned int& getCurrTexturePoolSize() { return _currTexturePoolSize; }
unsigned int getCurrTexturePoolSize() const { return _currTexturePoolSize; }
void setMaxTexturePoolSize(unsigned int size);
unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
bool hasSpace(unsigned int size) const { return (_currTexturePoolSize+size)<=_maxTexturePoolSize; }
bool makeSpace(unsigned int size);
osg::ref_ptr<TextureObject> generateTextureObject(const Texture* texture, GLenum target);
osg::ref_ptr<TextureObject> generateTextureObject(const Texture* texture,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
void handlePendingOrphandedTextureObjects();
void deleteAllTextureObjects();
void discardAllTextureObjects();
void flushAllDeletedTextureObjects();
void discardAllDeletedTextureObjects();
void flushDeletedTextureObjects(double currentTime, double& availableTime);
void releaseTextureObject(TextureObject* to);
TextureObjectSet* getTextureObjectSet(const TextureProfile& profile);
void newFrame(osg::FrameStamp* fs);
void resetStats();
void reportStats(std::ostream& out);
void recomputeStats(std::ostream& out) const;
bool checkConsistency() const;
unsigned int& getFrameNumber() { return _frameNumber; }
unsigned int& getNumberFrames() { return _numFrames; }
unsigned int& getNumberDeleted() { return _numDeleted; }
double& getDeleteTime() { return _deleteTime; }
unsigned int& getNumberGenerated() { return _numGenerated; }
double& getGenerateTime() { return _generateTime; }
unsigned int& getNumberApplied() { return _numApplied; }
double& getApplyTime() { return _applyTime; }
protected:
typedef std::map< TextureProfile, osg::ref_ptr<TextureObjectSet> > TextureSetMap;
unsigned int _contextID;
unsigned int _numActiveTextureObjects;
unsigned int _numOrphanedTextureObjects;
unsigned int _currTexturePoolSize;
unsigned int _maxTexturePoolSize;
TextureSetMap _textureSetMap;
unsigned int _frameNumber;
unsigned int _numFrames;
unsigned int _numDeleted;
double _deleteTime;
unsigned int _numGenerated;
double _generateTime;
unsigned int _numApplied;
double _applyTime;
};
static osg::ref_ptr<Texture::TextureObjectManager>& getTextureObjectManager(unsigned int contextID);
static osg::ref_ptr<TextureObject> generateTextureObject(const Texture* texture, unsigned int contextID,GLenum target);
@ -1254,13 +1115,6 @@ class OSG_EXPORT Texture : public osg::StateAttribute
GLsizei depth,
GLint border) const;
static void deleteAllTextureObjects(unsigned int contextID);
static void discardAllTextureObjects(unsigned int contextID);
static void flushAllDeletedTextureObjects(unsigned int contextID);
static void discardAllDeletedTextureObjects(unsigned int contextID);
static void flushDeletedTextureObjects(unsigned int contextID,double currentTime, double& availableTime);
static void releaseTextureObject(unsigned int contextID, TextureObject* to);
protected:
typedef buffered_object< ref_ptr<TextureObject> > TextureObjectBuffer;
@ -1269,6 +1123,139 @@ class OSG_EXPORT Texture : public osg::StateAttribute
};
class OSG_EXPORT TextureObjectSet : public Referenced
{
public:
TextureObjectSet(TextureObjectManager* parent, const Texture::TextureProfile& profile);
const Texture::TextureProfile& getProfile() const { return _profile; }
void handlePendingOrphandedTextureObjects();
void deleteAllTextureObjects();
void discardAllTextureObjects();
void flushAllDeletedTextureObjects();
void discardAllDeletedTextureObjects();
void flushDeletedTextureObjects(double currentTime, double& availableTime);
osg::ref_ptr<Texture::TextureObject> takeFromOrphans(Texture* texture);
osg::ref_ptr<Texture::TextureObject> takeOrGenerate(Texture* texture);
void moveToBack(Texture::TextureObject* to);
void addToBack(Texture::TextureObject* to);
void orphan(Texture::TextureObject* to);
void remove(Texture::TextureObject* to);
void moveToSet(Texture::TextureObject* to, TextureObjectSet* set);
unsigned int size() const { return _profile._size * _numOfTextureObjects; }
bool makeSpace(unsigned int& size);
bool checkConsistency() const;
TextureObjectManager* getParent() { return _parent; }
unsigned int computeNumTextureObjectsInList() const;
unsigned int getNumOfTextureObjects() const { return _numOfTextureObjects; }
unsigned int getNumOrphans() const { return static_cast<unsigned int>(_orphanedTextureObjects.size()); }
unsigned int getNumPendingOrphans() const { return static_cast<unsigned int>(_pendingOrphanedTextureObjects.size()); }
protected:
virtual ~TextureObjectSet();
OpenThreads::Mutex _mutex;
TextureObjectManager* _parent;
unsigned int _contextID;
Texture::TextureProfile _profile;
unsigned int _numOfTextureObjects;
Texture::TextureObjectList _orphanedTextureObjects;
Texture::TextureObjectList _pendingOrphanedTextureObjects;
Texture::TextureObject* _head;
Texture::TextureObject* _tail;
};
class OSG_EXPORT TextureObjectManager : public GraphicsObjectManager
{
public:
TextureObjectManager(unsigned int contextID);
void setNumberActiveTextureObjects(unsigned int size) { _numActiveTextureObjects = size; }
unsigned int& getNumberActiveTextureObjects() { return _numActiveTextureObjects; }
unsigned int getNumberActiveTextureObjects() const { return _numActiveTextureObjects; }
void setNumberOrphanedTextureObjects(unsigned int size) { _numOrphanedTextureObjects = size; }
unsigned int& getNumberOrphanedTextureObjects() { return _numOrphanedTextureObjects; }
unsigned int getNumberOrphanedTextureObjects() const { return _numOrphanedTextureObjects; }
void setCurrTexturePoolSize(unsigned int size) { _currTexturePoolSize = size; }
unsigned int& getCurrTexturePoolSize() { return _currTexturePoolSize; }
unsigned int getCurrTexturePoolSize() const { return _currTexturePoolSize; }
void setMaxTexturePoolSize(unsigned int size);
unsigned int getMaxTexturePoolSize() const { return _maxTexturePoolSize; }
bool hasSpace(unsigned int size) const { return (_currTexturePoolSize+size)<=_maxTexturePoolSize; }
bool makeSpace(unsigned int size);
osg::ref_ptr<Texture::TextureObject> generateTextureObject(const Texture* texture, GLenum target);
osg::ref_ptr<Texture::TextureObject> generateTextureObject(const Texture* texture,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
void handlePendingOrphandedTextureObjects();
void deleteAllGLObjects();
void discardAllGLObjects();
void flushAllDeletedGLObjects();
void discardAllDeletedGLObjects();
void flushDeletedGLObjects(double currentTime, double& availableTime);
TextureObjectSet* getTextureObjectSet(const Texture::TextureProfile& profile);
void newFrame(osg::FrameStamp* fs);
void resetStats();
void reportStats(std::ostream& out);
void recomputeStats(std::ostream& out) const;
bool checkConsistency() const;
unsigned int& getFrameNumber() { return _frameNumber; }
unsigned int& getNumberFrames() { return _numFrames; }
unsigned int& getNumberDeleted() { return _numDeleted; }
double& getDeleteTime() { return _deleteTime; }
unsigned int& getNumberGenerated() { return _numGenerated; }
double& getGenerateTime() { return _generateTime; }
protected:
~TextureObjectManager();
typedef std::map< Texture::TextureProfile, osg::ref_ptr<TextureObjectSet> > TextureSetMap;
unsigned int _numActiveTextureObjects;
unsigned int _numOrphanedTextureObjects;
unsigned int _currTexturePoolSize;
unsigned int _maxTexturePoolSize;
TextureSetMap _textureSetMap;
unsigned int _frameNumber;
unsigned int _numFrames;
unsigned int _numDeleted;
double _deleteTime;
unsigned int _numGenerated;
double _generateTime;
};
}
#endif

View File

@ -205,25 +205,6 @@ class OSG_EXPORT VertexProgram : public StateAttribute
/** Force a recompile on next apply() of associated OpenGL vertex program objects. */
void dirtyVertexProgramObject();
/** Use deleteVertexProgramObject instead of glDeletePrograms to allow
* OpenGL Vertex Program objects to cached until they can be deleted
* by the OpenGL context in which they were created, specified
* by contextID.
*/
static void deleteVertexProgramObject(unsigned int contextID,GLuint handle);
/** Flush all the cached vertex programs which need to be deleted
* in the OpenGL context related to contextID.
*/
static void flushDeletedVertexProgramObjects(unsigned int contextID,double currentTime, double& availableTime);
/** discard all the cached vertex programs which need to be deleted
* in the OpenGL context related to contextID.
* Note, unlike flush no OpenGL calls are made, instead the handles are all removed.
* this call is useful for when an OpenGL context has been destroyed.
*/
static void discardDeletedVertexProgramObjects(unsigned int contextID);
virtual void apply(State& state) const;
virtual void compileGLObjects(State& state) const { apply(state); }

View File

@ -19,13 +19,13 @@ FOREACH( mylibfolder
osgFX
osgManipulator
osgParticle
osgPresentation
osgUI
osgVolume
osgShadow
osgSim
osgTerrain
osgWidget
osgUI
osgVolume
osgPresentation
osgWrappers/serializers
osgWrappers/deprecated-dotosg
osgPlugins

View File

@ -24,6 +24,7 @@
#include <osg/State>
#include <osg/PrimitiveSet>
#include <osg/Array>
#include <osg/ContextData>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
@ -79,6 +80,11 @@ GLBufferObject::~GLBufferObject()
//OSG_NOTICE<<"Destructing BufferObject "<<this<<std::endl;
}
void GLBufferObject::release()
{
if (_set) _set->orphan(this);
}
void GLBufferObject::setBufferObject(BufferObject* bufferObject)
{
assign(bufferObject);
@ -844,7 +850,7 @@ unsigned int GLBufferObjectSet::computeNumGLBufferObjectsInList() const
GLBufferObjectManager::GLBufferObjectManager(unsigned int contextID):
_contextID(contextID),
GraphicsObjectManager("GLBufferObjectManager", contextID),
_numActiveGLBufferObjects(0),
_numOrphanedGLBufferObjects(0),
_currGLBufferObjectPoolSize(0),
@ -860,6 +866,10 @@ GLBufferObjectManager::GLBufferObjectManager(unsigned int contextID):
{
}
GLBufferObjectManager::~GLBufferObjectManager()
{
}
void GLBufferObjectManager::setMaxGLBufferObjectPoolSize(unsigned int size)
{
if (_maxGLBufferObjectPoolSize == size) return;
@ -915,7 +925,7 @@ void GLBufferObjectManager::handlePendingOrphandedGLBufferObjects()
}
}
void GLBufferObjectManager::deleteAllGLBufferObjects()
void GLBufferObjectManager::deleteAllGLObjects()
{
ElapsedTime elapsedTime(&(getDeleteTime()));
@ -927,7 +937,7 @@ void GLBufferObjectManager::deleteAllGLBufferObjects()
}
}
void GLBufferObjectManager::discardAllGLBufferObjects()
void GLBufferObjectManager::discardAllGLObjects()
{
for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin();
itr != _glBufferObjectSetMap.end();
@ -937,7 +947,7 @@ void GLBufferObjectManager::discardAllGLBufferObjects()
}
}
void GLBufferObjectManager::flushAllDeletedGLBufferObjects()
void GLBufferObjectManager::flushAllDeletedGLObjects()
{
ElapsedTime elapsedTime(&(getDeleteTime()));
@ -949,7 +959,7 @@ void GLBufferObjectManager::flushAllDeletedGLBufferObjects()
}
}
void GLBufferObjectManager::discardAllDeletedGLBufferObjects()
void GLBufferObjectManager::discardAllDeletedGLObjects()
{
for(GLBufferObjectSetMap::iterator itr = _glBufferObjectSetMap.begin();
itr != _glBufferObjectSetMap.end();
@ -959,7 +969,7 @@ void GLBufferObjectManager::discardAllDeletedGLBufferObjects()
}
}
void GLBufferObjectManager::flushDeletedGLBufferObjects(double currentTime, double& availableTime)
void GLBufferObjectManager::flushDeletedGLObjects(double currentTime, double& availableTime)
{
ElapsedTime elapsedTime(&(getDeleteTime()));
@ -971,13 +981,6 @@ void GLBufferObjectManager::flushDeletedGLBufferObjects(double currentTime, doub
}
}
void GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to)
{
if (to->_set) to->_set->orphan(to);
else OSG_NOTICE<<"GLBufferObjectManager::releaseGLBufferObject(GLBufferObject* to) Not implemented yet"<<std::endl;
}
void GLBufferObjectManager::newFrame(osg::FrameStamp* fs)
{
if (fs) _frameNumber = fs->getFrameNumber();
@ -1042,52 +1045,6 @@ void GLBufferObjectManager::recomputeStats(std::ostream& out)
out<<" getMaxGLBufferObjectPoolSize()="<<getMaxGLBufferObjectPoolSize()<<" current/max size = "<<double(currentSize)/double(getMaxGLBufferObjectPoolSize())<<std::endl;
}
osg::ref_ptr<GLBufferObjectManager>& GLBufferObjectManager::getGLBufferObjectManager(unsigned int contextID)
{
typedef osg::buffered_object< ref_ptr<GLBufferObjectManager> > GLBufferObjectManagerBuffer;
static GLBufferObjectManagerBuffer s_GLBufferObjectManager;
if (!s_GLBufferObjectManager[contextID]) s_GLBufferObjectManager[contextID] = new GLBufferObjectManager(contextID);
return s_GLBufferObjectManager[contextID];
}
osg::ref_ptr<GLBufferObject> GLBufferObject::createGLBufferObject(unsigned int contextID, const BufferObject* bufferObject)
{
return GLBufferObjectManager::getGLBufferObjectManager(contextID)->generateGLBufferObject(bufferObject);
}
void GLBufferObject::deleteAllBufferObjects(unsigned int contextID)
{
GLBufferObjectManager::getGLBufferObjectManager(contextID)->deleteAllGLBufferObjects();
}
void GLBufferObject::discardAllBufferObjects(unsigned int contextID)
{
GLBufferObjectManager::getGLBufferObjectManager(contextID)->discardAllGLBufferObjects();
}
void GLBufferObject::flushAllDeletedBufferObjects(unsigned int contextID)
{
GLBufferObjectManager::getGLBufferObjectManager(contextID)->flushAllDeletedGLBufferObjects();
}
void GLBufferObject::discardAllDeletedBufferObjects(unsigned int contextID)
{
GLBufferObjectManager::getGLBufferObjectManager(contextID)->discardAllDeletedGLBufferObjects();
}
void GLBufferObject::flushDeletedBufferObjects(unsigned int contextID,double currentTime, double& availbleTime)
{
GLBufferObjectManager::getGLBufferObjectManager(contextID)->flushDeletedGLBufferObjects(currentTime, availbleTime);
}
void GLBufferObject::releaseGLBufferObject(unsigned int contextID, GLBufferObject* to)
{
GLBufferObjectManager::getGLBufferObjectManager(contextID)->releaseGLBufferObject(to);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// BufferObject
@ -1108,6 +1065,11 @@ BufferObject::~BufferObject()
releaseGLObjects(0);
}
GLBufferObject* BufferObject::getOrCreateGLBufferObject(unsigned int contextID) const
{
if (!_glBufferObjects[contextID]) _glBufferObjects[contextID] = osg::get<GLBufferObjectManager>(contextID)->generateGLBufferObject(this);
return _glBufferObjects[contextID].get();
}
void BufferObject::setBufferData(unsigned int index, BufferData* bd)
{
@ -1136,7 +1098,7 @@ void BufferObject::releaseGLObjects(State* state) const
unsigned int contextID = state->getContextID();
if (_glBufferObjects[contextID].valid())
{
GLBufferObject::releaseGLBufferObject(contextID, _glBufferObjects[contextID].get());
_glBufferObjects[contextID]->release();
_glBufferObjects[contextID] = 0;
}
}
@ -1147,7 +1109,7 @@ void BufferObject::releaseGLObjects(State* state) const
if (_glBufferObjects[i].valid())
{
// OSG_NOTICE<<" GLBufferObject::releaseGLBufferObject("<<i<<", _glBufferObjects["<<i<<"]="<<_glBufferObjects[i].get()<<")"<<std::endl;
GLBufferObject::releaseGLBufferObject(i, _glBufferObjects[i].get());
_glBufferObjects[i]->release();
_glBufferObjects[i] = 0;
}
}
@ -1235,7 +1197,7 @@ void BufferObject::deleteBufferObject(unsigned int contextID,GLuint globj)
// implement deleteBufferObject for backwards compatibility by adding
// a GLBufferObject for the globj id to BufferObjectManager/Set for the specified context.
osg::ref_ptr<GLBufferObjectManager>& bufferObjectManager = GLBufferObjectManager::getGLBufferObjectManager(contextID);
GLBufferObjectManager* bufferObjectManager = osg::get<GLBufferObjectManager>(contextID);
if (!bufferObjectManager)
{
OSG_NOTICE<<"Warning::BufferObject::deleteBufferObject("<<contextID<<", "<<globj<<") unable to get GLBufferObjectManager for context."<<std::endl;

View File

@ -55,6 +55,7 @@ SET(TARGET_H
${HEADER_PATH}/ColorMaski
${HEADER_PATH}/ColorMatrix
${HEADER_PATH}/ComputeBoundsVisitor
${HEADER_PATH}/ContextData
${HEADER_PATH}/ConvexPlanarOccluder
${HEADER_PATH}/ConvexPlanarPolygon
${HEADER_PATH}/CoordinateSystemNode
@ -257,6 +258,7 @@ SET(TARGET_SRC
ColorMaski.cpp
ColorMatrix.cpp
ComputeBoundsVisitor.cpp
ContextData.cpp
ConvexPlanarOccluder.cpp
ConvexPlanarPolygon.cpp
CoordinateSystemNode.cpp

335
src/osg/ContextData.cpp Normal file
View File

@ -0,0 +1,335 @@
/* -*-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
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osg/ContextData>
#include <osg/FrameStamp>
#include <OpenThreads/ReentrantMutex>
#include <algorithm>
using namespace osg;
typedef std::map<unsigned int, osg::ref_ptr<ContextData> > ContextIDMap;
static ContextIDMap s_contextIDMap;
static OpenThreads::ReentrantMutex s_contextIDMapMutex;
static ContextData::GraphicsContexts s_registeredContexts;
ContextData::ContextData(unsigned int contextID):
GraphicsObjectManager("ContextData", contextID)
{
}
ContextData::~ContextData()
{
}
void ContextData::newFrame(osg::FrameStamp* frameStamp)
{
// OSG_NOTICE<<"ContextData::newFrame("<<frameStamp->getFrameNumber()<<")"<<std::endl;
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->newFrame(frameStamp);
}
}
void ContextData::resetStats()
{
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->resetStats();
}
}
void ContextData::reportStats(std::ostream& out)
{
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->reportStats(out);
}
}
void ContextData::recomputeStats(std::ostream& out) const
{
for(ManagerMap::const_iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->recomputeStats(out);
}
}
void ContextData::flushDeletedGLObjects(double currentTime, double& availableTime)
{
// OSG_NOTICE<<"ContextData::flushDeletedGLObjects("<<currentTime<<","<<availableTime<<")"<<std::endl;
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->flushDeletedGLObjects(currentTime, availableTime);
}
}
void ContextData::flushAllDeletedGLObjects()
{
// OSG_NOTICE<<"ContextData::flushAllDeletedGLObjects()"<<std::endl;
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->flushAllDeletedGLObjects();
}
}
void ContextData::deleteAllGLObjects()
{
// OSG_NOTICE<<"ContextData::deleteAllGLObjects()"<<std::endl;
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->deleteAllGLObjects();
}
}
void ContextData::discardAllGLObjects()
{
// OSG_NOTICE<<"ContextData::discardAllGLObjects()"<<std::endl;
for(ManagerMap::iterator itr = _managerMap.begin();
itr != _managerMap.end();
++itr)
{
osg::GraphicsObjectManager* gom = dynamic_cast<osg::GraphicsObjectManager*>(itr->second.get());
if (gom) gom->discardAllGLObjects();
}
}
ContextData* osg::getContextData(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
ContextIDMap::iterator itr = s_contextIDMap.find(contextID);
return (itr!=s_contextIDMap.end()) ? itr->second.get() : 0;
}
/** Get or create the ContextData for a specific contextID.*/
ContextData* osg::getOrCreateContextData(unsigned int contextID)
{
//OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
osg::ref_ptr<ContextData>& cd = s_contextIDMap[contextID];
if (!cd)
{
cd = new ContextData(contextID);
}
return cd.get();
}
unsigned int ContextData::createNewContextID()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
// first check to see if we can reuse contextID;
for(ContextIDMap::iterator itr = s_contextIDMap.begin();
itr != s_contextIDMap.end();
++itr)
{
if (!itr->second || itr->second->getNumContexts() == 0)
{
itr->second = new ContextData(itr->first);
itr->second->setNumContexts(1);
OSG_INFO<<"ContextData::createNewContextID() : reusing contextID="<<itr->first<<std::endl;
return itr->first;
}
}
unsigned int contextID = s_contextIDMap.size();
s_contextIDMap[contextID] = new ContextData(contextID);
s_contextIDMap[contextID]->setNumContexts(1);
OSG_INFO<<"ContextData::createNewContextID() creating contextID="<<contextID<<std::endl;
OSG_INFO<<"Updating the MaxNumberOfGraphicsContexts to "<<contextID+1<<std::endl;
// update the maximum number of graphics contexts,
// to ensure that texture objects and display buffers are configured to the correct size.
osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( contextID + 1 );
return contextID;
}
unsigned int ContextData::getMaxContextID()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
unsigned int maxContextID = 0;
for(ContextIDMap::iterator itr = s_contextIDMap.begin();
itr != s_contextIDMap.end();
++itr)
{
if (itr->first > maxContextID) maxContextID = itr->first;
}
return maxContextID;
}
void ContextData::incrementContextIDUsageCount(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (!s_contextIDMap[contextID]) s_contextIDMap[contextID] = new ContextData(contextID);
s_contextIDMap[contextID]->incrementUsageCount();
OSG_NOTICE<<"ContextData::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]->getNumContexts()<<std::endl;
}
void ContextData::decrementContextIDUsageCount(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[contextID].valid())
{
if (s_contextIDMap[contextID]->getNumContexts()!=0)
{
s_contextIDMap[contextID]->decrementUsageCount();
}
if (s_contextIDMap[contextID]->getNumContexts()==0)
{
s_contextIDMap[contextID] = 0;
}
}
}
void ContextData::registerGraphicsContext(GraphicsContext* gc)
{
OSG_INFO<<"ContextData::registerGraphicsContext "<<gc<<std::endl;
if (!gc) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(), s_registeredContexts.end(), gc);
if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
s_registeredContexts.push_back(gc);
}
void ContextData::unregisterGraphicsContext(GraphicsContext* gc)
{
OSG_INFO<<"ContextData::unregisterGraphicsContext "<<gc<<std::endl;
if (!gc) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(), s_registeredContexts.end(), gc);
if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
}
ContextData::GraphicsContexts ContextData::getAllRegisteredGraphicsContexts()
{
OSG_INFO<<"ContextData::getAllRegisteredGraphicsContexts s_registeredContexts.size()="<<s_registeredContexts.size()<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
return s_registeredContexts;
}
ContextData::GraphicsContexts ContextData::getRegisteredGraphicsContexts(unsigned int contextID)
{
GraphicsContexts contexts;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
for(GraphicsContexts::iterator itr = s_registeredContexts.begin();
itr != s_registeredContexts.end();
++itr)
{
GraphicsContext* gc = *itr;
if (gc->getState() && gc->getState()->getContextID()==contextID) contexts.push_back(gc);
}
OSG_INFO<<"ContextData::getRegisteredGraphicsContexts "<<contextID<<" contexts.size()="<<contexts.size()<<std::endl;
return contexts;
}
GraphicsContext* ContextData::getOrCreateCompileContext(unsigned int contextID)
{
OSG_NOTICE<<"ContextData::createCompileContext."<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[contextID]->getCompileContext()) return s_contextIDMap[contextID]->getCompileContext();
}
GraphicsContexts contexts = ContextData::getRegisteredGraphicsContexts(contextID);
if (contexts.empty()) return 0;
GraphicsContext* src_gc = contexts.front();
const osg::GraphicsContext::Traits* src_traits = src_gc->getTraits();
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
traits->screenNum = src_traits->screenNum;
traits->displayNum = src_traits->displayNum;
traits->hostName = src_traits->hostName;
traits->width = 100;
traits->height = 100;
traits->red = src_traits->red;
traits->green = src_traits->green;
traits->blue = src_traits->blue;
traits->alpha = src_traits->alpha;
traits->depth = src_traits->depth;
traits->sharedContext = src_gc;
traits->pbuffer = true;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits);
if (gc.valid() && gc->realize())
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID]->setCompileContext(gc.get());
OSG_NOTICE<<" succeeded ContextData::createCompileContext."<<std::endl;
return gc.release();
}
else
{
return 0;
}
}
void ContextData::setCompileContext(unsigned int contextID, GraphicsContext* gc)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID]->setCompileContext(gc);
}
GraphicsContext* ContextData::getCompileContext(unsigned int contextID)
{
// OSG_NOTICE<<"ContextData::getCompileContext "<<contextID<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
ContextIDMap::iterator itr = s_contextIDMap.find(contextID);
if (itr != s_contextIDMap.end()) return itr->second->getCompileContext();
else return 0;
}

View File

@ -21,6 +21,7 @@
#include <osg/GLExtensions>
#include <osg/Timer>
#include <osg/TriangleFunctor>
#include <osg/ContextData>
#include <osg/io_utils>
#include <algorithm>
@ -32,58 +33,7 @@
using namespace osg;
unsigned int Drawable::s_numberDrawablesReusedLastInLastFrame = 0;
unsigned int Drawable::s_numberNewDrawablesInLastFrame = 0;
unsigned int Drawable::s_numberDeletedDrawablesInLastFrame = 0;
// static cache of deleted display lists which can only
// by completely deleted once the appropriate OpenGL context
// is set. Used osg::Drawable::deleteDisplayList(..) and flushDeletedDisplayLists(..) below.
typedef std::multimap<unsigned int,GLuint> DisplayListMap;
typedef osg::buffered_object<DisplayListMap> DeletedDisplayListCache;
static OpenThreads::Mutex s_mutex_deletedDisplayListCache;
static DeletedDisplayListCache s_deletedDisplayListCache;
GLuint Drawable::generateDisplayList(unsigned int contextID, unsigned int sizeHint)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
DisplayListMap& dll = s_deletedDisplayListCache[contextID];
if (dll.empty())
{
++s_numberNewDrawablesInLastFrame;
return glGenLists( 1 );
}
else
{
DisplayListMap::iterator itr = dll.lower_bound(sizeHint);
if (itr!=dll.end())
{
// OSG_NOTICE<<"Reusing a display list of size = "<<itr->first<<" for requested size = "<<sizeHint<<std::endl;
++s_numberDrawablesReusedLastInLastFrame;
GLuint globj = itr->second;
dll.erase(itr);
return globj;
}
else
{
// OSG_NOTICE<<"Creating a new display list of size = "<<sizeHint<<" although "<<dll.size()<<" are available"<<std::endl;
++s_numberNewDrawablesInLastFrame;
return glGenLists( 1 );
}
}
#else
OSG_NOTICE<<"Warning: Drawable::generateDisplayList(..) - not supported."<<std::endl;
return 0;
#endif
}
unsigned int s_minimumNumberOfDisplayListsToRetainInCache = 0;
static unsigned int s_minimumNumberOfDisplayListsToRetainInCache = 0;
void Drawable::setMinimumNumberOfDisplayListsToRetainInCache(unsigned int minimum)
{
s_minimumNumberOfDisplayListsToRetainInCache = minimum;
@ -94,128 +44,205 @@ unsigned int Drawable::getMinimumNumberOfDisplayListsToRetainInCache()
return s_minimumNumberOfDisplayListsToRetainInCache;
}
void Drawable::deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int sizeHint)
class DisplayListManager : public GraphicsObjectManager
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
if (globj!=0)
public:
DisplayListManager(unsigned int contextID):
GraphicsObjectManager("DisplayListManager", contextID),
_numberDrawablesReusedLastInLastFrame(0),
_numberNewDrawablesInLastFrame(0),
_numberDeletedDrawablesInLastFrame(0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
// insert the globj into the cache for the appropriate context.
s_deletedDisplayListCache[contextID].insert(DisplayListMap::value_type(sizeHint,globj));
}
#else
OSG_NOTICE<<"Warning: Drawable::deleteDisplayList(..) - not supported."<<std::endl;
#endif
}
void Drawable::flushAllDeletedDisplayLists(unsigned int contextID)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
DisplayListMap& dll = s_deletedDisplayListCache[contextID];
for(DisplayListMap::iterator ditr=dll.begin();
ditr!=dll.end();
++ditr)
{
glDeleteLists(ditr->second,1);
}
dll.clear();
#else
OSG_NOTICE<<"Warning: Drawable::deleteDisplayList(..) - not supported."<<std::endl;
#endif
}
void Drawable::discardAllDeletedDisplayLists(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
DisplayListMap& dll = s_deletedDisplayListCache[contextID];
dll.clear();
}
void Drawable::flushDeletedDisplayLists(unsigned int contextID, double& availableTime)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
unsigned int noDeleted = 0;
virtual void flushDeletedGLObjects(double, double& availableTime)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedDisplayListCache);
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
// OSG_NOTICE<<"void DisplayListManager::flushDeletedGLObjects(, "<<availableTime<<")"<<std::endl;
DisplayListMap& dll = s_deletedDisplayListCache[contextID];
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
unsigned int noDeleted = 0;
bool trimFromFront = true;
if (trimFromFront)
{
unsigned int prev_size = dll.size();
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_deletedDisplayListCache);
DisplayListMap::iterator ditr=dll.begin();
unsigned int maxNumToDelete = (dll.size() > s_minimumNumberOfDisplayListsToRetainInCache) ? dll.size()-s_minimumNumberOfDisplayListsToRetainInCache : 0;
for(;
ditr!=dll.end() && elapsedTime<availableTime && noDeleted<maxNumToDelete;
++ditr)
bool trimFromFront = true;
if (trimFromFront)
{
glDeleteLists(ditr->second,1);
unsigned int prev_size = _displayListMap.size();
elapsedTime = timer.delta_s(start_tick,timer.tick());
++noDeleted;
DisplayListMap::iterator ditr=_displayListMap.begin();
unsigned int maxNumToDelete = (_displayListMap.size() > s_minimumNumberOfDisplayListsToRetainInCache) ? _displayListMap.size()-s_minimumNumberOfDisplayListsToRetainInCache : 0;
for(;
ditr!=_displayListMap.end() && elapsedTime<availableTime && noDeleted<maxNumToDelete;
++ditr)
{
glDeleteLists(ditr->second,1);
++Drawable::s_numberDeletedDrawablesInLastFrame;
}
elapsedTime = timer.delta_s(start_tick,timer.tick());
++noDeleted;
if (ditr!=dll.begin()) dll.erase(dll.begin(),ditr);
++_numberDeletedDrawablesInLastFrame;
}
if (noDeleted+dll.size() != prev_size)
{
OSG_WARN<<"Error in delete"<<std::endl;
}
if (ditr!=_displayListMap.begin()) _displayListMap.erase(_displayListMap.begin(),ditr);
if (noDeleted+_displayListMap.size() != prev_size)
{
OSG_WARN<<"Error in delete"<<std::endl;
}
}
else
{
unsigned int prev_size = _displayListMap.size();
DisplayListMap::reverse_iterator ditr=_displayListMap.rbegin();
unsigned int maxNumToDelete = (_displayListMap.size() > s_minimumNumberOfDisplayListsToRetainInCache) ? _displayListMap.size()-s_minimumNumberOfDisplayListsToRetainInCache : 0;
for(;
ditr!=_displayListMap.rend() && elapsedTime<availableTime && noDeleted<maxNumToDelete;
++ditr)
{
glDeleteLists(ditr->second,1);
elapsedTime = timer.delta_s(start_tick,timer.tick());
++noDeleted;
++_numberDeletedDrawablesInLastFrame;
}
if (ditr!=_displayListMap.rbegin()) _displayListMap.erase(ditr.base(),_displayListMap.end());
if (noDeleted+_displayListMap.size() != prev_size)
{
OSG_WARN<<"Error in delete"<<std::endl;
}
}
}
elapsedTime = timer.delta_s(start_tick,timer.tick());
if (noDeleted!=0) OSG_INFO<<"Number display lists deleted = "<<noDeleted<<" elapsed time"<<elapsedTime<<std::endl;
availableTime -= elapsedTime;
#else
OSG_NOTICE<<"Warning: Drawable::flushDeletedDisplayLists(..) - not supported."<<std::endl;
#endif
}
virtual void flushAllDeletedGLObjects()
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
OSG_NOTICE<<"void DisplayListManager::flushAllDeletedGLObjects()"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_deletedDisplayListCache);
for(DisplayListMap::iterator ditr=_displayListMap.begin();
ditr!=_displayListMap.end();
++ditr)
{
glDeleteLists(ditr->second,1);
}
_displayListMap.clear();
#else
OSG_NOTICE<<"Warning: Drawable::deleteDisplayList(..) - not supported."<<std::endl;
#endif
}
virtual void deleteAllGLObjects()
{
OSG_NOTICE<<"DisplayListManager::deleteAllGLObjects() Not currently implementated"<<std::endl;
}
virtual void discardAllGLObjects()
{
OSG_NOTICE<<"void DisplayListManager::discardAllGLObjects()"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_deletedDisplayListCache);
_displayListMap.clear();
}
void deleteDisplayList(GLuint globj, unsigned int sizeHint)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
if (globj!=0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_deletedDisplayListCache);
// insert the globj into the cache for the appropriate context.
_displayListMap.insert(DisplayListMap::value_type(sizeHint,globj));
}
#else
OSG_NOTICE<<"Warning: Drawable::deleteDisplayList(..) - not supported."<<std::endl;
#endif
}
GLuint generateDisplayList(unsigned int sizeHint)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex_deletedDisplayListCache);
if (_displayListMap.empty())
{
++_numberNewDrawablesInLastFrame;
return glGenLists( 1 );
}
else
{
unsigned int prev_size = dll.size();
DisplayListMap::reverse_iterator ditr=dll.rbegin();
unsigned int maxNumToDelete = (dll.size() > s_minimumNumberOfDisplayListsToRetainInCache) ? dll.size()-s_minimumNumberOfDisplayListsToRetainInCache : 0;
for(;
ditr!=dll.rend() && elapsedTime<availableTime && noDeleted<maxNumToDelete;
++ditr)
DisplayListMap::iterator itr = _displayListMap.lower_bound(sizeHint);
if (itr!=_displayListMap.end())
{
glDeleteLists(ditr->second,1);
// OSG_NOTICE<<"Reusing a display list of size = "<<itr->first<<" for requested size = "<<sizeHint<<std::endl;
elapsedTime = timer.delta_s(start_tick,timer.tick());
++noDeleted;
++_numberDrawablesReusedLastInLastFrame;
++Drawable::s_numberDeletedDrawablesInLastFrame;
}
GLuint globj = itr->second;
_displayListMap.erase(itr);
if (ditr!=dll.rbegin()) dll.erase(ditr.base(),dll.end());
if (noDeleted+dll.size() != prev_size)
{
OSG_WARN<<"Error in delete"<<std::endl;
}
return globj;
}
else
{
// OSG_NOTICE<<"Creating a new display list of size = "<<sizeHint<<" although "<<_displayListMap.size()<<" are available"<<std::endl;
++_numberNewDrawablesInLastFrame;
return glGenLists( 1 );
}
}
#else
OSG_NOTICE<<"Warning: Drawable::generateDisplayList(..) - not supported."<<std::endl;
return 0;
#endif
}
elapsedTime = timer.delta_s(start_tick,timer.tick());
if (noDeleted!=0) OSG_INFO<<"Number display lists deleted = "<<noDeleted<<" elapsed time"<<elapsedTime<<std::endl;
protected:
availableTime -= elapsedTime;
#else
OSG_NOTICE<<"Warning: Drawable::flushDeletedDisplayLists(..) - not supported."<<std::endl;
#endif
int _numberDrawablesReusedLastInLastFrame;
int _numberNewDrawablesInLastFrame;
int _numberDeletedDrawablesInLastFrame;
typedef std::multimap<unsigned int,GLuint> DisplayListMap;
OpenThreads::Mutex _mutex_deletedDisplayListCache;
DisplayListMap _displayListMap;
};
GLuint Drawable::generateDisplayList(unsigned int contextID, unsigned int sizeHint)
{
return osg::get<DisplayListManager>(contextID)->generateDisplayList(sizeHint);
}
void Drawable::deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int sizeHint)
{
osg::get<DisplayListManager>(contextID)->deleteDisplayList(globj, sizeHint);
}
bool Drawable::UpdateCallback::run(osg::Object* object, osg::Object* data)
{
osg::Drawable* drawable = dynamic_cast<osg::Drawable*>(object);

View File

@ -15,71 +15,21 @@
#include <osg/FragmentProgram>
#include <osg/State>
#include <osg/Timer>
#include <list>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
#include <osg/ContextData>
using namespace osg;
// static cache of deleted fragment programs which can only
// by completely deleted once the appropriate OpenGL context
// is set.
typedef std::list<GLuint> FragmentProgramObjectList;
typedef osg::buffered_object<FragmentProgramObjectList> DeletedFragmentProgramObjectCache;
static OpenThreads::Mutex s_mutex_deletedFragmentProgramObjectCache;
static DeletedFragmentProgramObjectCache s_deletedFragmentProgramObjectCache;
void FragmentProgram::deleteFragmentProgramObject(unsigned int contextID,GLuint handle)
class GLFragmentProgramManager : public GLObjectManager
{
if (handle!=0)
public:
GLFragmentProgramManager(unsigned int contextID) : GLObjectManager("GLFragmentProgramManager",contextID) {}
virtual void deleteGLObject(GLuint globj)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedFragmentProgramObjectCache);
// insert the handle into the cache for the appropriate context.
s_deletedFragmentProgramObjectCache[contextID].push_back(handle);
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeletePrograms(1, &globj );
}
}
void FragmentProgram::flushDeletedFragmentProgramObjects(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedFragmentProgramObjectCache);
const GLExtensions* extensions = GLExtensions::Get(contextID,true);
FragmentProgramObjectList& vpol = s_deletedFragmentProgramObjectCache[contextID];
for(FragmentProgramObjectList::iterator titr=vpol.begin();
titr!=vpol.end() && elapsedTime<availableTime;
)
{
extensions->glDeletePrograms( 1L, &(*titr ) );
titr = vpol.erase(titr);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
}
void FragmentProgram::discardDeletedFragmentProgramObjects(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedFragmentProgramObjectCache);
FragmentProgramObjectList& vpol = s_deletedFragmentProgramObjectCache[contextID];
vpol.clear();
}
};
FragmentProgram::FragmentProgram()
{
@ -117,7 +67,7 @@ void FragmentProgram::dirtyFragmentProgramObject()
{
if (_fragmentProgramIDList[i] != 0)
{
FragmentProgram::deleteFragmentProgramObject(i,_fragmentProgramIDList[i]);
osg::get<GLFragmentProgramManager>(i)->deleteGLObject(_fragmentProgramIDList[i]);
_fragmentProgramIDList[i] = 0;
}
}
@ -207,7 +157,7 @@ void FragmentProgram::releaseGLObjects(State* state) const
unsigned int contextID = state->getContextID();
if (_fragmentProgramIDList[contextID] != 0)
{
FragmentProgram::deleteFragmentProgramObject(contextID,_fragmentProgramIDList[contextID]);
osg::get<GLFragmentProgramManager>(contextID)->deleteGLObject(_fragmentProgramIDList[contextID]);
_fragmentProgramIDList[contextID] = 0;
}
}

View File

@ -24,73 +24,37 @@
#include <osg/TextureCubeMap>
#include <osg/TextureRectangle>
#include <osg/Notify>
#include <osg/ContextData>
#include <osg/Timer>
using namespace osg;
GLRenderBufferManager::GLRenderBufferManager(unsigned int contextID):
GLObjectManager("GLRenderBufferManager",contextID)
{}
void GLRenderBufferManager::deleteGLObject(GLuint globj)
{
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeleteRenderbuffers(1, &globj );
}
GLFrameBufferObjectManager::GLFrameBufferObjectManager(unsigned int contextID):
GLObjectManager("GLFrameBufferObjectManager",contextID)
{}
void GLFrameBufferObjectManager::deleteGLObject(GLuint globj)
{
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeleteFramebuffers(1, &globj );
}
/**************************************************************************
* RenderBuffer
**************************************************************************/
///////////////////////////////////////////////////////////////////////////
// static cache of glRenderbuffers flagged for deletion, which will actually
// be deleted in the correct GL context.
typedef std::list<GLuint> RenderBufferHandleList;
typedef osg::buffered_object<RenderBufferHandleList> DeletedRenderBufferCache;
static OpenThreads::Mutex s_mutex_deletedRenderBufferCache;
static DeletedRenderBufferCache s_deletedRenderBufferCache;
void RenderBuffer::deleteRenderBuffer(unsigned int contextID, GLuint rb)
{
if( rb )
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedRenderBufferCache);
// add glProgram to the cache for the appropriate context.
s_deletedRenderBufferCache[contextID].push_back(rb);
}
}
void RenderBuffer::flushDeletedRenderBuffers(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const GLExtensions* extensions = GLExtensions::Get(contextID,true);
if(!extensions || !extensions->isFrameBufferObjectSupported ) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedRenderBufferCache);
RenderBufferHandleList& pList = s_deletedRenderBufferCache[contextID];
for(RenderBufferHandleList::iterator titr=pList.begin();
titr!=pList.end() && elapsedTime<availableTime;
)
{
extensions->glDeleteRenderbuffers(1, &(*titr) );
titr = pList.erase( titr );
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
}
void RenderBuffer::discardDeletedRenderBuffers(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedRenderBufferCache);
RenderBufferHandleList& pList = s_deletedRenderBufferCache[contextID];
pList.clear();
}
RenderBuffer::RenderBuffer()
: Object(),
_internalFormat(GL_DEPTH_COMPONENT24),
@ -125,7 +89,7 @@ RenderBuffer::~RenderBuffer()
{
for(unsigned i=0; i<_objectID.size(); ++i)
{
if (_objectID[i]) deleteRenderBuffer(i, _objectID[i]);
if (_objectID[i]) osg::get<GLRenderBufferManager>(i)->deleteGLObject(_objectID[i]);
}
}
@ -209,7 +173,7 @@ void RenderBuffer::releaseGLObjects(osg::State* state) const
unsigned int contextID = state->getContextID();
if (_objectID[contextID])
{
deleteRenderBuffer(contextID, _objectID[contextID]);
osg::get<GLRenderBufferManager>(contextID)->deleteGLObject(_objectID[contextID]);
_objectID[contextID] = 0;
}
}
@ -219,7 +183,7 @@ void RenderBuffer::releaseGLObjects(osg::State* state) const
{
if (_objectID[i])
{
deleteRenderBuffer(i, _objectID[i]);
osg::get<GLRenderBufferManager>(i)->deleteGLObject(_objectID[i]);
_objectID[i] = 0;
}
}
@ -615,66 +579,6 @@ unsigned int FrameBufferAttachment::getTextureArrayLayer() const
* FrameBufferObject
**************************************************************************/
///////////////////////////////////////////////////////////////////////////
// static cache of glRenderbuffers flagged for deletion, which will actually
// be deleted in the correct GL context.
typedef std::list<GLuint> FrameBufferObjectHandleList;
typedef osg::buffered_object<FrameBufferObjectHandleList> DeletedFrameBufferObjectCache;
static OpenThreads::Mutex s_mutex_deletedFrameBufferObjectCache;
static DeletedFrameBufferObjectCache s_deletedFrameBufferObjectCache;
void FrameBufferObject::deleteFrameBufferObject(unsigned int contextID, GLuint rb)
{
if( rb )
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedFrameBufferObjectCache);
// add glProgram to the cache for the appropriate context.
s_deletedFrameBufferObjectCache[contextID].push_back(rb);
}
}
void FrameBufferObject::flushDeletedFrameBufferObjects(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const GLExtensions* extensions = GLExtensions::Get(contextID,true);
if(!extensions || !extensions->isFrameBufferObjectSupported ) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedFrameBufferObjectCache);
FrameBufferObjectHandleList& pList = s_deletedFrameBufferObjectCache[contextID];
for(FrameBufferObjectHandleList::iterator titr=pList.begin();
titr!=pList.end() && elapsedTime<availableTime;
)
{
extensions->glDeleteFramebuffers(1, &(*titr) );
titr = pList.erase( titr );
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
}
void FrameBufferObject::discardDeletedFrameBufferObjects(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedFrameBufferObjectCache);
FrameBufferObjectHandleList& pList = s_deletedFrameBufferObjectCache[contextID];
pList.clear();
}
FrameBufferObject::FrameBufferObject()
: StateAttribute()
{
@ -691,7 +595,7 @@ FrameBufferObject::~FrameBufferObject()
{
for(unsigned i=0; i<_fboID.size(); ++i)
{
if (_fboID[i]) deleteFrameBufferObject(i, _fboID[i]);
if (_fboID[i]) osg::get<GLFrameBufferObjectManager>(i)->deleteGLObject(_fboID[i]);
}
}
@ -709,7 +613,7 @@ void FrameBufferObject::releaseGLObjects(osg::State* state) const
unsigned int contextID = state->getContextID();
if (_fboID[contextID])
{
deleteFrameBufferObject(contextID, _fboID[contextID]);
osg::get<GLFrameBufferObjectManager>(contextID)->deleteGLObject(_fboID[contextID]);
_fboID[contextID] = 0;
}
}
@ -719,7 +623,7 @@ void FrameBufferObject::releaseGLObjects(osg::State* state) const
{
if (_fboID[i])
{
deleteFrameBufferObject(i, _fboID[i]);
osg::get<GLFrameBufferObjectManager>(i)->deleteGLObject(_fboID[i]);
_fboID[i] = 0;
}
}

View File

@ -12,102 +12,139 @@
*/
#include <osg/GLObjects>
#include <osg/Texture>
#include <osg/VertexProgram>
#include <osg/FragmentProgram>
#include <osg/Shader>
#include <osg/BufferObject>
#include <osg/FrameBufferObject>
#include <osg/Drawable>
#include <osg/OcclusionQueryNode>
#include <osg/ContextData>
using namespace osg;
void osg::flushDeletedGLObjects(unsigned int contextID, double currentTime, double& availableTime)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
osg::Drawable::flushDeletedDisplayLists(contextID,availableTime);
#endif
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(contextID,currentTime,availableTime);
#endif
osg::GLBufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(contextID,currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(contextID,currentTime,availableTime);
osg::Texture::flushDeletedTextureObjects(contextID,currentTime,availableTime);
osg::OcclusionQueryNode::flushDeletedQueryObjects(contextID,currentTime,availableTime);
osg::getContextData(contextID)->flushDeletedGLObjects(currentTime, availableTime);
}
void osg::flushAllDeletedGLObjects(unsigned int contextID)
{
double currentTime = DBL_MAX;
double availableTime = DBL_MAX;
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
osg::Drawable::flushAllDeletedDisplayLists(contextID);
#endif
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(contextID,currentTime,availableTime);
#endif
osg::GLBufferObject::flushAllDeletedBufferObjects(contextID);
osg::Texture::flushAllDeletedTextureObjects(contextID);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(contextID,currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(contextID,currentTime,availableTime);
osg::OcclusionQueryNode::flushDeletedQueryObjects(contextID,currentTime,availableTime);
osg::getContextData(contextID)->flushAllDeletedGLObjects();
}
void osg::deleteAllGLObjects(unsigned int contextID)
{
double currentTime = DBL_MAX;
double availableTime = DBL_MAX;
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
osg::Drawable::flushAllDeletedDisplayLists(contextID);
#endif
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(contextID,currentTime,availableTime);
#endif
osg::GLBufferObject::deleteAllBufferObjects(contextID);
osg::Texture::deleteAllTextureObjects(contextID);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(contextID,currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(contextID,currentTime,availableTime);
osg::OcclusionQueryNode::flushDeletedQueryObjects(contextID,currentTime,availableTime);
osg::getContextData(contextID)->deleteAllGLObjects();
}
void osg::discardAllGLObjects(unsigned int contextID)
{
#ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
osg::Drawable::discardAllDeletedDisplayLists(contextID);
#endif
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
osg::FragmentProgram::discardDeletedFragmentProgramObjects(contextID);
osg::VertexProgram::discardDeletedVertexProgramObjects(contextID);
#endif
osg::GLBufferObject::discardAllBufferObjects(contextID);
osg::Texture::discardAllTextureObjects(contextID);
osg::FrameBufferObject::discardDeletedFrameBufferObjects(contextID);
osg::Program::discardDeletedGlPrograms(contextID);
osg::RenderBuffer::discardDeletedRenderBuffers(contextID);
osg::Shader::discardDeletedGlShaders(contextID);
osg::OcclusionQueryNode::discardDeletedQueryObjects(contextID);
osg::getContextData(contextID)->discardAllGLObjects();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// GraphicsObject
//
GraphicsObject::GraphicsObject()
{
// OSG_NOTICE<<"GraphicsObject::GraphicsObject() "<<this<<std::endl;
}
GraphicsObject::~GraphicsObject()
{
// OSG_NOTICE<<"GraphicsObject::~GraphicsObject() "<<this<<std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// GraphicsObjectManager
//
GraphicsObjectManager::GraphicsObjectManager(const std::string& name, unsigned int contextID):
_name(name),
_contextID(contextID)
{
OSG_INFO<<_name<<"::"<<_name<<"()"<<this<<std::endl;
}
GraphicsObjectManager::~GraphicsObjectManager()
{
OSG_INFO<<_name<<"::~"<<_name<<"()"<<this<<std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// GLObjectManager
//
GLObjectManager::GLObjectManager(const std::string& name, unsigned int contextID):
GraphicsObjectManager(name, contextID)
{
}
GLObjectManager::~GLObjectManager()
{
}
void GLObjectManager::flushDeletedGLObjects(double, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
for(GLObjectHandleList::iterator itr = _deleteGLObjectHandles.begin();
itr != _deleteGLObjectHandles.end() && elapsedTime<availableTime;
)
{
deleteGLObject( *itr );
itr = _deleteGLObjectHandles.erase( itr );
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
availableTime -= elapsedTime;
}
void GLObjectManager::flushAllDeletedGLObjects()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
for(GLObjectHandleList::iterator itr = _deleteGLObjectHandles.begin();
itr != _deleteGLObjectHandles.end();
++itr)
{
deleteGLObject( *itr );
}
_deleteGLObjectHandles.clear();
}
void GLObjectManager::deleteAllGLObjects()
{
OSG_INFO<<"void "<<_name<<"::deleteAllGLObjects() : Not Implementated"<<std::endl;
}
void GLObjectManager::discardAllGLObjects()
{
// OSG_NOTICE<<"void "<<_name<<"::discardAllGLObjects()"<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
_deleteGLObjectHandles.clear();
}
void GLObjectManager::sheduleGLObjectForDeletion(GLuint globj)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
// add glProgram to the cache for the appropriate context.
_deleteGLObjectHandles.push_back(globj);
}
GLuint GLObjectManager::createGLObject()
{
OSG_INFO<<"void "<<_name<<"::createGLObject() : Not Implementated"<<std::endl;
return 0;
}

View File

@ -17,6 +17,7 @@
#include <osg/Camera>
#include <osg/View>
#include <osg/GLObjects>
#include <osg/ContextData>
#include <osg/FrameBufferObject>
#include <osg/Program>
@ -232,7 +233,7 @@ bool GraphicsContext::Traits::getContextVersion(unsigned int& major, unsigned in
return true;
}
#if 0
class ContextData
{
public:
@ -261,197 +262,63 @@ public:
osg::ref_ptr<osg::GraphicsContext> _compileContext;
};
typedef std::map<unsigned int, ContextData> ContextIDMap;
static ContextIDMap s_contextIDMap;
static OpenThreads::ReentrantMutex s_contextIDMapMutex;
static GraphicsContext::GraphicsContexts s_registeredContexts;
#endif
unsigned int GraphicsContext::createNewContextID()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
// first check to see if we can reuse contextID;
for(ContextIDMap::iterator itr = s_contextIDMap.begin();
itr != s_contextIDMap.end();
++itr)
{
if (itr->second._numContexts == 0)
{
// reuse contextID;
itr->second._numContexts = 1;
OSG_INFO<<"GraphicsContext::createNewContextID() reusing contextID="<<itr->first<<std::endl;
return itr->first;
}
}
unsigned int contextID = s_contextIDMap.size();
s_contextIDMap[contextID]._numContexts = 1;
OSG_INFO<<"GraphicsContext::createNewContextID() creating contextID="<<contextID<<std::endl;
OSG_INFO<<"Updating the MaxNumberOfGraphicsContexts to "<<contextID+1<<std::endl;
// update the maximum number of graphics contexts,
// to ensure that texture objects and display buffers are configured to the correct size.
osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( contextID + 1 );
return contextID;
return ContextData::createNewContextID();
}
unsigned int GraphicsContext::getMaxContextID()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
unsigned int maxContextID = 0;
for(ContextIDMap::iterator itr = s_contextIDMap.begin();
itr != s_contextIDMap.end();
++itr)
{
if (itr->first > maxContextID) maxContextID = itr->first;
}
return maxContextID;
return ContextData::getMaxContextID();
}
void GraphicsContext::incrementContextIDUsageCount(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID].incrementUsageCount();
OSG_INFO<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
return ContextData::incrementContextIDUsageCount(contextID);
}
void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[contextID]._numContexts!=0)
{
s_contextIDMap[contextID].decrementUsageCount();
}
else
{
OSG_NOTICE<<"Warning: decrementContextIDUsageCount("<<contextID<<") called on expired contextID."<<std::endl;
}
OSG_INFO<<"GraphicsContext::decrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
return ContextData::decrementContextIDUsageCount(contextID);
}
void GraphicsContext::registerGraphicsContext(GraphicsContext* gc)
{
OSG_INFO<<"GraphicsContext::registerGraphicsContext "<<gc<<std::endl;
if (!gc) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(), s_registeredContexts.end(), gc);
if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
s_registeredContexts.push_back(gc);
ContextData::registerGraphicsContext(gc);
}
void GraphicsContext::unregisterGraphicsContext(GraphicsContext* gc)
{
OSG_INFO<<"GraphicsContext::unregisterGraphicsContext "<<gc<<std::endl;
if (!gc) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(), s_registeredContexts.end(), gc);
if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
ContextData::unregisterGraphicsContext(gc);
}
GraphicsContext::GraphicsContexts GraphicsContext::getAllRegisteredGraphicsContexts()
{
OSG_INFO<<"GraphicsContext::getAllRegisteredGraphicsContexts s_registeredContexts.size()="<<s_registeredContexts.size()<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
return s_registeredContexts;
return ContextData::getAllRegisteredGraphicsContexts();
}
GraphicsContext::GraphicsContexts GraphicsContext::getRegisteredGraphicsContexts(unsigned int contextID)
{
GraphicsContexts contexts;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
for(GraphicsContexts::iterator itr = s_registeredContexts.begin();
itr != s_registeredContexts.end();
++itr)
{
GraphicsContext* gc = *itr;
if (gc->getState() && gc->getState()->getContextID()==contextID) contexts.push_back(gc);
}
OSG_INFO<<"GraphicsContext::getRegisteredGraphicsContexts "<<contextID<<" contexts.size()="<<contexts.size()<<std::endl;
return contexts;
return ContextData::getRegisteredGraphicsContexts(contextID);
}
GraphicsContext* GraphicsContext::getOrCreateCompileContext(unsigned int contextID)
{
OSG_NOTICE<<"GraphicsContext::createCompileContext."<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[contextID]._compileContext.valid()) return s_contextIDMap[contextID]._compileContext.get();
}
GraphicsContext::GraphicsContexts contexts = GraphicsContext::getRegisteredGraphicsContexts(contextID);
if (contexts.empty()) return 0;
GraphicsContext* src_gc = contexts.front();
const osg::GraphicsContext::Traits* src_traits = src_gc->getTraits();
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
traits->screenNum = src_traits->screenNum;
traits->displayNum = src_traits->displayNum;
traits->hostName = src_traits->hostName;
traits->width = 100;
traits->height = 100;
traits->red = src_traits->red;
traits->green = src_traits->green;
traits->blue = src_traits->blue;
traits->alpha = src_traits->alpha;
traits->depth = src_traits->depth;
traits->sharedContext = src_gc;
traits->pbuffer = true;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits);
if (gc.valid() && gc->realize())
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID]._compileContext = gc;
OSG_NOTICE<<" succeeded GraphicsContext::createCompileContext."<<std::endl;
return gc.release();
}
else
{
return 0;
}
return ContextData::getOrCreateCompileContext(contextID);
}
void GraphicsContext::setCompileContext(unsigned int contextID, GraphicsContext* gc)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID]._compileContext = gc;
return ContextData::setCompileContext(contextID, gc);
}
GraphicsContext* GraphicsContext::getCompileContext(unsigned int contextID)
{
// OSG_NOTICE<<"GraphicsContext::getCompileContext "<<contextID<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
ContextIDMap::iterator itr = s_contextIDMap.find(contextID);
if (itr != s_contextIDMap.end()) return itr->second._compileContext.get();
else return 0;
return ContextData::getCompileContext(contextID);
}
@ -530,8 +397,8 @@ void GraphicsContext::close(bool callCloseImplementation)
if (_state.valid())
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[_state->getContextID()]._numContexts>1) sharedContextExists = true;
osg::ContextData* cd = osg::getContextData(_state->getContextID());
if (cd && cd->getNumContexts()>1) sharedContextExists = true;
}
// release all the OpenGL objects in the scene graphs associated with this
@ -1011,3 +878,4 @@ void SyncSwapBuffersCallback::swapBuffersImplementation(osg::GraphicsContext* gc
//OSG_NOTICE<<"After swap"<<std::endl;
}

View File

@ -32,6 +32,7 @@
#include <osg/ColorMask>
#include <osg/PolygonOffset>
#include <osg/Depth>
#include <osg/ContextData>
#include <map>
#include <vector>
@ -230,18 +231,22 @@ struct ClearQueriesCallback : public osg::Camera::DrawCallback
};
// static cache of deleted query objects which can only
// be completely deleted once the appropriate OpenGL context
// is set.
typedef std::list< GLuint > QueryObjectList;
typedef osg::buffered_object< QueryObjectList > DeletedQueryObjectCache;
static OpenThreads::Mutex s_mutex_deletedQueryObjectCache;
static DeletedQueryObjectCache s_deletedQueryObjectCache;
namespace osg
{
class QueryObjectManager : public GLObjectManager
{
public:
QueryObjectManager(unsigned int contextID) : GLObjectManager("QueryObjectManager", contextID) {}
virtual void deleteGLObject(GLuint globj)
{
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeleteQueries( 1L, &globj );
}
};
QueryGeometry::QueryGeometry( const std::string& oqnName )
: _oqnName( oqnName )
@ -378,7 +383,11 @@ QueryGeometry::releaseGLObjects( osg::State* state ) const
TestResult& tr = it->second;
if (tr._contextID == contextID)
{
#if 1
osg::get<QueryObjectManager>(contextID)->sheduleGLObjectForDeletion(tr._id );
#else
QueryGeometry::deleteQueryObject( contextID, tr._id );
#endif
tr._init = false;
}
it++;
@ -389,52 +398,20 @@ QueryGeometry::releaseGLObjects( osg::State* state ) const
void
QueryGeometry::deleteQueryObject( unsigned int contextID, GLuint handle )
{
if (handle!=0)
{
OpenThreads::ScopedLock< OpenThreads::Mutex > lock( s_mutex_deletedQueryObjectCache );
// insert the handle into the cache for the appropriate context.
s_deletedQueryObjectCache[contextID].push_back( handle );
}
osg::get<QueryObjectManager>(contextID)->sheduleGLObjectForDeletion(handle);
}
void
QueryGeometry::flushDeletedQueryObjects( unsigned int contextID, double /*currentTime*/, double& availableTime )
QueryGeometry::flushDeletedQueryObjects( unsigned int contextID, double currentTime, double& availableTime )
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedQueryObjectCache);
const osg::GLExtensions* extensions = osg::GLExtensions::Get( contextID, true );
QueryObjectList& qol = s_deletedQueryObjectCache[contextID];
for(QueryObjectList::iterator titr=qol.begin();
titr!=qol.end() && elapsedTime<availableTime;
)
{
extensions->glDeleteQueries( 1L, &(*titr ) );
titr = qol.erase(titr);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
osg::get<QueryObjectManager>(contextID)->flushDeletedGLObjects(currentTime, availableTime);
}
void
QueryGeometry::discardDeletedQueryObjects( unsigned int contextID )
{
OpenThreads::ScopedLock< OpenThreads::Mutex > lock( s_mutex_deletedQueryObjectCache );
QueryObjectList& qol = s_deletedQueryObjectCache[ contextID ];
qol.clear();
osg::get<QueryObjectManager>(contextID)->discardAllGLObjects();
}
// End support classes

View File

@ -31,6 +31,7 @@
#include <osg/Program>
#include <osg/Shader>
#include <osg/GLExtensions>
#include <osg/ContextData>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
@ -39,62 +40,17 @@
using namespace osg;
///////////////////////////////////////////////////////////////////////////
// static cache of glPrograms flagged for deletion, which will actually
// be deleted in the correct GL context.
typedef std::list<GLuint> GlProgramHandleList;
typedef osg::buffered_object<GlProgramHandleList> DeletedGlProgramCache;
static OpenThreads::Mutex s_mutex_deletedGlProgramCache;
static DeletedGlProgramCache s_deletedGlProgramCache;
void Program::deleteGlProgram(unsigned int contextID, GLuint program)
class GLProgramManager : public GLObjectManager
{
if( program )
public:
GLProgramManager(unsigned int contextID) : GLObjectManager("GLProgramManager", contextID) {}
virtual void deleteGLObject(GLuint globj)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGlProgramCache);
// add glProgram to the cache for the appropriate context.
s_deletedGlProgramCache[contextID].push_back(program);
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeleteProgram( globj );
}
}
void Program::flushDeletedGlPrograms(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGlProgramCache);
const GLExtensions* extensions = GLExtensions::Get(contextID,true);
if( ! extensions->isGlslSupported ) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
GlProgramHandleList& pList = s_deletedGlProgramCache[contextID];
for(GlProgramHandleList::iterator titr=pList.begin();
titr!=pList.end() && elapsedTime<availableTime;
)
{
extensions->glDeleteProgram( *titr );
titr = pList.erase( titr );
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
}
void Program::discardDeletedGlPrograms(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGlProgramCache);
GlProgramHandleList& pList = s_deletedGlProgramCache[contextID];
pList.clear();
}
};
///////////////////////////////////////////////////////////////////////////
@ -733,7 +689,7 @@ Program::PerContextProgram::~PerContextProgram()
{
if (_ownsProgramHandle)
{
Program::deleteGlProgram( _contextID, _glProgramHandle );
osg::get<GLProgramManager>(_contextID)->deleteGLObject(_glProgramHandle);
}
}

View File

@ -32,12 +32,21 @@
#include <osg/ref_ptr>
#include <osg/Shader>
#include <osg/GLExtensions>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
#include <osg/ContextData>
using namespace osg;
class GLShaderManager : public GLObjectManager
{
public:
GLShaderManager(unsigned int contextID) : GLObjectManager("GLShaderManager",contextID) {}
virtual void deleteGLObject(GLuint globj)
{
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeleteShader( globj );
}
};
///////////////////////////////////////////////////////////////////////////////////
//
@ -151,64 +160,6 @@ ShaderBinary* ShaderBinary::readShaderBinaryFile(const std::string& fileName)
return shaderBinary.release();
}
///////////////////////////////////////////////////////////////////////////
// static cache of glShaders flagged for deletion, which will actually
// be deleted in the correct GL context.
typedef std::list<GLuint> GlShaderHandleList;
typedef osg::buffered_object<GlShaderHandleList> DeletedGlShaderCache;
static OpenThreads::Mutex s_mutex_deletedGlShaderCache;
static DeletedGlShaderCache s_deletedGlShaderCache;
void Shader::deleteGlShader(unsigned int contextID, GLuint shader)
{
if( shader )
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGlShaderCache);
// add glShader to the cache for the appropriate context.
s_deletedGlShaderCache[contextID].push_back(shader);
}
}
void Shader::flushDeletedGlShaders(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const GLExtensions* extensions = GLExtensions::Get(contextID,true);
if( ! extensions->isGlslSupported ) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGlShaderCache);
GlShaderHandleList& pList = s_deletedGlShaderCache[contextID];
for(GlShaderHandleList::iterator titr=pList.begin();
titr!=pList.end() && elapsedTime<availableTime;
)
{
extensions->glDeleteShader( *titr );
titr = pList.erase( titr );
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
}
void Shader::discardDeletedGlShaders(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedGlShaderCache);
GlShaderHandleList& pList = s_deletedGlShaderCache[contextID];
pList.clear();
}
///////////////////////////////////////////////////////////////////////////
// osg::Shader
///////////////////////////////////////////////////////////////////////////
@ -513,7 +464,7 @@ Shader::PerContextShader::PerContextShader(const Shader* shader, unsigned int co
Shader::PerContextShader::~PerContextShader()
{
Shader::deleteGlShader( _contextID, _glShaderHandle );
osg::get<GLShaderManager>(_contextID)->deleteGLObject(_glShaderHandle);
}

View File

@ -17,6 +17,7 @@
#include <osg/GLExtensions>
#include <osg/Drawable>
#include <osg/ApplicationUsage>
#include <osg/ContextData>
#include <sstream>
#include <algorithm>
@ -301,14 +302,14 @@ void State::setInitialViewMatrix(const osg::RefMatrix* matrix)
void State::setMaxTexturePoolSize(unsigned int size)
{
_maxTexturePoolSize = size;
osg::Texture::getTextureObjectManager(getContextID())->setMaxTexturePoolSize(size);
osg::get<TextureObjectManager>(_contextID)->setMaxTexturePoolSize(size);
OSG_INFO<<"osg::State::_maxTexturePoolSize="<<_maxTexturePoolSize<<std::endl;
}
void State::setMaxBufferObjectPoolSize(unsigned int size)
{
_maxBufferObjectPoolSize = size;
osg::GLBufferObjectManager::getGLBufferObjectManager(getContextID())->setMaxGLBufferObjectPoolSize(_maxBufferObjectPoolSize);
osg::get<GLBufferObjectManager>(_contextID)->setMaxGLBufferObjectPoolSize(_maxBufferObjectPoolSize);
OSG_INFO<<"osg::State::_maxBufferObjectPoolSize="<<_maxBufferObjectPoolSize<<std::endl;
}

View File

@ -21,6 +21,7 @@
#include <osg/FrameBufferObject>
#include <osg/TextureRectangle>
#include <osg/Texture1D>
#include <osg/ContextData>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
@ -247,6 +248,11 @@ void Texture::TextureObject::bind()
if (_set) _set->moveToBack(this);
}
void Texture::TextureObject::release()
{
if (_set) _set->orphan(this);
}
void Texture::TextureObject::setAllocated(GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
@ -347,7 +353,7 @@ void Texture::TextureProfile::computeSize()
//
// New texture object manager
//
Texture::TextureObjectSet::TextureObjectSet(TextureObjectManager* parent, const TextureProfile& profile):
TextureObjectSet::TextureObjectSet(TextureObjectManager* parent, const Texture::TextureProfile& profile):
_parent(parent),
_contextID(parent->getContextID()),
_profile(profile),
@ -357,7 +363,7 @@ Texture::TextureObjectSet::TextureObjectSet(TextureObjectManager* parent, const
{
}
Texture::TextureObjectSet::~TextureObjectSet()
TextureObjectSet::~TextureObjectSet()
{
#if 0
OSG_NOTICE<<"TextureObjectSet::~TextureObjectSet(), _numOfTextureObjects="<<_numOfTextureObjects<<std::endl;
@ -367,7 +373,7 @@ Texture::TextureObjectSet::~TextureObjectSet()
#endif
}
bool Texture::TextureObjectSet::checkConsistency() const
bool TextureObjectSet::checkConsistency() const
{
OSG_NOTICE<<"TextureObjectSet::checkConsistency()"<<std::endl;
// check consistency of linked list.
@ -381,7 +387,7 @@ bool Texture::TextureObjectSet::checkConsistency() const
{
if ((to->_next)->_previous != to)
{
OSG_NOTICE<<"Texture::TextureObjectSet::checkConsistency() : Error (to->_next)->_previous != to "<<std::endl;
OSG_NOTICE<<"TextureObjectSet::checkConsistency() : Error (to->_next)->_previous != to "<<std::endl;
return false;
}
}
@ -389,7 +395,7 @@ bool Texture::TextureObjectSet::checkConsistency() const
{
if (_tail != to)
{
OSG_NOTICE<<"Texture::TextureObjectSet::checkConsistency() : Error _tail != to"<<std::endl;
OSG_NOTICE<<"TextureObjectSet::checkConsistency() : Error _tail != to"<<std::endl;
return false;
}
}
@ -413,7 +419,7 @@ bool Texture::TextureObjectSet::checkConsistency() const
return true;
}
void Texture::TextureObjectSet::handlePendingOrphandedTextureObjects()
void TextureObjectSet::handlePendingOrphandedTextureObjects()
{
// OSG_NOTICE<<"handlePendingOrphandedTextureObjects()"<<_pendingOrphanedTextureObjects.size()<<std::endl;
@ -421,11 +427,11 @@ void Texture::TextureObjectSet::handlePendingOrphandedTextureObjects()
unsigned int numOrphaned = _pendingOrphanedTextureObjects.size();
for(TextureObjectList::iterator itr = _pendingOrphanedTextureObjects.begin();
for(Texture::TextureObjectList::iterator itr = _pendingOrphanedTextureObjects.begin();
itr != _pendingOrphanedTextureObjects.end();
++itr)
{
TextureObject* to = itr->get();
Texture::TextureObject* to = itr->get();
_orphanedTextureObjects.push_back(to);
@ -443,15 +449,15 @@ void Texture::TextureObjectSet::handlePendingOrphandedTextureObjects()
}
void Texture::TextureObjectSet::deleteAllTextureObjects()
void TextureObjectSet::deleteAllTextureObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectSet::deleteAllTextureObjects()"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::deleteAllTextureObjects()"<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
@ -460,10 +466,10 @@ void Texture::TextureObjectSet::deleteAllTextureObjects()
// detect all the active texture objects from their Textures
unsigned int numOrphaned = 0;
TextureObject* to = _head;
Texture::TextureObject* to = _head;
while(to!=0)
{
ref_ptr<TextureObject> glto = to;
ref_ptr<Texture::TextureObject> glto = to;
to = to->_next;
@ -489,14 +495,14 @@ void Texture::TextureObjectSet::deleteAllTextureObjects()
// OSG_NOTICE<<"done GLBufferObjectSet::deleteAllGLBufferObjects()"<<std::endl;
}
void Texture::TextureObjectSet::discardAllTextureObjects()
void TextureObjectSet::discardAllTextureObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectSet::discardAllTextureObjects()."<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::discardAllTextureObjects()."<<std::endl;
TextureObject* to = _head;
Texture::TextureObject* to = _head;
while(to!=0)
{
ref_ptr<TextureObject> glto = to;
ref_ptr<Texture::TextureObject> glto = to;
to = to->_next;
@ -524,19 +530,19 @@ void Texture::TextureObjectSet::discardAllTextureObjects()
_parent->getNumberDeleted() += numDeleted;
}
void Texture::TextureObjectSet::flushAllDeletedTextureObjects()
void TextureObjectSet::flushAllDeletedTextureObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushAllDeletedTextureObjects()"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::flushAllDeletedTextureObjects()"<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
for(TextureObjectList::iterator itr = _orphanedTextureObjects.begin();
for(Texture::TextureObjectList::iterator itr = _orphanedTextureObjects.begin();
itr != _orphanedTextureObjects.end();
++itr)
{
@ -558,16 +564,16 @@ void Texture::TextureObjectSet::flushAllDeletedTextureObjects()
_orphanedTextureObjects.clear();
}
void Texture::TextureObjectSet::discardAllDeletedTextureObjects()
void TextureObjectSet::discardAllDeletedTextureObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectSet::discardAllDeletedTextureObjects()"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::discardAllDeletedTextureObjects()"<<std::endl;
// clean up the pending orphans.
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
@ -587,15 +593,15 @@ void Texture::TextureObjectSet::discardAllDeletedTextureObjects()
_orphanedTextureObjects.clear();
}
void Texture::TextureObjectSet::flushDeletedTextureObjects(double /*currentTime*/, double& availableTime)
void TextureObjectSet::flushDeletedTextureObjects(double /*currentTime*/, double& availableTime)
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..)"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::flushDeletedTextureObjects(..)"<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::flushDeletedTextureObjects(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
@ -627,7 +633,7 @@ void Texture::TextureObjectSet::flushDeletedTextureObjects(double /*currentTime*
ElapsedTime timer;
TextureObjectList::iterator itr = _orphanedTextureObjects.begin();
Texture::TextureObjectList::iterator itr = _orphanedTextureObjects.begin();
for(;
itr != _orphanedTextureObjects.end() && timer.elapsedTime()<availableTime && numDeleted<maxNumObjectsToDelete;
++itr)
@ -657,13 +663,13 @@ void Texture::TextureObjectSet::flushDeletedTextureObjects(double /*currentTime*
availableTime -= timer.elapsedTime();
}
bool Texture::TextureObjectSet::makeSpace(unsigned int& size)
bool TextureObjectSet::makeSpace(unsigned int& size)
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_pendingOrphanedTextureObjects.empty())
{
// OSG_NOTICE<<"Texture::TextureObjectSet::Texture::TextureObjectSet::makeSpace(..) handling orphans"<<std::endl;
// OSG_NOTICE<<"TextureObjectSet::TextureObjectSet::makeSpace(..) handling orphans"<<std::endl;
handlePendingOrphandedTextureObjects();
}
}
@ -680,10 +686,10 @@ bool Texture::TextureObjectSet::makeSpace(unsigned int& size)
return size==0;
}
osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectSet::takeFromOrphans(Texture* texture)
osg::ref_ptr<Texture::TextureObject> TextureObjectSet::takeFromOrphans(Texture* texture)
{
// take front of orphaned list.
ref_ptr<TextureObject> to = _orphanedTextureObjects.front();
ref_ptr<Texture::TextureObject> to = _orphanedTextureObjects.front();
// remove from orphan list.
_orphanedTextureObjects.pop_front();
@ -704,7 +710,7 @@ osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectSet::takeFromOrphans(
}
osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectSet::takeOrGenerate(Texture* texture)
osg::ref_ptr<Texture::TextureObject> TextureObjectSet::takeOrGenerate(Texture* texture)
{
// see if we can recyle TextureObject from the orphan list
{
@ -733,7 +739,7 @@ osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectSet::takeOrGenerate(T
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
ref_ptr<TextureObject> to = _head;
ref_ptr<Texture::TextureObject> to = _head;
ref_ptr<Texture> original_texture = to->getTexture();
@ -761,7 +767,7 @@ osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectSet::takeOrGenerate(T
GLuint id;
glGenTextures( 1L, &id );
osg::ref_ptr<TextureObject> to = new Texture::TextureObject(const_cast<Texture*>(texture),id,_profile);
osg::ref_ptr<Texture::TextureObject> to = new Texture::TextureObject(const_cast<Texture*>(texture),id,_profile);
to->_set = this;
++_numOfTextureObjects;
@ -776,7 +782,7 @@ osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectSet::takeOrGenerate(T
return to;
}
void Texture::TextureObjectSet::moveToBack(Texture::TextureObject* to)
void TextureObjectSet::moveToBack(Texture::TextureObject* to)
{
#if 0
OSG_NOTICE<<"TextureObjectSet::moveToBack("<<to<<")"<<std::endl;
@ -838,7 +844,7 @@ void Texture::TextureObjectSet::moveToBack(Texture::TextureObject* to)
CHECK_CONSISTENCY
}
void Texture::TextureObjectSet::addToBack(Texture::TextureObject* to)
void TextureObjectSet::addToBack(Texture::TextureObject* to)
{
#if 0
OSG_NOTICE<<"TextureObjectSet::addToBack("<<to<<")"<<std::endl;
@ -871,7 +877,7 @@ void Texture::TextureObjectSet::addToBack(Texture::TextureObject* to)
CHECK_CONSISTENCY
}
void Texture::TextureObjectSet::orphan(Texture::TextureObject* to)
void TextureObjectSet::orphan(Texture::TextureObject* to)
{
// OSG_NOTICE<<"TextureObjectSet::orphan("<<to<<")"<<std::endl;
@ -893,7 +899,7 @@ void Texture::TextureObjectSet::orphan(Texture::TextureObject* to)
#endif
}
void Texture::TextureObjectSet::remove(Texture::TextureObject* to)
void TextureObjectSet::remove(Texture::TextureObject* to)
{
if (to->_previous!=0)
{
@ -920,7 +926,7 @@ void Texture::TextureObjectSet::remove(Texture::TextureObject* to)
to->_previous = 0;
}
void Texture::TextureObjectSet::moveToSet(TextureObject* to, TextureObjectSet* set)
void TextureObjectSet::moveToSet(Texture::TextureObject* to, TextureObjectSet* set)
{
if (set==this) return;
if (!set) return;
@ -935,10 +941,10 @@ void Texture::TextureObjectSet::moveToSet(TextureObject* to, TextureObjectSet* s
set->addToBack(to);
}
unsigned int Texture::TextureObjectSet::computeNumTextureObjectsInList() const
unsigned int TextureObjectSet::computeNumTextureObjectsInList() const
{
unsigned int num=0;
TextureObject* obj = _head;
Texture::TextureObject* obj = _head;
while(obj!=NULL)
{
++num;
@ -948,8 +954,8 @@ unsigned int Texture::TextureObjectSet::computeNumTextureObjectsInList() const
}
Texture::TextureObjectManager::TextureObjectManager(unsigned int contextID):
_contextID(contextID),
TextureObjectManager::TextureObjectManager(unsigned int contextID):
GraphicsObjectManager("TextureObjectManager", contextID),
_numActiveTextureObjects(0),
_numOrphanedTextureObjects(0),
_currTexturePoolSize(0),
@ -959,13 +965,16 @@ Texture::TextureObjectManager::TextureObjectManager(unsigned int contextID):
_numDeleted(0),
_deleteTime(0.0),
_numGenerated(0),
_generateTime(0.0),
_numApplied(0),
_applyTime(0.0)
_generateTime(0.0)
{
}
void Texture::TextureObjectManager::setMaxTexturePoolSize(unsigned int size)
TextureObjectManager::~TextureObjectManager()
{
}
void TextureObjectManager::setMaxTexturePoolSize(unsigned int size)
{
if (_maxTexturePoolSize == size) return;
@ -977,7 +986,7 @@ void Texture::TextureObjectManager::setMaxTexturePoolSize(unsigned int size)
_maxTexturePoolSize = size;
}
bool Texture::TextureObjectManager::makeSpace(unsigned int size)
bool TextureObjectManager::makeSpace(unsigned int size)
{
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end() && size>0;
@ -990,12 +999,12 @@ bool Texture::TextureObjectManager::makeSpace(unsigned int size)
}
osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectManager::generateTextureObject(const Texture* texture, GLenum target)
osg::ref_ptr<Texture::TextureObject> TextureObjectManager::generateTextureObject(const Texture* texture, GLenum target)
{
return generateTextureObject(texture, target, 0, 0, 0, 0, 0, 0);
}
osg::ref_ptr<Texture::TextureObject> Texture::TextureObjectManager::generateTextureObject(const Texture* texture,
osg::ref_ptr<Texture::TextureObject> TextureObjectManager::generateTextureObject(const Texture* texture,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
@ -1032,14 +1041,14 @@ Texture::TextureObject* Texture::generateAndAssignTextureObject(
return _textureObjectBuffer[contextID].get();
}
Texture::TextureObjectSet* Texture::TextureObjectManager::getTextureObjectSet(const TextureProfile& profile)
TextureObjectSet* TextureObjectManager::getTextureObjectSet(const Texture::TextureProfile& profile)
{
osg::ref_ptr<Texture::TextureObjectSet>& tos = _textureSetMap[profile];
if (!tos) tos = new Texture::TextureObjectSet(this, profile);
osg::ref_ptr<TextureObjectSet>& tos = _textureSetMap[profile];
if (!tos) tos = new TextureObjectSet(this, profile);
return tos.get();
}
void Texture::TextureObjectManager::handlePendingOrphandedTextureObjects()
void TextureObjectManager::handlePendingOrphandedTextureObjects()
{
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end();
@ -1049,12 +1058,8 @@ void Texture::TextureObjectManager::handlePendingOrphandedTextureObjects()
}
}
void Texture::TextureObjectManager::deleteAllTextureObjects()
void TextureObjectManager::deleteAllGLObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectManager::deleteAllTextureObjects() _contextID="<<_contextID<<std::endl;
ElapsedTime elapsedTime(&(getDeleteTime()));
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end();
++itr)
@ -1063,10 +1068,8 @@ void Texture::TextureObjectManager::deleteAllTextureObjects()
}
}
void Texture::TextureObjectManager::discardAllTextureObjects()
void TextureObjectManager::discardAllGLObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectManager::discardAllTextureObjects() _contextID="<<_contextID<<" _numActiveTextureObjects="<<_numActiveTextureObjects<<std::endl;
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end();
++itr)
@ -1075,12 +1078,8 @@ void Texture::TextureObjectManager::discardAllTextureObjects()
}
}
void Texture::TextureObjectManager::flushAllDeletedTextureObjects()
void TextureObjectManager::flushAllDeletedGLObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectManager::flushAllDeletedTextureObjects() _contextID="<<_contextID<<std::endl;
ElapsedTime elapsedTime(&(getDeleteTime()));
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end();
++itr)
@ -1089,10 +1088,8 @@ void Texture::TextureObjectManager::flushAllDeletedTextureObjects()
}
}
void Texture::TextureObjectManager::discardAllDeletedTextureObjects()
void TextureObjectManager::discardAllDeletedGLObjects()
{
// OSG_NOTICE<<"Texture::TextureObjectManager::discardAllDeletedTextureObjects() _contextID="<<_contextID<<" _numActiveTextureObjects="<<_numActiveTextureObjects<<std::endl;
for(TextureSetMap::iterator itr = _textureSetMap.begin();
itr != _textureSetMap.end();
++itr)
@ -1101,10 +1098,8 @@ void Texture::TextureObjectManager::discardAllDeletedTextureObjects()
}
}
void Texture::TextureObjectManager::flushDeletedTextureObjects(double currentTime, double& availableTime)
void TextureObjectManager::flushDeletedGLObjects(double currentTime, double& availableTime)
{
ElapsedTime elapsedTime(&(getDeleteTime()));
for(TextureSetMap::iterator itr = _textureSetMap.begin();
(itr != _textureSetMap.end()) && (availableTime > 0.0);
++itr)
@ -1113,14 +1108,7 @@ void Texture::TextureObjectManager::flushDeletedTextureObjects(double currentTim
}
}
void Texture::TextureObjectManager::releaseTextureObject(Texture::TextureObject* to)
{
if (to->_set) to->_set->orphan(to);
else OSG_NOTICE<<"TextureObjectManager::releaseTextureObject(Texture::TextureObject* to) Not implemented yet"<<std::endl;
}
void Texture::TextureObjectManager::newFrame(osg::FrameStamp* fs)
void TextureObjectManager::newFrame(osg::FrameStamp* fs)
{
if (fs) _frameNumber = fs->getFrameNumber();
else ++_frameNumber;
@ -1128,19 +1116,18 @@ void Texture::TextureObjectManager::newFrame(osg::FrameStamp* fs)
++_numFrames;
}
void Texture::TextureObjectManager::reportStats(std::ostream& out)
void TextureObjectManager::reportStats(std::ostream& out)
{
double numFrames(_numFrames==0 ? 1.0 : _numFrames);
out<<"TextureObjectMananger::reportStats()"<<std::endl;
out<<" total _numOfTextureObjects="<<_numActiveTextureObjects<<", _numOrphanedTextureObjects="<<_numOrphanedTextureObjects<<" _currTexturePoolSize="<<_currTexturePoolSize<<std::endl;
out<<" total _numGenerated="<<_numGenerated<<", _generateTime="<<_generateTime<<", averagePerFrame="<<_generateTime/numFrames*1000.0<<"ms"<<std::endl;
out<<" total _numDeleted="<<_numDeleted<<", _deleteTime="<<_deleteTime<<", averagePerFrame="<<_deleteTime/numFrames*1000.0<<"ms"<<std::endl;
out<<" total _numApplied="<<_numApplied<<", _applyTime="<<_applyTime<<", averagePerFrame="<<_applyTime/numFrames*1000.0<<"ms"<<std::endl;
out<<" getMaxTexturePoolSize()="<<getMaxTexturePoolSize()<<" current/max size = "<<double(_currTexturePoolSize)/double(getMaxTexturePoolSize())<<std::endl;
recomputeStats(out);
}
void Texture::TextureObjectManager::resetStats()
void TextureObjectManager::resetStats()
{
_numFrames = 0;
_numDeleted = 0;
@ -1148,15 +1135,12 @@ void Texture::TextureObjectManager::resetStats()
_numGenerated = 0;
_generateTime = 0;
_numApplied = 0;
_applyTime = 0;
}
void Texture::TextureObjectManager::recomputeStats(std::ostream& out) const
void TextureObjectManager::recomputeStats(std::ostream& out) const
{
out<<"Texture::TextureObjectManager::recomputeStats()"<<std::endl;
out<<"TextureObjectManager::recomputeStats()"<<std::endl;
unsigned int numObjectsInLists = 0;
unsigned int numActive = 0;
unsigned int numOrphans = 0;
@ -1184,7 +1168,7 @@ void Texture::TextureObjectManager::recomputeStats(std::ostream& out) const
if (currentSize != _currTexturePoolSize) out<<" WARNING: _currTexturePoolSize("<<_currTexturePoolSize<<") != currentSize, delta = "<<int(_currTexturePoolSize)-int(currentSize)<<std::endl;
}
bool Texture::TextureObjectManager::checkConsistency() const
bool TextureObjectManager::checkConsistency() const
{
unsigned int numObjectsInLists = 0;
unsigned int numActive = 0;
@ -1207,25 +1191,15 @@ bool Texture::TextureObjectManager::checkConsistency() const
{
recomputeStats(osg::notify(osg::NOTICE));
throw "Texture::TextureObjectManager::checkConsistency() sizes inconsistent";
throw "TextureObjectManager::checkConsistency() sizes inconsistent";
return false;
}
return true;
}
osg::ref_ptr<Texture::TextureObjectManager>& Texture::getTextureObjectManager(unsigned int contextID)
{
typedef osg::buffered_object< ref_ptr<Texture::TextureObjectManager> > TextureObjectManagerBuffer;
static TextureObjectManagerBuffer s_TextureObjectManager;
if (!s_TextureObjectManager[contextID]) s_TextureObjectManager[contextID] = new Texture::TextureObjectManager(contextID);
return s_TextureObjectManager[contextID];
}
osg::ref_ptr<Texture::TextureObject> Texture::generateTextureObject(const Texture* texture, unsigned int contextID, GLenum target)
{
return getTextureObjectManager(contextID)->generateTextureObject(texture, target);
return osg::get<TextureObjectManager>(contextID)->generateTextureObject(texture, target);
}
osg::ref_ptr<Texture::TextureObject> Texture::generateTextureObject(const Texture* texture, unsigned int contextID,
@ -1237,37 +1211,7 @@ osg::ref_ptr<Texture::TextureObject> Texture::generateTextureObject(const Textur
GLsizei depth,
GLint border)
{
return getTextureObjectManager(contextID)->generateTextureObject(texture,target,numMipmapLevels,internalFormat,width,height,depth,border);
}
void Texture::deleteAllTextureObjects(unsigned int contextID)
{
getTextureObjectManager(contextID)->deleteAllTextureObjects();
}
void Texture::discardAllTextureObjects(unsigned int contextID)
{
getTextureObjectManager(contextID)->discardAllTextureObjects();
}
void Texture::flushAllDeletedTextureObjects(unsigned int contextID)
{
getTextureObjectManager(contextID)->flushAllDeletedTextureObjects();
}
void Texture::discardAllDeletedTextureObjects(unsigned int contextID)
{
getTextureObjectManager(contextID)->discardAllDeletedTextureObjects();
}
void Texture::flushDeletedTextureObjects(unsigned int contextID,double currentTime, double& availbleTime)
{
getTextureObjectManager(contextID)->flushDeletedTextureObjects(currentTime, availbleTime);
}
void Texture::releaseTextureObject(unsigned int contextID, Texture::TextureObject* to)
{
getTextureObjectManager(contextID)->releaseTextureObject(to);
return osg::get<TextureObjectManager>(contextID)->generateTextureObject(texture,target,numMipmapLevels,internalFormat,width,height,depth,border);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1453,7 +1397,7 @@ void Texture::dirtyTextureObject()
{
if (_textureObjectBuffer[i].valid())
{
Texture::releaseTextureObject(i, _textureObjectBuffer[i].get());
_textureObjectBuffer[i]->release();
_textureObjectBuffer[i] = 0;
}
}
@ -2829,7 +2773,7 @@ void Texture::releaseGLObjects(State* state) const
unsigned int contextID = state->getContextID();
if (_textureObjectBuffer[contextID].valid())
{
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
}

View File

@ -134,10 +134,6 @@ void Texture1D::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
@ -153,7 +149,7 @@ void Texture1D::apply(State& state) const
if (!textureObject->match(GL_TEXTURE_1D, new_numMipmapLevels, _internalFormat, new_width, 1, 1, _borderWidth))
{
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
textureObject = 0;
}

View File

@ -14,6 +14,7 @@
#include <osg/GLExtensions>
#include <osg/Texture2D>
#include <osg/State>
#include <osg/ContextData>
#include <osg/Notify>
using namespace osg;
@ -165,10 +166,6 @@ void Texture2D::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
if (textureObject)
@ -186,7 +183,7 @@ void Texture2D::apply(State& state) const
if (textureObjectInvalidated)
{
// OSG_NOTICE<<"Discarding TextureObject"<<std::endl;
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
textureObject = 0;
}

View File

@ -235,10 +235,6 @@ void Texture2DArray::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
const GLExtensions* extensions = state.get<GLExtensions>();
// if not supported, then return
@ -268,7 +264,7 @@ void Texture2DArray::apply(State& state) const
if (!textureObject->match(GL_TEXTURE_2D_ARRAY_EXT, new_numMipmapLevels, _internalFormat, new_width, new_height, textureDepth, _borderWidth))
{
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
textureObject = 0;
}

View File

@ -93,10 +93,6 @@ void Texture2DMultisample::apply(State& state) const
return;
}
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);

View File

@ -204,10 +204,6 @@ void Texture3D::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
const GLExtensions* extensions = state.get<GLExtensions>();
if (!extensions->isTexture3DSupported)
@ -233,7 +229,7 @@ void Texture3D::apply(State& state) const
if (!textureObject->match(GL_TEXTURE_3D, new_numMipmapLevels, _internalFormat, new_width, new_height, new_depth, _borderWidth))
{
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
textureObject = 0;
}

View File

@ -199,10 +199,6 @@ void TextureCubeMap::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
const GLExtensions* extensions = state.get<GLExtensions>();
if (!extensions->isCubeMapSupported)
@ -226,7 +222,7 @@ void TextureCubeMap::apply(State& state) const
if (!textureObject->match(GL_TEXTURE_CUBE_MAP, new_numMipmapLevels, _internalFormat, new_width, new_height, 1, _borderWidth))
{
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
textureObject = 0;
}

View File

@ -167,11 +167,6 @@ void TextureRectangle::apply(State& state) const
// current OpenGL context.
const unsigned int contextID = state.getContextID();
Texture::TextureObjectManager* tom = Texture::getTextureObjectManager(contextID).get();
ElapsedTime elapsedTime(&(tom->getApplyTime()));
tom->getNumberApplied()++;
// get the texture object for the current contextID.
TextureObject* textureObject = getTextureObject(contextID);
@ -189,7 +184,7 @@ void TextureRectangle::apply(State& state) const
if (!textureObject->match(GL_TEXTURE_RECTANGLE, new_numMipmapLevels, _internalFormat, new_width, new_height, 1, _borderWidth))
{
Texture::releaseTextureObject(contextID, _textureObjectBuffer[contextID].get());
_textureObjectBuffer[contextID]->release();
_textureObjectBuffer[contextID] = 0;
textureObject = 0;
}

View File

@ -15,71 +15,21 @@
#include <osg/VertexProgram>
#include <osg/State>
#include <osg/Timer>
#include <list>
#include <OpenThreads/ScopedLock>
#include <OpenThreads/Mutex>
#include <osg/ContextData>
using namespace osg;
// static cache of deleted vertex programs which can only
// by completely deleted once the appropriate OpenGL context
// is set.
typedef std::list<GLuint> VertexProgramObjectList;
typedef osg::buffered_object<VertexProgramObjectList> DeletedVertexProgramObjectCache;
static OpenThreads::Mutex s_mutex_deletedVertexProgramObjectCache;
static DeletedVertexProgramObjectCache s_deletedVertexProgramObjectCache;
void VertexProgram::deleteVertexProgramObject(unsigned int contextID,GLuint handle)
class GLVertexProgramManager : public GLObjectManager
{
if (handle!=0)
public:
GLVertexProgramManager(unsigned int contextID) : GLObjectManager("GLVertexProgramManager",contextID) {}
virtual void deleteGLObject(GLuint globj)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedVertexProgramObjectCache);
// insert the handle into the cache for the appropriate context.
s_deletedVertexProgramObjectCache[contextID].push_back(handle);
const GLExtensions* extensions = GLExtensions::Get(_contextID,true);
if (extensions->isGlslSupported) extensions->glDeletePrograms(1, &globj );
}
}
void VertexProgram::flushDeletedVertexProgramObjects(unsigned int contextID,double /*currentTime*/, double& availableTime)
{
// if no time available don't try to flush objects.
if (availableTime<=0.0) return;
const osg::Timer& timer = *osg::Timer::instance();
osg::Timer_t start_tick = timer.tick();
double elapsedTime = 0.0;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedVertexProgramObjectCache);
const GLExtensions* extensions = GLExtensions::Get(contextID,true);
VertexProgramObjectList& vpol = s_deletedVertexProgramObjectCache[contextID];
for(VertexProgramObjectList::iterator titr=vpol.begin();
titr!=vpol.end() && elapsedTime<availableTime;
)
{
extensions->glDeletePrograms( 1L, &(*titr ) );
titr = vpol.erase(titr);
elapsedTime = timer.delta_s(start_tick,timer.tick());
}
}
availableTime -= elapsedTime;
}
void VertexProgram::discardDeletedVertexProgramObjects(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_mutex_deletedVertexProgramObjectCache);
VertexProgramObjectList& vpol = s_deletedVertexProgramObjectCache[contextID];
vpol.clear();
}
};
VertexProgram::VertexProgram()
{
@ -117,7 +67,7 @@ void VertexProgram::dirtyVertexProgramObject()
{
if (_vertexProgramIDList[i] != 0)
{
VertexProgram::deleteVertexProgramObject(i,_vertexProgramIDList[i]);
osg::get<GLVertexProgramManager>(i)->deleteGLObject(_vertexProgramIDList[i]);
_vertexProgramIDList[i] = 0;
}
}
@ -207,7 +157,7 @@ void VertexProgram::releaseGLObjects(State* state) const
unsigned int contextID = state->getContextID();
if (_vertexProgramIDList[contextID] != 0)
{
VertexProgram::deleteVertexProgramObject(contextID,_vertexProgramIDList[contextID]);
osg::get<GLVertexProgramManager>(contextID)->deleteGLObject(_vertexProgramIDList[contextID]);
_vertexProgramIDList[contextID] = 0;
}
}

View File

@ -19,6 +19,7 @@
#include <osg/Texture3D>
#include <osg/TextureRectangle>
#include <osg/TextureCubeMap>
#include <osg/ContextData>
#include <osg/GLExtensions>
#include <osg/GLU>
@ -537,12 +538,8 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
fbo = 0;
// clean up.
double availableTime = 100.0f;
double currentTime = state.getFrameStamp()?state.getFrameStamp()->getReferenceTime():0.0;
osg::RenderBuffer::flushDeletedRenderBuffers(state.getContextID(),currentTime,availableTime);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(state.getContextID(),currentTime,availableTime);
osg::get<osg::GLRenderBufferManager>(state.getContextID())->flushAllDeletedGLObjects();
osg::get<osg::GLFrameBufferObjectManager>(state.getContextID())->flushAllDeletedGLObjects();
}
else
{
@ -568,10 +565,8 @@ void RenderStage::runCameraSetUp(osg::RenderInfo& renderInfo)
_resolveFbo = 0;
// clean up.
double availableTime = 100.0f;
double currentTime = state.getFrameStamp()?state.getFrameStamp()->getReferenceTime():0.0;
osg::RenderBuffer::flushDeletedRenderBuffers(state.getContextID(),currentTime,availableTime);
osg::FrameBufferObject::flushDeletedFrameBufferObjects(state.getContextID(),currentTime,availableTime);
osg::get<osg::GLRenderBufferManager>(state.getContextID())->flushAllDeletedGLObjects();
osg::get<osg::GLFrameBufferObjectManager>(state.getContextID())->flushAllDeletedGLObjects();
}
else
{

View File

@ -24,6 +24,7 @@
#include <osg/ColorMatrix>
#include <osg/LightModel>
#include <osg/CollectOccludersVisitor>
#include <osg/ContextData>
#include <osg/GLU>
@ -579,7 +580,7 @@ void SceneView::computeRightEyeViewport(const osg::Viewport *viewport)
void SceneView::setLightingMode(LightingMode mode)
{
if (mode==_lightingMode) return;
osg::StateSet* stateSetToModify = _secondaryStateSet.valid() ? _secondaryStateSet.get() : _globalStateSet.get();
if (_lightingMode!=NO_SCENEVIEW_LIGHT)
@ -963,11 +964,7 @@ void SceneView::draw()
state->initializeExtensionProcs();
osg::Texture::TextureObjectManager* tom = osg::Texture::getTextureObjectManager(state->getContextID()).get();
tom->newFrame(state->getFrameStamp());
osg::GLBufferObjectManager* bom = osg::GLBufferObjectManager::getGLBufferObjectManager(state->getContextID()).get();
bom->newFrame(state->getFrameStamp());
osg::get<ContextData>(state->getContextID())->newFrame(state->getFrameStamp());
if (!_initCalled) init();