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 4609c893 authored by schultezub's avatar schultezub
Browse files

* started implementing proper deinitialization of everything

 * added Runnable interface
 * started letting PipelineEvaluator manage its thread itself
 * documentation

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@196 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent 1302ca97
......@@ -12,8 +12,6 @@
#include "core/pipeline/pipelineevaluator.h"
#include "modules/pipelines/slicevis.h"
#include <functional>
using namespace TUMVis;
SliceVis* sliceVis = 0;
......@@ -44,7 +42,6 @@ int main(int argc, char** argv) {
tbb::task_scheduler_init init;
renderCanvas->getContext()->acquire();
app->addCanvas(renderCanvas);
//app->addCanvas(sliceVisCanvas);
app->init();
LogMgr.getConsoleLog()->addCat("", true);
LGL_ERROR;
......@@ -92,6 +89,12 @@ int main(int argc, char** argv) {
evaluatorThread.join();
painterThread.join();
sliceVis->deinit();
painter->deinit();
tgt::deinitGL();
tgt::QtContextManager::deinit();
tgt::deinit();
delete painter;
delete sliceVis;
delete app;
......
......@@ -89,7 +89,6 @@ namespace TUMVis {
void TumVisPainter::sizeChanged(const tgt::ivec2& size) {
_pipeline->setRenderTargetSize(size);
_renderCondition.wakeAll();
}
void TumVisPainter::init() {
......@@ -102,6 +101,10 @@ namespace TUMVis {
}
}
void TumVisPainter::deinit() {
ShdrMgr.dispose(_copyShader);
}
void TumVisPainter::setPipeline(VisualizationPipeline* pipeline) {
tgtAssert(pipeline != 0, "The given pipeline must not be 0.");
if (_pipeline != 0) {
......
......@@ -26,6 +26,7 @@ namespace TUMVis {
virtual void paint();
virtual void sizeChanged(const tgt::ivec2& size);
virtual void init();
virtual void deinit();
void setPipeline(VisualizationPipeline* pipeline);
void onPipelineInvalidated();
......
......@@ -27,6 +27,18 @@ namespace TUMVis {
}
}
void AbstractPipeline::deinit() {
// deinitialize all processors:
for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
try {
(*it)->deinit();
}
catch (tgt::Exception& e) {
LERROR("Caught Exception during deinitialization of processor: " << e.what());
}
}
}
void AbstractPipeline::onNotify(const ProcessorObserverArgs& poa) {
_invalidationLevel.setLevel(InvalidationLevel::INVALID_RESULT);
s_PipelineInvalidated();
......@@ -42,10 +54,6 @@ namespace TUMVis {
processor.unlockProperties();
}
tbb::mutex& AbstractPipeline::getEvaluationMutex() {
return _evaluationMutex;
}
InvalidationLevel& AbstractPipeline::getInvalidationLevel() {
return _invalidationLevel;
}
......
......@@ -15,12 +15,14 @@
#include <vector>
namespace TUMVis {
class PipelineEvaluator;
/**
* Abstract base class for TUMVis Pipelines.
*
*/
class AbstractPipeline : public GenericObserver<ProcessorObserverArgs> {
friend class PipelineEvaluator;
public:
/**
* Creates a AbstractPipeline.
......@@ -34,12 +36,19 @@ namespace TUMVis {
/**
* Initializes the OpenGL context of the pipeline and its processors.
* Initializes this pipeline and all of its processors.
* Everything that requires a valid OpenGL context or is otherwise expensive gets in here.
*
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void init();
/**
* Deinitializes this pipeline and all of its processors.
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void deinit();
/**
* Execute this pipeline.
**/
......@@ -65,8 +74,6 @@ namespace TUMVis {
*/
virtual void onNotify(const ProcessorObserverArgs& poa);
tbb::mutex& getEvaluationMutex();
InvalidationLevel& getInvalidationLevel();
......@@ -85,7 +92,7 @@ namespace TUMVis {
InvalidationLevel _invalidationLevel; ///< current invalidation level
tbb::spin_mutex _localMutex; ///< mutex for altering local members
tbb::mutex _evaluationMutex; ///< mutex for the evaluation of this pipeline
tbb::mutex _evaluationMutex; ///< mutex for the evaluation of this pipeline
static const std::string loggerCat_;
};
......
......@@ -34,9 +34,12 @@ namespace TUMVis {
}
void AbstractProcessor::init() {
}
void AbstractProcessor::deinit() {
}
void AbstractProcessor::lockProperties() {
_properties.lockAllProperties();
}
......
......@@ -69,10 +69,18 @@ namespace TUMVis {
/**
* Initializes the OpenGL context of the processor.
* Initializes the processor.
* Everything that requires a valid OpenGL context or is otherwise expensive gets in here.
*
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void init();
/**
* Deinitializes this processors.
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void deinit();
/**
* Execute this processor.
......
......@@ -6,19 +6,21 @@ namespace TUMVis {
PipelineEvaluator::PipelineEvaluator(AbstractPipeline* pipeline)
: _pipeline(pipeline)
, _evaluatePipeline(false)
, _evaluationThread()
{
tgtAssert(pipeline != 0, "Pipeline must not be 0.");
_evaluatePipeline = false;
pipeline->s_PipelineInvalidated.connect(this, &PipelineEvaluator::OnPipelineInvalidated);
}
PipelineEvaluator::~PipelineEvaluator() {
_pipeline->s_PipelineInvalidated.disconnect(this);
}
void PipelineEvaluator::startEvaluation() {
_evaluatePipeline = true;
std::unique_lock<tbb::mutex> lock(_pipeline->getEvaluationMutex());
std::unique_lock<tbb::mutex> lock(_pipeline->_evaluationMutex);
while (_evaluatePipeline) {
_pipeline->execute();
......
......@@ -3,12 +3,14 @@
#include "sigslot/sigslot.h"
#include "core/pipeline/abstractpipeline.h"
#include "tbb/include/tbb/compat/thread"
#include "tbb/include/tbb/compat/condition_variable"
#include "tbb/include/tbb/atomic.h"
namespace TUMVis {
/**
*
* The PipelineEvaluator
*/
class PipelineEvaluator : public sigslot::has_slots<> {
public:
......@@ -18,16 +20,18 @@ namespace TUMVis {
void startEvaluation();
void stopEvaluation();
void evaluate();
void OnPipelineInvalidated();
protected:
AbstractPipeline* _pipeline;
bool _evaluatePipeline;
tbb::atomic<bool> _evaluatePipeline;
std::thread _evaluationThread;
std::condition_variable _evaluationCondition;
static const std::string loggerCat_;
......
......@@ -45,6 +45,11 @@ namespace TUMVis {
AbstractPipeline::init();
}
void VisualizationPipeline::deinit() {
tgt::GLContextScopedLock lock(_canvas->getContext());
AbstractPipeline::deinit();
}
const tgt::ivec2& VisualizationPipeline::getRenderTargetSize() const {
return _renderTargetSize.getValue();
}
......@@ -66,7 +71,7 @@ namespace TUMVis {
void VisualizationPipeline::lockGLContextAndExecuteProcessor(AbstractProcessor& processor) {
tgt::GLContextScopedLock lock(_canvas->getContext());
executeProcessor(processor);
glFlush();
glFlush(); // TODO: is glFlush enough or do we need a glFinish here?
}
}
......@@ -39,6 +39,12 @@ namespace TUMVis {
*/
virtual void init();
/**
* Deinitializes this pipeline and all of its processors.
* \note When overwriting this method, make sure to call the base class version first.
*/
virtual void deinit();
/**
* Execute this pipeline.
**/
......@@ -86,7 +92,7 @@ namespace TUMVis {
*/
void onDataContainerDataAdded(const std::string& name, const DataHandle* dh);
/// Signal emitted when the pipeline's render target has changed
sigslot::signal0<> s_renderTargetChanged;
protected:
......
......@@ -4,9 +4,10 @@ namespace TUMVis {
VisualizationProcessor::VisualizationProcessor(GenericProperty<tgt::ivec2>& canvasSize)
: AbstractProcessor()
, _canvasSize("canvasSize", "Canvas Size", canvasSize.getValue())
, _renderTargetSize("canvasSize", "Canvas Size", canvasSize.getValue())
{
canvasSize.addSharedProperty(&_canvasSize);
canvasSize.addSharedProperty(&_renderTargetSize);
_renderTargetSize.addObserver(this);
}
VisualizationProcessor::~VisualizationProcessor() {
......
......@@ -9,25 +9,25 @@
namespace TUMVis {
/**
* Abstract base class for TUMVis Processors.
* A processor implements a specific task, which it performs on the DataCollection passed
* during process(). Properties provide a transparent layer for adjusting the processor's
* behaviour.
* Once a processor has finished it sets it should set its invalidation level to valid. As
* soon as one of its properties changes, the processor will be notified and possibliy
* change its invalidation level. Observing pipelines will be notified of this and can
* and have to decide which part of the pipeline has to be re-evaluated wrt. the processor's
* invalidation level.
* Specialization of AbstractProcessor for visualization purposes.
* VisualizationProcessors are required to be called by a VisualizationPipeline which ensure
* to provide a valid OpenGL context when calling the processor's process() method. Hence, a
* VisualizationProcessor is allowed/capable of performing OpenGl operations.
* For determining the canvas/viewport size, a VisualizationProcessor gets a reference to the
* parent pipeline's render target size property during instantiation.
*
* \sa AbstractPipeline
* \sa VisualizationPipeline
*/
class VisualizationProcessor : public AbstractProcessor {
public:
/**
* Creates a VisualizationProcessor.
* \note The render target size property of this VisualizationProcessor will automatically
* be assigned as shared property of the given \a renderTargetSize property.
* \param renderTargetSize Reference to the parent pipeline's render target size property.
*/
VisualizationProcessor(GenericProperty<tgt::ivec2>& canvasSize);
VisualizationProcessor(GenericProperty<tgt::ivec2>& renderTargetSize);
/**
* Virtual Destructor
......@@ -36,7 +36,7 @@ namespace TUMVis {
protected:
GenericProperty<tgt::ivec2> _canvasSize; ///< Viewport size of target canvas
GenericProperty<tgt::ivec2> _renderTargetSize; ///< Viewport size of target canvas
};
}
......
#ifndef RUNNABLE_H__
#define RUNNABLE_H__
#include "tgt/logmanager.h"
#include "tbb/include/tbb/compat/thread"
#include "tbb/include/tbb/atomic.h"
namespace TUMVis {
/**
* Abstract base class for objects that shall run in a separate thread.
*/
class Runnable {
public:
Runnable()
: _stopExecution()
, _thread()
{}
virtual ~Runnable() {
stop();
}
virtual void stop() {
_stopExecution = true;
try {
_thread.join();
}
catch(std::exception& e) {
LERRORC("TUMVis.core.tools.Runnable", "Caught exception during _thread.join: " << e.what());
}
}
void start() {
_thread = std::thread(&Runnable::run, *this);
}
protected:
virtual void run() = 0;
tbb::atomic<bool> _stopExecution;
private:
Runnable(Runnable const&) = delete;
Runnable& operator =(Runnable const&) = delete;
std::thread _thread;
};
}
#endif // RUNNABLE_H__
......@@ -67,7 +67,6 @@ public:
// override Qt events so that they don't interfere with the threading.
void resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
sizeChanged(ivec2(event->size().width(), event->size().height()));
};
......
......@@ -31,6 +31,10 @@ namespace TUMVis {
_shader = ShdrMgr.loadSeparate("core/glsl/passthrough.vert", "modules/vis/sliceextractor.frag", "", false);
}
void SliceExtractor::deinit() {
ShdrMgr.dispose(_shader);
}
void SliceExtractor::process(DataContainer& data) {
const ImageDataLocal* img = data.getTypedData<ImageDataLocal>(_sourceImageID.getValue());
......@@ -40,7 +44,7 @@ namespace TUMVis {
const tgt::svec3& imgSize = img->getSize();
ImageDataLocal* slice = img->getSubImage(tgt::svec3(0, 0, _sliceNumber.getValue()), tgt::svec3(imgSize.x-1, imgSize.y-1, _sliceNumber.getValue()));
ImageDataGL* glData = ImageDataConverter::tryConvert<ImageDataGL>(slice);
ImageDataRenderTarget* rt = new ImageDataRenderTarget(tgt::svec3(_canvasSize.getValue(), 1));
ImageDataRenderTarget* rt = new ImageDataRenderTarget(tgt::svec3(_renderTargetSize.getValue(), 1));
_shader->activate();
tgt::TextureUnit inputUnit;
......
......@@ -26,9 +26,12 @@ namespace TUMVis {
**/
virtual ~SliceExtractor();
/// \see AbstractProcessor::init
virtual void init();
/// \see AbstractProcessor::deinit
virtual void deinit();
virtual void process(DataContainer& data);
GenericProperty<std::string> _sourceImageID; ///< image ID for input image
......
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