abstractpipeline.cpp 10.4 KB
Newer Older
1

2
3
// ================================================================================================
// 
schultezub's avatar
schultezub committed
4
// This file is part of the CAMPVis Software Framework.
5
// 
6
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
schultezub's avatar
schultezub committed
7
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
8
//      Chair for Computer Aided Medical Procedures
9
10
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
11
// 
schultezub's avatar
schultezub committed
12
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
13
// 
14
15
16
17
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 
// except in compliance with the License. You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
18
// 
19
20
21
22
// Unless required by applicable law or agreed to in writing, software distributed under the 
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
// either express or implied. See the License for the specific language governing permissions 
// and limitations under the License.
23
24
25
// 
// ================================================================================================

26
#include "abstractpipeline.h"
schultezub's avatar
schultezub committed
27

28
29
#include <tbb/tick_count.h>

schultezub's avatar
schultezub committed
30
#include "tgt/exception.h"
31
#include "tgt/glcanvas.h"
32
33
#include "tgt/glcontextmanager.h"
#include "tgt/painter.h"
34
35
36
#include "tgt/tgt_gl.h"

#include "core/pipeline/visualizationprocessor.h"
37
#include "core/pipeline/abstractprocessor.h"
38

39

schultezub's avatar
schultezub committed
40
41
namespace campvis {
    const std::string AbstractPipeline::loggerCat_ = "CAMPVis.core.datastructures.AbstractPipeline";
42

43
    AbstractPipeline::AbstractPipeline(DataContainer* dc) 
44
        : HasPropertyCollection()
45
46
        , tgt::EventHandler()
        , tgt::EventListener()
47
        , _data(dc)
48
49
50
51
        , _canvas(0)
        , _canvasSize("CanvasSize", "Canvas Size", tgt::ivec2(128, 128), tgt::ivec2(1, 1), tgt::ivec2(4096, 4096))
        , _ignoreCanvasSizeUpdate(false)
        , _renderTargetID("renderTargetID", "Render Target ID", "AbstractPipeline.renderTarget", DataNameProperty::READ)
schultezub's avatar
   
schultezub committed
52
    {
53
54
        tgtAssert(_data != 0, "Pointer to the DataContainer for this pipeline must not be 0!");

55
        _enabled = false;
56
        _pipelineDirty = true;
57

58
59
        addProperty(_renderTargetID);
        addProperty(_canvasSize);
schultezub's avatar
   
schultezub committed
60
61
62
    }

    AbstractPipeline::~AbstractPipeline() {
63

schultezub's avatar
   
schultezub committed
64
65
    }

66
    void AbstractPipeline::init() {
67
68
        _renderTargetID.s_changed.connect<AbstractPipeline>(this, &AbstractPipeline::onPropertyChanged);

schultezub's avatar
schultezub committed
69
70
        initAllProperties();

71
        // initialize all processors:
schultezub's avatar
schultezub committed
72
73
74
75
76
77
78
79
        for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
            try {
                (*it)->init();
            }
            catch (tgt::Exception& e) {
                LERROR("Caught Exception during initialization of processor: " << e.what());
            }
        }
80
    }
schultezub's avatar
schultezub committed
81

82
    void AbstractPipeline::deinit() {
83
84
        stop();

schultezub's avatar
schultezub committed
85
86
        deinitAllProperties();

87
88
89
        // deinitialize all processors:
        for (std::vector<AbstractProcessor*>::iterator it = _processors.begin(); it != _processors.end(); ++it) {
            try {
schultezub's avatar
schultezub committed
90
                (*it)->s_invalidated.disconnect(this);
91
92
93
94
95
96
                (*it)->deinit();
            }
            catch (tgt::Exception& e) {
                LERROR("Caught Exception during deinitialization of processor: " << e.what());
            }
        }
97

98
99
        _renderTargetID.s_changed.disconnect(this);

100
        // clear DataContainer
101
        _data->clear();
102
103
    }

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
    void AbstractPipeline::run() {
        std::unique_lock<std::mutex> lock(*tgt::GlContextManager::getRef().getGlMutexForContext(_canvas));
        tgt::GlContextManager::getRef().acquireContext(_canvas, false);

        while (! _stopExecution) {
            if (_enabled && _pipelineDirty) {
                // mark pipeline as not dirty
                _pipelineDirty = false;

                // execute pipeline
                executePipeline();

                // paint on canvas
                _canvas->getPainter()->paint();
            }

            if (!_enabled || !_pipelineDirty) {
                tgt::GlContextManager::getRef().releaseContext(_canvas, false);
                _evaluationCondition.wait(lock);
                tgt::GlContextManager::getRef().acquireContext(_canvas, false);
            }
        }

        tgt::GlContextManager::getRef().releaseContext(_canvas, false);
    }

    void AbstractPipeline::stop() {
        _stopExecution = true;
        _evaluationCondition.notify_all();

        Runnable::stop();
    }

schultezub's avatar
schultezub committed
137
    void AbstractPipeline::onPropertyChanged(const AbstractProperty* prop) {
138
        if (prop == &_renderTargetID) {
139
            setPipelineDirty();
140
        }
141
        else if (prop == &_canvasSize && _canvas != nullptr && !_ignoreCanvasSizeUpdate) {
142
143
144
145
146
147
            if (_canvasSize.getValue() != _canvas->getSize()) {
                _ignoreCanvasSizeUpdate = true;
                _canvas->setSize(_canvasSize.getValue());
                _ignoreCanvasSizeUpdate = false;
            }
        }
schultezub's avatar
schultezub committed
148
149
150
    }

    const DataContainer& AbstractPipeline::getDataContainer() const {
151
        return *_data;
schultezub's avatar
schultezub committed
152
153
    }

