Added support for texture object manager, which provides an automatic mechansim

for reusing deleted textures.
This commit is contained in:
Robert Osfield
2003-07-14 14:42:10 +00:00
parent 94d8e72ad3
commit 1b9d7d458a
18 changed files with 795 additions and 387 deletions

View File

@@ -69,6 +69,7 @@ class SG_EXPORT StateSet : public Object
/** set this StateSet to contain specified GLMode and value.*/
void setMode(StateAttribute::GLMode mode, StateAttribute::GLModeValue value);
/** set this StateSet to inherit specified GLMode type from parents.
* has the effect of deleting any GlMode of specified type from StateSet.*/
void setModeToInherit(StateAttribute::GLMode mode);

View File

@@ -21,6 +21,8 @@
#include <osg/Vec4>
#include <osg/buffered_value>
#include <list>
#include <map>
// if not defined by gl.h use the definition found in:
// http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_filter_anisotropic.txt
@@ -204,12 +206,20 @@ class SG_EXPORT Texture : public osg::StateAttribute
bool isCompressedInternalFormat() const;
class TextureObject;
/** Get the handle to the texture object for the current context.*/
inline GLuint& getTextureObject(unsigned int contextID) const
inline TextureObject* getTextureObject(unsigned int contextID) const
{
return _handleList[contextID];
return _textureObjectBuffer[contextID].get();
}
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
void dirtyTextureObject();
/** return true if the texture objects for all the required graphics contexts are loaded.*/
bool areAllTextureObjectsLoaded() const;
/** get the dirty flag for the current contextID.*/
inline unsigned int& getTextureParameterDirty(unsigned int contextID) const
@@ -217,22 +227,12 @@ class SG_EXPORT Texture : public osg::StateAttribute
return _texParametersDirtyList[contextID];
}
/** Force a recompile on next apply() of associated OpenGL texture objects.*/
void dirtyTextureObject();
/** Force a resetting on next apply() of associated OpenGL texture parameters.*/
void dirtyTextureParameters();
/** use deleteTextureObject instead of glDeleteTextures to allow
* OpenGL texture objects to cached until they can be deleted
* by the OpenGL context in which they were created, specified
* by contextID.*/
static void deleteTextureObject(unsigned int contextID,GLuint handle);
/** flush all the cached display list which need to be deleted
* in the OpenGL context related to contextID.*/
static void flushDeletedTextureObjects(unsigned int contextID);
/** Texture is pure virtual base class, apply must be overriden. */
virtual void apply(State& state) const = 0;
@@ -326,13 +326,14 @@ class SG_EXPORT Texture : public osg::StateAttribute
* but need to ensure that they all use the same low common denominator extensions.*/
static void setExtensions(unsigned int contextID,Extensions* extensions);
/** Helper method which does the creation of the texture itself, but does not set or use texture binding.
* Note, do not call this method directly unless you are implementing your own Subload callback*/
void applyTexImage2D_load(GLenum target, const Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const;
void applyTexImage2D_load(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height,GLsizei numMipmapLevels) const;
/** Helper method which subloads images to the texture itself, but does not set or use texture binding.
* Note, do not call this method directly unless you are implementing your own Subload callback*/
void applyTexImage2D_subload(GLenum target, const Image* image, State& state, GLsizei& width, GLsizei& height,GLsizei& numMimpmapLevels) const;
void applyTexImage2D_subload(State& state, GLenum target, const Image* image, GLsizei width, GLsizei height,GLsizei numMipmapLevels) const;
protected :
@@ -342,18 +343,18 @@ class SG_EXPORT Texture : public osg::StateAttribute
void computeInternalFormatWithImage(const osg::Image& image) const;
void computeRequiredTextureDimensions(State& state, const osg::Image& image,GLsizei& width, GLsizei& height,GLsizei& numMipmapLevels) const;
bool isCompressedInternalFormat(GLint internalFormat) const;
/** Helper method which does setting of texture paramters. */
void applyTexParameters(GLenum target, State& state) const;
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
int compareTexture(const Texture& rhs) const;
typedef buffered_value<GLuint> TextureNameList;
mutable TextureNameList _handleList;
typedef buffered_value<unsigned int> TexParameterDirtyList;
mutable TexParameterDirtyList _texParametersDirtyList;
@@ -371,6 +372,172 @@ class SG_EXPORT Texture : public osg::StateAttribute
InternalFormatMode _internalFormatMode;
mutable GLint _internalFormat;
public:
class TextureObject : public osg::Referenced
{
public:
inline TextureObject(GLuint id,GLenum target):
_id(id),
_target(target),
_numMipmapLevels(0),
_internalFormat(0),
_width(0),
_height(0),
_depth(0),
_border(0),
_allocated(false),
_timeStamp(0) {}
inline TextureObject(GLuint id,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border):
_id(id),
_target(target),
_numMipmapLevels(numMipmapLevels),
_internalFormat(internalFormat),
_width(width),
_height(height),
_depth(depth),
_border(border),
_allocated(false),
_timeStamp(0) {}
inline bool match(GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
return isReusable() &&
(_target == target) &&
(_numMipmapLevels == numMipmapLevels) &&
(_internalFormat == internalFormat) &&
(_width == width) &&
(_height == height) &&
(_depth == depth) &&
(_border == border);
}
inline void bind()
{
glBindTexture( _target, _id);
}
inline void setAllocated(bool allocated=true) { _allocated = allocated; }
inline void setAllocated(GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
_allocated=true;
_numMipmapLevels = numMipmapLevels;
_internalFormat = internalFormat;
_width = width;
_height = height;
_depth = depth;
_border = border;
}
inline bool isAllocated() const { return _allocated; }
inline bool isReusable() const { return _allocated && _width!=0; }
GLuint _id;
GLenum _target;
GLint _numMipmapLevels;
GLenum _internalFormat;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLint _border;
bool _allocated;
double _timeStamp;
};
typedef std::list< ref_ptr<TextureObject> > TextureObjectList;
typedef std::map<unsigned int, TextureObjectList > TextureObjectListMap;
/** take the active texture objects from the Texture and place them in the specified TextureObjectListMap.*/
void takeTextureObjects(TextureObjectListMap& toblm);
typedef buffered_object< ref_ptr<TextureObject> > TextureObjectBuffer;
mutable TextureObjectBuffer _textureObjectBuffer;
class TextureObjectManager : public osg::Referenced
{
public:
virtual TextureObject* generateTextureObject(unsigned int contextID,GLenum target);
virtual TextureObject* generateTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
virtual TextureObject* reuseTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border);
inline TextureObject* reuseOrGenerateTextureObject(unsigned int contextID,
GLenum target,
GLint numMipmapLevels,
GLenum internalFormat,
GLsizei width,
GLsizei height,
GLsizei depth,
GLint border)
{
TextureObject* to = reuseTextureObject(contextID,target,numMipmapLevels,internalFormat,width,height,depth,border);
if (to) return to;
else return generateTextureObject(contextID,target,numMipmapLevels,internalFormat,width,height,depth,border);
}
virtual void addTextureObjects(TextureObjectListMap& toblm);
virtual void addTextureObjectsFrom(Texture& texture);
virtual void deleteTextureObjects(unsigned int contextID,double currentTime);
// how long to keep unsed texture objects around for before deleting.
double _expiryDelay;
TextureObjectListMap _textureObjectListMap;
};
static void setTextureObjectManager(TextureObjectManager* tom);
static TextureObjectManager* getTextureObjectManager();
};

