Currently job artifacts in CI/CD pipelines on LRZ GitLab never expire. Starting from Wed 26.1.2022 the default expiration time will be 30 days (GitLab default). Currently existing artifacts in already completed jobs will not be affected by the change. The latest artifacts for all jobs in the latest successful pipelines will be kept. More information: https://gitlab.lrz.de/help/user/admin_area/settings/continuous_integration.html#default-artifacts-expiration

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