2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

Commit a1f23eb3 authored by Christian Schulte zu Berge's avatar Christian Schulte zu Berge
Browse files

* Tied tgt::OpenGLJobProcessor and tgt::OpenGLGarbageCollector closer together...

* Tied tgt::OpenGLJobProcessor and tgt::OpenGLGarbageCollector closer together regarding OpenGL garbage collection
* AutoEvaluationPipeline checks for valid OpenGL state after each processor call (only in debug)
parent 25e14d19
...@@ -194,7 +194,10 @@ namespace campvis { ...@@ -194,7 +194,10 @@ namespace campvis {
void CampVisApplication::deinit() { void CampVisApplication::deinit() {
tgtAssert(_initialized, "Tried to deinitialize uninitialized CampVisApplication."); tgtAssert(_initialized, "Tried to deinitialize uninitialized CampVisApplication.");
GLJobProc.stop(); // Stop all pipeline threads.
for (std::vector<PipelineRecord>::iterator it = _pipelines.begin(); it != _pipelines.end(); ++it) {
it->_pipeline->stop();
}
{ {
// Deinit everything OpenGL related using the local context. // Deinit everything OpenGL related using the local context.
...@@ -215,19 +218,20 @@ namespace campvis { ...@@ -215,19 +218,20 @@ namespace campvis {
tgt::deinitGL(); tgt::deinitGL();
} }
tgt::GlContextManager::deinit(); // MainWindow dtor needs a valid CampVisApplication, so we need to call it here instead of during destruction.
tgt::deinit(); delete _mainWindow;
GLJobProc.stop();
OpenGLJobProcessor::deinit(); OpenGLJobProcessor::deinit();
SimpleJobProcessor::deinit(); SimpleJobProcessor::deinit();
tgt::GlContextManager::deinit();
tgt::deinit();
PropertyWidgetFactory::deinit(); PropertyWidgetFactory::deinit();
ImageRepresentationConverter::deinit(); ImageRepresentationConverter::deinit();
PipelineFactory::deinit(); PipelineFactory::deinit();
// MainWindow dtor needs a valid CampVisApplication, so we need to call it here instead of during destruction.
delete _mainWindow;
_initialized = false; _initialized = false;
} }
......
...@@ -80,8 +80,6 @@ namespace campvis { ...@@ -80,8 +80,6 @@ namespace campvis {
} }
void AbstractPipeline::deinit() { void AbstractPipeline::deinit() {
stop();
deinitAllProperties(); deinitAllProperties();
// deinitialize all processors: // deinitialize all processors:
...@@ -117,7 +115,7 @@ namespace campvis { ...@@ -117,7 +115,7 @@ namespace campvis {
_canvas->getPainter()->paint(); _canvas->getPainter()->paint();
} }
if (!_enabled || !_pipelineDirty) { if (!_stopExecution && (!_enabled || !_pipelineDirty)) {
tgt::GlContextManager::getRef().releaseContext(_canvas, false); tgt::GlContextManager::getRef().releaseContext(_canvas, false);
_evaluationCondition.wait(lock); _evaluationCondition.wait(lock);
tgt::GlContextManager::getRef().acquireContext(_canvas, false); tgt::GlContextManager::getRef().acquireContext(_canvas, false);
......
...@@ -81,7 +81,7 @@ namespace campvis { ...@@ -81,7 +81,7 @@ namespace campvis {
// execute each processor once // execute each processor once
// (AbstractProcessor::process() takes care of executing only invalid processors) // (AbstractProcessor::process() takes care of executing only invalid processors)
for (size_t i = 0; i < _processors.size(); ++i) { for (size_t i = 0; i < _processors.size(); ++i) {
_processors[i]->process(getDataContainer()); executeProcessorAndCheckOpenGLState(_processors[i]);
} }
} }
......
...@@ -37,8 +37,6 @@ namespace tgt { ...@@ -37,8 +37,6 @@ namespace tgt {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
// LDEBUG("Initialized context '" << title << "'");
} }
void GlContextManager::removeContext(GLCanvas* context) { void GlContextManager::removeContext(GLCanvas* context) {
...@@ -77,8 +75,6 @@ namespace tgt { ...@@ -77,8 +75,6 @@ namespace tgt {
ci._acquired = true; ci._acquired = true;
ci._threadId = std::this_thread::get_id(); ci._threadId = std::this_thread::get_id();
context->acquireAsCurrentContext(); context->acquireAsCurrentContext();
// LDEBUG("Acquired context '" << a->second._title << "' from thread " << a->second._threadId);
} }
else { else {
tgtAssert(false, "Could not find the context in map, this should not happen!"); tgtAssert(false, "Could not find the context in map, this should not happen!");
...@@ -102,7 +98,6 @@ namespace tgt { ...@@ -102,7 +98,6 @@ namespace tgt {
if (unlockGlMutex) if (unlockGlMutex)
ci._glMutex->unlock(); ci._glMutex->unlock();
// LDEBUG("Released context '" << a->second._title << "'");
} }
else { else {
tgtAssert(false, "Could not find the context in map, this should not happen!"); tgtAssert(false, "Could not find the context in map, this should not happen!");
......
...@@ -61,19 +61,19 @@ namespace tgt { ...@@ -61,19 +61,19 @@ namespace tgt {
void addGarbageTexture(GLuint id) { void addGarbageTexture(GLuint id) {
tbb::spin_mutex::scoped_lock lock(_addMutex); tbb::spin_mutex::scoped_lock lock(_addMutex);
_texturesToDelete[_currentFrontindex].push_back(id); _texturesToDelete[_currentFrontindex].push_back(id);
GLJobProc.enqueueJob(makeJobOnHeap(this, &OpenGLGarbageCollector::deleteGarbage)); GLJobProc.enqueueGarbageCollection();
}; };
void addGarbageFramebufferObject(GLuint id) { void addGarbageFramebufferObject(GLuint id) {
tbb::spin_mutex::scoped_lock lock(_addMutex); tbb::spin_mutex::scoped_lock lock(_addMutex);
_fbosToDelete[_currentFrontindex].push_back(id); _fbosToDelete[_currentFrontindex].push_back(id);
GLJobProc.enqueueJob(makeJobOnHeap(this, &OpenGLGarbageCollector::deleteGarbage)); GLJobProc.enqueueGarbageCollection();
}; };
void addGarbageBufferObject(GLuint id) { void addGarbageBufferObject(GLuint id) {
tbb::spin_mutex::scoped_lock lock(_addMutex); tbb::spin_mutex::scoped_lock lock(_addMutex);
_buffersToDelete[_currentFrontindex].push_back(id); _buffersToDelete[_currentFrontindex].push_back(id);
GLJobProc.enqueueJob(makeJobOnHeap(this, &OpenGLGarbageCollector::deleteGarbage)); GLJobProc.enqueueGarbageCollection();
}; };
void deleteGarbage(); void deleteGarbage();
......
...@@ -55,6 +55,7 @@ namespace tgt { ...@@ -55,6 +55,7 @@ namespace tgt {
{ {
_pause = 0; _pause = 0;
_context= nullptr; _context= nullptr;
_performGarbageCollection = false;
} }
OpenGLJobProcessor::~OpenGLJobProcessor() { OpenGLJobProcessor::~OpenGLJobProcessor() {
...@@ -90,16 +91,20 @@ namespace tgt { ...@@ -90,16 +91,20 @@ namespace tgt {
// execute and delete the job // execute and delete the job
jobToDo->execute(); jobToDo->execute();
delete jobToDo; delete jobToDo;
performGarbageCollectionIfNecessary();
} }
while (_pause > 0) { while (_pause > 0 && !_stopExecution) {
performGarbageCollectionIfNecessary();
tgt::GlContextManager::getRef().releaseContext(_context, false); tgt::GlContextManager::getRef().releaseContext(_context, false);
_evaluationCondition.wait(lock); _evaluationCondition.wait(lock);
tgt::GlContextManager::getRef().acquireContext(_context, false); tgt::GlContextManager::getRef().acquireContext(_context, false);
hadWork = true; hadWork = true;
} }
if (! hadWork) { if (! hadWork && !_stopExecution) {
performGarbageCollectionIfNecessary();
tgt::GlContextManager::getRef().releaseContext(_context, false); tgt::GlContextManager::getRef().releaseContext(_context, false);
_evaluationCondition.wait(lock); _evaluationCondition.wait(lock);
tgt::GlContextManager::getRef().acquireContext(_context, false); tgt::GlContextManager::getRef().acquireContext(_context, false);
...@@ -139,6 +144,18 @@ namespace tgt { ...@@ -139,6 +144,18 @@ namespace tgt {
return _context; return _context;
} }
void OpenGLJobProcessor::enqueueGarbageCollection() {
_performGarbageCollection = true;
_evaluationCondition.notify_all();
}
void OpenGLJobProcessor::performGarbageCollectionIfNecessary() {
if (_performGarbageCollection && tgt::OpenGLGarbageCollector::isInited()) {
_performGarbageCollection = false;
GLGC.deleteGarbage();
}
}
} }
...@@ -119,13 +119,24 @@ namespace tgt { ...@@ -119,13 +119,24 @@ namespace tgt {
*/ */
void enqueueJob(AbstractJob* job); void enqueueJob(AbstractJob* job);
/**
* Enqueue OpenGL Garbage collection job
*/
void enqueueGarbageCollection();
protected: protected:
/**
* Performs a OpenGL Garbage Collection if necessary.
*/
void performGarbageCollectionIfNecessary();
// Protected constructor since it's a singleton // Protected constructor since it's a singleton
OpenGLJobProcessor(); OpenGLJobProcessor();
tgt::GLCanvas* _context; ///< The OpenGL context to use tgt::GLCanvas* _context; ///< The OpenGL context to use
tbb::concurrent_queue<AbstractJob*> _jobQueue; ///< The OpenGL job queue tbb::concurrent_queue<AbstractJob*> _jobQueue; ///< The OpenGL job queue
tbb::atomic<bool> _performGarbageCollection; ///< Flag whether to perform garbage cxollection
tbb::atomic<int> _pause; ///< Counter of pause requests tbb::atomic<int> _pause; ///< Counter of pause requests
std::condition_variable _evaluationCondition; ///< conditional wait to be used when there are currently no jobs to process std::condition_variable _evaluationCondition; ///< conditional wait to be used when there are currently no jobs to process
......
...@@ -67,6 +67,7 @@ namespace campvis { ...@@ -67,6 +67,7 @@ namespace campvis {
} }
void AdvOptimizedRaycaster::processImpl(DataContainer& data, ImageRepresentationGL::ScopedRepresentation& image) { void AdvOptimizedRaycaster::processImpl(DataContainer& data, ImageRepresentationGL::ScopedRepresentation& image) {
_shader->deactivate();
if (getInvalidationLevel() & INVALID_BBV){ if (getInvalidationLevel() & INVALID_BBV){
_vhm->createHierarchy(image, p_transferFunction.getTF()); _vhm->createHierarchy(image, p_transferFunction.getTF());
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment