diff --git a/src/osg/Drawable.cpp b/src/osg/Drawable.cpp index f0053c120..8441e6244 100644 --- a/src/osg/Drawable.cpp +++ b/src/osg/Drawable.cpp @@ -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 > DeletedDisplayListCache; +typedef std::vector DisplayListVector; +typedef std::map 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& displayListSet = citr->second; - for(std::set::iterator gitr=displayListSet.begin(); - gitr!=displayListSet.end(); - ++gitr) - { - glDeleteLists(*gitr,1); - } - - s_deletedDisplayListCache.erase(citr); - } -} void Drawable::setUpdateCallback(UpdateCallback* ac) { diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 38da00045..3fc1323cf 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -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 TextureObjectVector; +typedef std::map 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 #include -// static cache of deleted display lists which can only -// by completely deleted once the appropriate OpenGL context -// is set. -typedef std::map > 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& textureObjectSet = citr->second; - for(std::set::iterator titr=textureObjectSet.begin(); - titr!=textureObjectSet.end(); - ++titr) - { - glDeleteTextures( 1L, &(*titr )); - } - s_deletedTextureObjectCache.erase(citr); - } -} void Texture::compile(State& state) const { diff --git a/src/osgPlugins/txp/trPagePageManager.h b/src/osgPlugins/txp/trPagePageManager.h index 29e87adbf..630e264d3 100644 --- a/src/osgPlugins/txp/trPagePageManager.h +++ b/src/osgPlugins/txp/trPagePageManager.h @@ -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 {