154
    DataContainer& AbstractPipeline::getDataContainer() {
155
        return *_data;
156
157
    }

158
    void AbstractPipeline::executeProcessor(AbstractProcessor* processor) {
159
160
        tgtAssert(processor != 0, "Processor must not be 0.");

161
        // execute processor if needed
162
        if (processor->getEnabled() && !processor->isLocked()) {
163
            if (! processor->isValid()) {
164
165
166
                tbb::tick_count startTime;
                if (processor->getClockExecutionTime())
                    startTime = tbb::tick_count::now();
167
168

                try {
169
                    processor->process(*_data);
170
171
172
173
174
175
176
177
178
                }
                catch (std::exception& e) {
                    LERROR("Caught unhandled exception while executing processor " << processor->getName() << ": " << e.what());
                }
                catch (...) {
                    LERROR("Caught unhandled exception while executing processor " << processor->getName() << ": unknown exception");
                }

                if (processor->getClockExecutionTime()) {
179
180
                    tbb::tick_count endTime = tbb::tick_count::now();
                    LINFO("Executed processor " << processor->getName() << " duration: " << (endTime - startTime).seconds());
181
                }
182
            }
183
        }
184
185
    }

186
187
188
189
    void AbstractPipeline::executeProcessorAndCheckOpenGLState(AbstractProcessor* processor) {
        AbstractPipeline::executeProcessor(processor);

#ifdef CAMPVIS_DEBUG
190
191
        tgtAssert(tgt::getGlBool(GL_DEPTH_TEST) == false, "Invalid OpenGL state after processor execution, GL_DEPTH_TEST != false.");
        tgtAssert(tgt::getGlBool(GL_SCISSOR_TEST) == false, "Invalid OpenGL state after processor execution, GL_SCISSOR_TEST != false.");
192

193
194
        tgtAssert(tgt::getGlInt(GL_CULL_FACE_MODE) == GL_BACK, "Invalid OpenGL state after processor execution, GL_CULL_FACE_MODE != GL_BACk.");
        tgtAssert(tgt::getGlInt(GL_DEPTH_FUNC) == GL_LESS, "Invalid OpenGL state after processor execution, GL_DEPTH_FUNC != GL_LESS.");
195

196
        tgtAssert(tgt::getGlFloat(GL_DEPTH_CLEAR_VALUE) == 1.f, "Invalid OpenGL state after processor execution, GL_DEPTH_CLEAR_VALUE != 1.f.");
197

198
199
200
201
        tgtAssert(tgt::getGlFloat(GL_RED_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_RED_SCALE != 1.f.");
        tgtAssert(tgt::getGlFloat(GL_GREEN_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_GREEN_SCALE != 1.f.");
        tgtAssert(tgt::getGlFloat(GL_BLUE_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_BLUE_SCALE != 1.f.");
        tgtAssert(tgt::getGlFloat(GL_ALPHA_SCALE) == 1.f, "Invalid OpenGL state after processor execution, GL_ALPHA_SCALE != 1.f.");
202

203
204
205
206
        tgtAssert(tgt::getGlFloat(GL_RED_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_RED_BIAS != 0.f.");
        tgtAssert(tgt::getGlFloat(GL_GREEN_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_GREEN_BIAS != 0.f.");
        tgtAssert(tgt::getGlFloat(GL_BLUE_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_BLUE_BIAS != 0.f.");
        tgtAssert(tgt::getGlFloat(GL_ALPHA_BIAS) == 0.f, "Invalid OpenGL state after processor execution, GL_ALPHA_BIAS != 0.f.");
207
208
209
#endif
    }

210
211
212
213
    const std::vector<AbstractProcessor*>& AbstractPipeline::getProcessors() const {
        return _processors;
    }

214
215
216
217
218
219
    bool AbstractPipeline::getEnabled() const {
        return _enabled;
    }

    void AbstractPipeline::setEnabled(bool enabled) {
        _enabled = enabled;
220
        setPipelineDirty();
221
222
    }

223
224
225
    void AbstractPipeline::onEvent(tgt::Event* e) {
        // copy and paste from tgt::EventHandler::onEvent() but without deleting e
        for (size_t i = 0 ; i < listeners_.size() ; ++i) {
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
226
227
228
229
            // don't forward this event to ourselves - otherwise we'll end up with an endless loop.
            if (listeners_[i] == this) {
                tgt::EventListener::onEvent(e);
            }
230
            // check if current listener listens to the eventType of e
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
231
            else if (listeners_[i]->getEventTypes() & e->getEventType() ){
232
233
                listeners_[i]->onEvent(e);
            }
Christian Schulte zu Berge's avatar
Christian Schulte zu Berge committed
234
235
236

            if (e->isAccepted())
                break;
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
        }
    }

    void AbstractPipeline::setCanvas(tgt::GLCanvas* canvas) {
        _canvas = canvas;
    }

    void AbstractPipeline::setRenderTargetSize(const tgt::ivec2& size) {
        if (_canvasSize.getValue() != size && !_ignoreCanvasSizeUpdate) {
            _canvasSize.setValue(size);
        }
    }

    const tgt::ivec2& AbstractPipeline::getRenderTargetSize() const {
        return _canvasSize.getValue();
    }

    const std::string& AbstractPipeline::getRenderTargetID() const {
        return _renderTargetID.getValue();
    }

258
    void AbstractPipeline::addProcessor(AbstractProcessor* processor) {
schultezub's avatar
schultezub committed
259
        tgtAssert(processor != 0, "Processor must not be 0.")
260
261
        _processors.push_back(processor);
    }
262

263
264
    void AbstractPipeline::setPipelineDirty() {
        _pipelineDirty = true;
265

266
267
        if (_enabled)
            _evaluationCondition.notify_all();
268
    }
269
}