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

* made Processor execution time measurement runtime-configurable

* fixed transfer function shader
* let processor unlock call after execution be handled by seperate thread

git-svn-id: https://camplinux.in.tum.de/svn/campvis/trunk@494 bb408c1c-ae56-11e1-83d9-df6b3e0c105e
parent dffa84eb
......@@ -38,7 +38,8 @@ namespace campvis {
namespace {
const int COLUMN_NAME = 0;
const int COLUMN_ENABLED_STATE = 1;
const int COLUMN_DESCRIPTION = 2;
const int COLUMN_CLOCK_STATE = 2;
const int COLUMN_DESCRIPTION = 3;
}
// = TreeModel items ==============================================================================
......@@ -102,6 +103,8 @@ namespace campvis {
case Qt::CheckStateRole:
if (column == COLUMN_ENABLED_STATE)
return _processor->getEnabled() ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
else if (column == COLUMN_CLOCK_STATE)
return _processor->getClockExecutionTime() ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
else
return QVariant();
case Qt::UserRole:
......@@ -121,6 +124,12 @@ namespace campvis {
return true;
}
}
else if (column == COLUMN_CLOCK_STATE) {
if (role == Qt::CheckStateRole) {
_processor->setClockExecutionTime(value == Qt::Checked ? true : false);
return true;
}
}
return false;
}
......@@ -136,6 +145,8 @@ namespace campvis {
return QVariant(QString("Description"));
else if (column == COLUMN_ENABLED_STATE)
return QVariant(QString("Enabled"));
else if (column == COLUMN_CLOCK_STATE)
return QVariant(QString("Clock"));
}
return QVariant();
......@@ -184,6 +195,8 @@ namespace campvis {
return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
case COLUMN_ENABLED_STATE:
return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
case COLUMN_CLOCK_STATE:
return QAbstractItemModel::flags(index) | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
}
return 0;
......@@ -241,7 +254,7 @@ namespace campvis {
}
int PipelineTreeModel::columnCount(const QModelIndex &parent /*= QModelIndex()*/) const {
return 3;
return 4;
}
void PipelineTreeModel::setData(const std::vector<AbstractPipeline*>& pipelines) {
......
......@@ -43,9 +43,9 @@ struct TFParameters2D {
*/
float mapIntensityToTFDomain(in vec2 intensityDomain, in float intensity) {
if(intensity < intensityDomain.x)
return 0.0;
return -1.0;
else if(intensity > intensityDomain.y)
return 1.0;
return -1.0;
else
return (intensity - intensityDomain.x) / (intensityDomain.y - intensityDomain.x);
}
......
......@@ -88,7 +88,7 @@ namespace campvis {
void AbstractPipeline::onProcessorInvalidated(AbstractProcessor* processor) {
if (processor->getEnabled())
SimpleJobProc.enqueueJob(makeJob(this, &AbstractPipeline::executeProcessor, processor));
SimpleJobProc.enqueueJob(makeJob(this, &AbstractPipeline::executeProcessor, processor, false));
s_PipelineInvalidated();
}
......@@ -101,14 +101,13 @@ namespace campvis {
return _data;
}
void AbstractPipeline::executeProcessor(AbstractProcessor* processor) {
void AbstractPipeline::executeProcessor(AbstractProcessor* processor, bool unlockInExtraThred) {
tgtAssert(processor != 0, "Processor must not be 0.");
if (processor->getEnabled() && !processor->isLocked() && processor->hasInvalidResult()) {
processor->lockProcessor();
#ifdef CAMPVIS_DEBUG
clock_t startTime = clock();
#endif
try {
processor->process(_data);
}
......@@ -119,14 +118,17 @@ namespace campvis {
LERROR("Caught unhandled exception while executing processor " << processor->getName() << ": unknown exception");
}
#ifdef CAMPVIS_DEBUG
clock_t endTime = clock();
#endif
processor->unlockProcessor();
if (processor->getClockExecutionTime()) {
clock_t endTime = clock();
LDEBUG("Executed processor " << processor->getName() << " duration: " << (endTime - startTime));
}
#ifdef CAMPVIS_DEBUG
LDEBUG("Executed processor " << processor->getName() << " duration: " << (endTime - startTime));
#endif
// Unlocking processors might be expensive, since a long chain of invalidations might be started
// -> do this in another thread...
if (unlockInExtraThred)
SimpleJobProc.enqueueJob(makeJob(processor, &AbstractProcessor::unlockProcessor));
else
processor->unlockProcessor();
}
}
......
......@@ -152,8 +152,9 @@ namespace campvis {
/**
* Executes the processor \a processor on the pipeline's data and locks its properties meanwhile.
* \param processor Processor to execute.
* \param unlockInExtraThred If true, the call to processor->unlock() will be done in an extra thread.
*/
void executeProcessor(AbstractProcessor* processor);
void executeProcessor(AbstractProcessor* processor, bool unlockInExtraThred);
DataContainer _data; ///< DataContainer containing local working set of data for this Pipeline
......
......@@ -41,6 +41,7 @@ namespace campvis {
: HasPropertyCollection()
{
_enabled = true;
_clockExecutionTime = false;
_locked = 0;
_level = VALID;
}
......@@ -116,5 +117,13 @@ namespace campvis {
s_validated(this);
}
bool AbstractProcessor::getClockExecutionTime() const {
return _clockExecutionTime;
}
void AbstractProcessor::setClockExecutionTime(bool value) {
_clockExecutionTime = value;
}
}
......@@ -123,6 +123,18 @@ namespace campvis {
* \param enabled New flag whether this processor is currently enabled.
*/
void setEnabled(bool enabled);
/**
* Returns whether to measure the execution time of this processor.
* \return _clockExecutionTime
*/
bool getClockExecutionTime() const;
/**
* Sets whether to measure the execution time of this processor.
* \param value The new flag vlaue whether to measure the execution time of this processor.
*/
void setClockExecutionTime(bool value);
/**
*
......@@ -245,6 +257,7 @@ namespace campvis {
protected:
tbb::atomic<bool> _enabled; ///< flag whether this processor is currently enabled
tbb::atomic<bool> _clockExecutionTime; ///< flag whether to measure the execution time of this processor
/// Flag whether this processor is currently locked
/// (This implies, that all properties are locked and it is not valid to call process())
......
......@@ -138,11 +138,11 @@ namespace campvis {
if (node->second->_isVisualizationProcessor) {
GLJobProc.enqueueJob(
_canvas,
makeJobOnHeap<DigraphVisualizationPipeline, AbstractProcessor*>(this, &DigraphVisualizationPipeline::executeProcessor, processor),
makeJobOnHeap<DigraphVisualizationPipeline, AbstractProcessor*, bool>(this, &DigraphVisualizationPipeline::executeProcessor, processor, true),
OpenGLJobProcessor::SerialJob);
}
else {
SimpleJobProc.enqueueJob(makeJob<DigraphVisualizationPipeline, AbstractProcessor*>(this, &DigraphVisualizationPipeline::executeProcessor, processor));
SimpleJobProc.enqueueJob(makeJob<DigraphVisualizationPipeline, AbstractProcessor*, bool>(this, &DigraphVisualizationPipeline::executeProcessor, processor, false));
}
}
else {
......
......@@ -127,7 +127,7 @@ namespace campvis {
tgtAssert(_canvas != 0, "Set a valid canvas before calling this method!");
GLJobProc.enqueueJob(
_canvas,
makeJobOnHeap<VisualizationPipeline, AbstractProcessor*>(this, &VisualizationPipeline::executeProcessor, processor),
makeJobOnHeap<VisualizationPipeline, AbstractProcessor*, bool>(this, &VisualizationPipeline::executeProcessor, processor, true),
OpenGLJobProcessor::SerialJob);
}
......@@ -185,7 +185,7 @@ namespace campvis {
OpenGLJobProcessor::SerialJob);
}
else {
SimpleJobProc.enqueueJob(makeJob<VisualizationPipeline, AbstractProcessor*>(this, &VisualizationPipeline::executeProcessor, processor));
SimpleJobProc.enqueueJob(makeJob<VisualizationPipeline, AbstractProcessor*, bool>(this, &VisualizationPipeline::executeProcessor, processor, false));
}
}
else {
......@@ -200,7 +200,7 @@ namespace campvis {
}
void VisualizationPipeline::executeProcessorAndCheckOpenGLState(AbstractProcessor* processor) {
AbstractPipeline::executeProcessor(processor);
AbstractPipeline::executeProcessor(processor, true);
#ifdef CAMPVIS_DEBUG
// tgtAssert(getGlBool(GL_DEPTH_TEST) == false, "Invalid OpenGL state after processor execution, GL_DEPTH_TEST != false.");
......
......@@ -167,18 +167,60 @@ namespace campvis {
void (*_callee)(A1); ///< Function to call
A1 _arg1; ///< Argument to pass to \a callee
};
/**
* Specific job, that is calling a member function pasing a single argument.
*/
template<class A1, class A2>
class CallFunc2ArgJob : public AbstractJob {
template<class T, class A1, class A2>
class CallMemberFunc2ArgJob : public AbstractJob {
public:
/**
* Creates an new job, that is calling \a callee on \a target pasing \a arg1 as single argument.
* Creates an new job, that is calling \a callee on \a target pasing \a arg1 and \a arg2 as arguments.
* \param target Target object
* \param callee Member function to call
* \param arg1 Argument to pass to \a callee
* \param arg1 First argument to pass to \a callee
* \param arg2 Second argument to pass to \a callee
*/
CallMemberFunc2ArgJob(T* target, void (T::*callee)(A1, A2), A1 arg1, A2 arg2)
: _target(target)
, _callee(callee)
, _arg1(arg1)
, _arg2(arg2)
{
tgtAssert(_target != 0, "Target object must not be 0.");
tgtAssert(_callee != 0, "Target member function pointer must not be 0.");
}
/**
* Destructor, nothing to do here
*/
~CallMemberFunc2ArgJob() {};
/**
* Executes this job by calling the member function.
*/
virtual void execute() {
(_target->*_callee)(_arg1, _arg2);
}
protected:
T* _target; ///< Target object
void (T::*_callee)(A1, A2); ///< Member function to call
A1 _arg1; ///< First argument to pass to \a callee
A2 _arg2; ///< Second argument to pass to \a callee
};
/**
* Specific job, that is calling a function passing two arguments.
*/
template<class A1, class A2>
class CallFunc2ArgJob : public AbstractJob {
public:
/**
* Creates an new job, that is calling \a callee passing \a arg1 and \a arg2 as arguments.
* \param callee Function to call
* \param arg1 First argument to pass to \a callee
* \param arg2 Second argument to pass to \a callee
*/
CallFunc2ArgJob(void (*callee)(A1, A2), A1 arg1, A2 arg2)
: _callee(callee)
......@@ -194,14 +236,14 @@ namespace campvis {
~CallFunc2ArgJob() {};
/**
* Executes this job by calling the member function.
* Executes this job by calling the function.
*/
virtual void execute() {
(*_callee)(_arg1, _arg2);
}
protected:
void (*_callee)(A1, A2); ///< Function to call
void (*_callee)(A1, A2); ///< Function to call
A1 _arg1; ///< First Argument to pass to \a callee
A2 _arg2; ///< Second Argument to pass to \a callee
};
......@@ -281,6 +323,31 @@ namespace campvis {
return CallFunc1ArgJob<A1>(callee, arg1);
}
/**
* Creates a new CallMemberFunc1ArgJob on the heap for the object \a target.
* \note The caller takes ownership of the returned pointer.
* \param target Target object to call method from.
* \param callee Pointer to method to call.
* \param arg1 First argument to pass to \callee.
* \return Pointer to the newly created CallMemberFunc1ArgJob. Caller has ownership!
*/
template<class T, class A1, class A2>
CallMemberFunc2ArgJob<T, A1, A2>* makeJobOnHeap(T* target, void (T::*callee)(A1, A2), A1 arg1, A2 arg2) {
return new CallMemberFunc2ArgJob<T, A1, A2>(target, callee, arg1, arg2);
}
/**
* Creates a new CallMemberFunc1ArgJob on the stack for the object \a target.
* \param target Target object to call method from.
* \param callee Pointer to method to call.
* \param arg1 First argument to pass to \callee.
* \return The newly created CallMemberFunc1ArgJob.
*/
template<class T, class A1, class A2>
CallMemberFunc2ArgJob<T, A1, A2> makeJob(T* target, void (T::*callee)(A1, A2), A1 arg1, A2 arg2) {
return CallMemberFunc2ArgJob<T, A1, A2>(target, callee, arg1, arg2);
}
/**
* Creates a new CallFunc2ArgJob on the heap for the object \a target.
* \note The caller takes ownership of the returned pointer.
......
......@@ -152,7 +152,7 @@ namespace campvis {
ss << p_sourcePath.getValue() << "\\" << "export" << std::setfill('0') << std::setw(4) << path << ".bmp";
_usReader.p_url.setValue(ss.str());
executeProcessor(&_usReader);
executeProcessor(&_usReader, false);
DataHandle dh = _data.getData(_usReader.p_targetImageID.getValue());
if (dh.getData() != 0) {
......@@ -161,11 +161,11 @@ namespace campvis {
}
}
executeProcessor(&_confidenceGenerator);
executeProcessor(&_usBlurFilter);
executeProcessor(&_confidenceGenerator, false);
executeProcessor(&_usBlurFilter, false);
_usFusion.p_view.selectById("mappingLAB");
executeProcessor(&_usFusion);
executeProcessor(&_usFusion, false);
save(path, p_targetPathColor.getValue());
// _usFusion.p_view.selectById("mappingSharpness");
......
......@@ -115,7 +115,7 @@ vec4 performRaycasting(in vec3 entryPoint, in vec3 exitPoint, in vec2 texCoords)
float formerT = t - _samplingStepSize;
// we just left the void, perform intersection refinement
for (float stepPower = 0.5; stepPower > 0.05; stepPower /= 2.0) {
for (float stepPower = 0.5; stepPower > 0.1; stepPower /= 2.0) {
// compute refined sample position
float newT = formerT + _samplingStepSize * stepPower;
vec3 newSamplePosition = entryPoint.rgb + newT * direction;
......
......@@ -72,10 +72,10 @@ namespace campvis {
_imageReader.p_targetImageID.setValue("reader.output");
_imageReader.p_targetImageID.connect(&_vr.p_inputVolume);
// Geometry1DTransferFunction* dvrTF = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .05f));
// dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.4f, .42f), tgt::col4(255, 0, 0, 255), tgt::col4(255, 0, 0, 255)));
// dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.45f, .5f), tgt::col4(0, 255, 0, 255), tgt::col4(0, 255, 0, 255)));
// _dvrNormal.p_transferFunction.replaceTF(dvrTF);
Geometry1DTransferFunction* dvrTF = new Geometry1DTransferFunction(128, tgt::vec2(0.f, .05f));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.1f, .125f), tgt::col4(255, 0, 0, 32), tgt::col4(255, 0, 0, 32)));
dvrTF->addGeometry(TFGeometry1D::createQuad(tgt::vec2(.4f, .5f), tgt::col4(0, 255, 0, 128), tgt::col4(0, 255, 0, 128)));
static_cast<TransferFunctionProperty*>(_vr.getProperty("transferFunction"))->replaceTF(dvrTF);
_trackballEH->setViewportSize(_effectiveRenderTargetSize.getValue());
_effectiveRenderTargetSize.s_changed.connect<VolumeRendererDemo>(this, &VolumeRendererDemo::onRenderTargetSizeChanged);
......
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