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

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