Changed the implementation of the texture objects and display list to delete
caches so that they use a std::vector<> swap on the internal data structures when ready to delete to minimize the amount of time that a race condition condition can happen.
This commit is contained in:
@@ -28,9 +28,42 @@ using namespace osg;
|
||||
// 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::map<GLuint,std::set<GLuint> > DeletedDisplayListCache;
|
||||
typedef std::vector<GLuint> DisplayListVector;
|
||||
typedef std::map<GLuint,DisplayListVector> DeletedDisplayListCache;
|
||||
static DeletedDisplayListCache s_deletedDisplayListCache;
|
||||
|
||||
void Drawable::deleteDisplayList(uint contextID,uint globj)
|
||||
{
|
||||
if (globj!=0)
|
||||
{
|
||||
// insert the globj into the cache for the appropriate context.
|
||||
s_deletedDisplayListCache[contextID].push_back(globj);
|
||||
}
|
||||
}
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
void Drawable::flushDeletedDisplayLists(uint contextID)
|
||||
{
|
||||
DeletedDisplayListCache::iterator citr = s_deletedDisplayListCache.find(contextID);
|
||||
if (citr!=s_deletedDisplayListCache.end())
|
||||
{
|
||||
DisplayListVector displayListSet;
|
||||
|
||||
// this swap will transfer the content of and empty citr->second
|
||||
// in one quick pointer change.
|
||||
displayListSet.swap(citr->second);
|
||||
|
||||
for(std::DisplayListVector::iterator gitr=displayListSet.begin();
|
||||
gitr!=displayListSet.end();
|
||||
++gitr)
|
||||
{
|
||||
glDeleteLists(*gitr,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Drawable::Drawable()
|
||||
{
|
||||
_bbox_computed = false;
|
||||
@@ -198,33 +231,6 @@ void Drawable::dirtyDisplayList()
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::deleteDisplayList(uint contextID,uint globj)
|
||||
{
|
||||
if (globj!=0)
|
||||
{
|
||||
// insert the globj into the cache for the appropriate context.
|
||||
s_deletedDisplayListCache[contextID].insert(globj);
|
||||
}
|
||||
}
|
||||
|
||||
/** flush all the cached display list which need to be deleted
|
||||
* in the OpenGL context related to contextID.*/
|
||||
void Drawable::flushDeletedDisplayLists(uint contextID)
|
||||
{
|
||||
DeletedDisplayListCache::iterator citr = s_deletedDisplayListCache.find(contextID);
|
||||
if (citr!=s_deletedDisplayListCache.end())
|
||||
{
|
||||
std::set<GLuint>& displayListSet = citr->second;
|
||||
for(std::set<GLuint>::iterator gitr=displayListSet.begin();
|
||||
gitr!=displayListSet.end();
|
||||
++gitr)
|
||||
{
|
||||
glDeleteLists(*gitr,1);
|
||||
}
|
||||
|
||||
s_deletedDisplayListCache.erase(citr);
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::setUpdateCallback(UpdateCallback* ac)
|
||||
{
|
||||
|
||||
@@ -23,6 +23,44 @@ using namespace osg;
|
||||
#define GL_TEXTURE_WRAP_R 0x8072
|
||||
#endif
|
||||
|
||||
// static cache of deleted display lists which can only
|
||||
// by completely deleted once the appropriate OpenGL context
|
||||
// is set.
|
||||
typedef std::vector<GLuint> TextureObjectVector;
|
||||
typedef std::map<osg::uint,TextureObjectVector> DeletedTextureObjectCache;
|
||||
static DeletedTextureObjectCache s_deletedTextureObjectCache;
|
||||
|
||||
|
||||
void Texture::deleteTextureObject(uint contextID,GLuint handle)
|
||||
{
|
||||
if (handle!=0)
|
||||
{
|
||||
// insert the handle into the cache for the appropriate context.
|
||||
s_deletedTextureObjectCache[contextID].push_back(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Texture::flushDeletedTextureObjects(uint contextID)
|
||||
{
|
||||
DeletedTextureObjectCache::iterator citr = s_deletedTextureObjectCache.find(contextID);
|
||||
if (citr!=s_deletedTextureObjectCache.end())
|
||||
{
|
||||
TextureObjectVector textureObjectSet;
|
||||
|
||||
// this swap will transfer the content of and empty citr->second
|
||||
// in one quick pointer change.
|
||||
textureObjectSet.swap(citr->second);
|
||||
for(TextureObjectVector::iterator titr=textureObjectSet.begin();
|
||||
titr!=textureObjectSet.end();
|
||||
++titr)
|
||||
{
|
||||
glDeleteTextures( 1L, &(*titr ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Texture::Texture():
|
||||
_wrap_s(CLAMP),
|
||||
_wrap_t(CLAMP),
|
||||
@@ -450,38 +488,6 @@ void Texture::applyTexImage2D(GLenum target, Image* image, State& state, GLsizei
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
// static cache of deleted display lists which can only
|
||||
// by completely deleted once the appropriate OpenGL context
|
||||
// is set.
|
||||
typedef std::map<osg::uint,std::set<GLuint> > DeletedTextureObjectCache;
|
||||
static DeletedTextureObjectCache s_deletedTextureObjectCache;
|
||||
|
||||
|
||||
void Texture::deleteTextureObject(uint contextID,GLuint handle)
|
||||
{
|
||||
if (handle!=0)
|
||||
{
|
||||
// insert the handle into the cache for the appropriate context.
|
||||
s_deletedTextureObjectCache[contextID].insert(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Texture::flushDeletedTextureObjects(uint contextID)
|
||||
{
|
||||
DeletedTextureObjectCache::iterator citr = s_deletedTextureObjectCache.find(contextID);
|
||||
if (citr!=s_deletedTextureObjectCache.end())
|
||||
{
|
||||
std::set<GLuint>& textureObjectSet = citr->second;
|
||||
for(std::set<GLuint>::iterator titr=textureObjectSet.begin();
|
||||
titr!=textureObjectSet.end();
|
||||
++titr)
|
||||
{
|
||||
glDeleteTextures( 1L, &(*titr ));
|
||||
}
|
||||
s_deletedTextureObjectCache.erase(citr);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::compile(State& state) const
|
||||
{
|
||||
|
||||
@@ -37,7 +37,12 @@
|
||||
|
||||
// Dec 2002, Robert Osfield -> comment out now, as we actually do want to delete in the main thread
|
||||
// as the deletion of the display and texture object isn't thread safe.
|
||||
// #define USE_THREADLOOP_DELETE
|
||||
// Jan 2002, Robert osfield -> comment back in now, as I've changed the way the
|
||||
// glDelete part is handled so that its much less likely to hit a race condtion,
|
||||
// in theory its still not thread safe, but a point swap should be much faster
|
||||
// and less likely to encounter a race condition on the static caches of display
|
||||
// and texture object lists.
|
||||
#define USE_THREADLOOP_DELETE
|
||||
|
||||
namespace txp
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user