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,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); }