View File

@@ -87,10 +87,10 @@ class SG_EXPORT Texture1D : public Texture
/** Set the number of mip map levels the the texture has been created with,
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
/** Get the number of mip map levels the the texture has been created with.*/
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
/** Copy pixels into a 1D texture image.As per glCopyTexImage1D.
@@ -118,7 +118,7 @@ class SG_EXPORT Texture1D : public Texture
/** Helper method which does the creation of the texture itself, and
* does not set or use texture binding. */
void applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& numMimpmapLevels) const;
void applyTexImage1D(GLenum target, Image* image, State& state, GLsizei& width, GLsizei& numMipmapLevels) const;
// not ideal that _image is mutable, but its required since
@@ -131,7 +131,7 @@ class SG_EXPORT Texture1D : public Texture
mutable GLsizei _textureWidth;
// number of mip map levels the the texture has been created with,
mutable GLsizei _numMimpmapLevels;
mutable GLsizei _numMipmapLevels;
ref_ptr<SubloadCallback> _subloadCallback;

View File

@@ -88,10 +88,10 @@ class SG_EXPORT Texture3D : public Texture
/** Set the number of mip map levels the the texture has been created with,
should only be called within an osg::Texuture::apply() and custom OpenGL texture load.*/
void setNumMipmapLevels(unsigned int num) const { _numMimpmapLevels=num; }
void setNumMipmapLevels(unsigned int num) const { _numMipmapLevels=num; }
/** Get the number of mip map levels the the texture has been created with.*/
unsigned int getNumMipmapLevels() const { return _numMimpmapLevels; }
unsigned int getNumMipmapLevels() const { return _numMipmapLevels; }
/** Copy a two-dimensional texture subimage. As per glCopyTexSubImage2D.
@@ -175,7 +175,7 @@ class SG_EXPORT Texture3D : public Texture
virtual void computeInternalFormat() const;
void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMimpmapLevels) const;
void applyTexImage3D(GLenum target, Image* image, State& state, GLsizei& inwidth, GLsizei& inheight, GLsizei& indepth, GLsizei& numMipmapLevels) const;
// not ideal that _image is mutable, but its required since
// Image::ensureDimensionsArePowerOfTwo() can only be called
@@ -187,7 +187,7 @@ class SG_EXPORT Texture3D : public Texture
mutable GLsizei _textureWidth, _textureHeight, _textureDepth;
// number of mip map levels the the texture has been created with,
mutable GLsizei _numMimpmapLevels;
mutable GLsizei _numMipmapLevels;
ref_ptr<SubloadCallback> _subloadCallback;

View File

@@ -202,9 +202,8 @@ public:
enum DrawModeMask
{
TEXT = 1, /// default
TEXT_PIXMAP = 2,
BOUNDINGBOX = 4,
ALIGNMENT = 8
BOUNDINGBOX = 2,
ALIGNMENT = 4
};
void setDrawMode(unsigned int mode);