Starting from 2021-07-01, all LRZ GitLab users will be required to explicitly accept the GitLab Terms of Service. Please see the detailed information at https://doku.lrz.de/display/PUBLIC/GitLab and make sure that your projects conform to the requirements.

Commit 6eeb3b4f authored by schultezub's avatar schultezub
Browse files

added DAG Visualization Pipeline stub

some minor tweaks

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@291 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent c2b0b6fb
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb@in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universitt Mnchen
// Boltzmannstr. 3, 85748 Garching b. Mnchen, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#include "digraphvisualizationpipeline.h"
#include "tgt/tgt_gl.h"
#include "tgt/glcanvas.h"
#include "tgt/glcontext.h"
#include "core/datastructures/imagedatarendertarget.h"
#include "core/pipeline/visualizationprocessor.h"
#include "core/tools/job.h"
#include "core/tools/opengljobprocessor.h"
#include <stack>
namespace TUMVis {
const std::string DigraphVisualizationPipeline::loggerCat_ = "TUMVis.core.datastructures.DigraphVisualizationPipeline";
DigraphVisualizationPipeline::DependencyNode::DependencyNode(AbstractProcessor* processor)
: _processor(processor)
{
tgtAssert(_processor != 0, "Processor must not be 0.");
if (_processor != 0) {
_isVisualizationProcessor = (dynamic_cast<VisualizationProcessor*>(_processor) != 0);
}
}
void DigraphVisualizationPipeline::DependencyNode::addDependency(DependencyNode* dependency) {
tgtAssert(dependency != 0, "DependencyNode must not be 0.");
// check for acyclicness
std::stack<DependencyNode*> nodesToVisit;
for (std::set<DependencyNode*>::const_iterator it = dependency->_dependentNodes.begin(); it != dependency->_dependentNodes.end(); ++it) {
nodesToVisit.push(*it);
}
while (! nodesToVisit.empty()) {
DependencyNode* node = nodesToVisit.top();
nodesToVisit.pop();
if (node == this) {
LERROR("Circle in dependency graph detected. DependencyNode insertion aborted.");
return;
}
for (std::set<DependencyNode*>::const_iterator it = dependency->_dependentNodes.begin(); it != dependency->_dependentNodes.end(); ++it) {
nodesToVisit.push(*it);
}
}
// add dependency
_dependentNodes.insert(dependency);
}
// ================================================================================================
DigraphVisualizationPipeline::DigraphVisualizationPipeline()
: VisualizationPipeline()
{
}
DigraphVisualizationPipeline::~DigraphVisualizationPipeline() {
// delete all DependencyNodes
for (std::map<AbstractProcessor*, DependencyNode*>::iterator it = _processorNodeMap.begin(); it != _processorNodeMap.end(); ++it) {
delete it->second;
}
}
void DigraphVisualizationPipeline::addProcessor(AbstractProcessor* processor) {
tgtAssert(processor != 0, "Processor must not be 0!");
// add processor to processor list and connect signals
_processors.push_back(processor);
processor->s_invalidated.connect<DigraphVisualizationPipeline>(this, &DigraphVisualizationPipeline::onProcessorInvalidated);
// create DependencyNode
std::map<AbstractProcessor*, DependencyNode*>::iterator lb = _processorNodeMap.lower_bound(processor);
if (lb == _processorNodeMap.end() || lb->first != processor) {
DependencyNode* node = new DependencyNode(processor);
_processorNodeMap.insert(lb, std::make_pair(processor, node));
}
else {
LDEBUG("Processor already added!");
}
}
void DigraphVisualizationPipeline::addProcessorDependency(AbstractProcessor* fatherProc, AbstractProcessor* childProc) {
tgtAssert(fatherProc != 0, "Father Processor must not be 0!");
tgtAssert(childProc != 0, "Child Processor must not be 0!");
// find corresponding DependencyNodes
std::map<AbstractProcessor*, DependencyNode*>::iterator fatherNode = _processorNodeMap.find(fatherProc);
std::map<AbstractProcessor*, DependencyNode*>::iterator childNode = _processorNodeMap.find(childProc);
if (fatherNode == _processorNodeMap.end() || childNode == _processorNodeMap.end()) {
tgtAssert(false, "Add processors first before defining dependencies between them!");
LERROR("Could not find DependencyNodes for at least one of the given processors. No dependency added!");
return;
}
// add dependency
fatherNode->second->addDependency(childNode->second);
}
void DigraphVisualizationPipeline::onProcessorInvalidated(const AbstractProcessor* processor) {
// TODO: implement
}
}
// ================================================================================================
//
// This file is part of the TUMVis Visualization Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012, all rights reserved,
// Christian Schulte zu Berge (christian.szb@in.tum.de)
// Chair for Computer Aided Medical Procedures
// Technische Universität München
// Boltzmannstr. 3, 85748 Garching b. München, Germany
//
// The licensing of this softare is not yet resolved. Until then, redistribution in source or
// binary forms outside the CAMP chair is not permitted, unless explicitly stated in legal form.
// However, the names of the original authors and the above copyright notice must retain in its
// original state in any case.
//
// Legal disclaimer provided by the BSD license:
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// ================================================================================================
#ifndef DIGRAPHVISUALIZATIONPIPELINE_H__
#define DIGRAPHVISUALIZATIONPIPELINE_H__
#include "sigslot/sigslot.h"
#include "tgt/vector.h"
#include "tgt/event/eventlistener.h"
#include "core/eventhandlers/abstracteventhandler.h"
#include "core/pipeline/visualizationpipeline.h"
#include "core/properties/genericproperty.h"
#include <map>
#include <set>
namespace TUMVis {
class VisualizationProcessor;
/**
* Specialization of the VisualizationPipeline that performs automatic evaluation based on
* an acyclic directed dependency graph.
*
* \todo Think about thread-safety. The current graph implementation is \b not thread-safe.
*/
class DigraphVisualizationPipeline : public VisualizationPipeline {
public:
/**
* Creates a DigraphVisualizationPipeline.
*/
DigraphVisualizationPipeline();
/**
* Virtual Destructor
**/
virtual ~DigraphVisualizationPipeline();
/**
* Execute this pipeline.
* Pipeline must have a valid canvas set before calling this method.
**/
virtual void execute() = 0;
/**
* Adds a processor to this pipeline, so that it will be managed.
*
* \note Add each processor only once!
* \param processor Processor to add
*/
void addProcessor(AbstractProcessor* processor);
/**
* Adds a dependency link between two processors.
* The processor \a childProc needs to be executed every time when \a fatherProc has been evaluated.
* \note Add each dependency between two processors only once!
* \param fatherProc The processor \a childProc is dependent on.
* \param childProc The dependent processor of \a fatherProc.
*/
void addProcessorDependency(AbstractProcessor* fatherProc, AbstractProcessor* childProc);
protected:
/**
* Struct for the nodes defining the processor evaluation dependency graph.
* Each Node represents one processor and stores the processors which are dependent on this
* processors, hence, the ones which need to be updated afterwards.
*
* \todo This struct is \b not thread-safe!
*/
struct DependencyNode {
/**
* Creates a new DependencyNode for the given Processor
* \param processor The processor this node represents. Must not be 0.
*/
DependencyNode(AbstractProcessor* processor);
/**
* Adds the given DependencyNode as dependency (child) of this node.
* \param dependency DependencyNode containing a processor which needs to be updated after this one.
*/
void addDependency(DependencyNode* dependency);
AbstractProcessor* _processor; ///< Processor this node wraps around
bool _isVisualizationProcessor; ///< Flag whether \a _processor is a VisualizationProcessor (hence, needs an OpenGL context)
std::set<DependencyNode*> _dependentNodes; ///< Set of all dependent nodes.
};
/**
* Slot getting called when one of the observed processors got invalidated.
* The default behaviour is just to set the invalidation level to invalid.
* \param processor The processor that emitted the signal
*/
virtual void onProcessorInvalidated(const AbstractProcessor* processor);
static const std::string loggerCat_;
std::map<AbstractProcessor*, DependencyNode*> _processorNodeMap;
tbb::atomic<DependencyNode*> _topNodeToEvaluate;
};
}
#endif // DIGRAPHVISUALIZATIONPIPELINE_H__
......@@ -85,7 +85,7 @@ namespace TUMVis {
protected:
T* _target; ///< Target object
void (T::*_callee)(); /// <Member function to call
void (T::*_callee)(); /// <Member function to call
};
/**
......@@ -124,7 +124,7 @@ namespace TUMVis {
protected:
T* _target; ///< Target object
void (T::*_callee)(A1); /// <Member function to call
A1 _arg1; ///< Argument to pass to \a callee
A1 _arg1; ///< Argument to pass to \a callee
};
}
......
......@@ -36,7 +36,6 @@ namespace TUMVis {
OpenGLJobProcessor::OpenGLJobProcessor()
: _currentContext(0)
, _startTimeCurrentContext(0)
{
}
......@@ -70,7 +69,7 @@ namespace TUMVis {
clock_t maxTimePerContext = 30 / _contexts.size();
for (size_t i = 0; i < _contexts.size(); ++i) {
_startTimeCurrentContext = clock() * 1000 / CLOCKS_PER_SEC;
clock_t startTimeCurrentContext = clock() * 1000 / CLOCKS_PER_SEC;
tgt::GLCanvas* context = _contexts[i];
tbb::concurrent_hash_map<tgt::GLCanvas*, PerContextJobQueue*>::const_accessor a;
......@@ -99,7 +98,7 @@ namespace TUMVis {
// now comes the per-context scheduling strategy:
// first: perform as much serial jobs as possible:
AbstractJob* jobToDo = 0;
while ((clock() * 1000 / CLOCKS_PER_SEC) - _startTimeCurrentContext < maxTimePerContext) {
while ((clock() * 1000 / CLOCKS_PER_SEC) - startTimeCurrentContext < maxTimePerContext) {
// try fetch a job
if (! a->second->_serialJobs.try_pop(jobToDo)) {
// no job to do, exit the while loop
......
......@@ -158,7 +158,6 @@ namespace TUMVis {
std::condition_variable _evaluationCondition; ///< conditional wait to be used when there are currently no jobs to process
tgt::GLCanvas* _currentContext; ///< current active OpenGL context
clock_t _startTimeCurrentContext; ///<
};
}
......
......@@ -192,13 +192,14 @@ namespace TUMVis {
}
if (!_dvrVM.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_dvrVM);
}
if (!_clRaycaster.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_clRaycaster);
lockGLContextAndExecuteProcessor(&_combine);
}
if (!_combine.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_combine);
}
if (!_clRaycaster.getInvalidationLevel().isValid()) {
lockGLContextAndExecuteProcessor(&_clRaycaster);
}
}
const std::string DVRVis::getName() const {
......
......@@ -170,6 +170,7 @@ namespace TUMVis {
LGL_ERROR;
data.addData(_targetImageID.getValue(), rt);
_targetImageID.issueWrite();
}
else {
LERROR("Entry-/Exitpoints texture size does not match.");
......
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