opengljobprocessor.cpp 5.22 KB
Newer Older
1
2
/**********************************************************************
 *                                                                    *
3
 * cgt - CAMP Graphics Toolbox, Copyright (C) 2012-2015               *
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 *     Chair for Computer Aided Medical Procedures                    *
 *     Technische Universitaet Muenchen, Germany.                     *
 *     <http://campar.in.tum.de/>                                     *
 *                                                                    *
 * forked from tgt - Tiny Graphics Toolbox, Copyright (C) 2006-2011   *
 *     Visualization and Computer Graphics Group, Department of       *
 *     Computer Science, University of Muenster, Germany.             *
 *     <http://viscg.uni-muenster.de>                                 *
 *                                                                    *
 * This file is part of the cgt library. This library is free         *
 * software; you can redistribute it and/or modify it under the terms *
 * of the GNU Lesser General Public License version 2.1 as published  *
 * by the Free Software Foundation.                                   *
 *                                                                    *
 * This library is distributed in the hope that it will be useful,    *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of     *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the       *
 * GNU Lesser General Public License for more details.                *
 *                                                                    *
 * You should have received a copy of the GNU Lesser General Public   *
 * License in the file "LICENSE.txt" along with this library.         *
 * If not, see <http://www.gnu.org/licenses/>.                        *
 *                                                                    *
 **********************************************************************/

29
30
#include "opengljobprocessor.h"

31
32
#include <tbb/tick_count.h>

33
34
35
#include "cgt/assert.h"
#include "cgt/logmanager.h"
#include "cgt/glcontextmanager.h"
36

37
namespace cgt {
38
39
40

    OpenGLJobProcessor::OpenGLJobProcessor()
    {
41
        _pause = 0;
42
        _context= nullptr;
43
44
45
    }

    OpenGLJobProcessor::~OpenGLJobProcessor() {
46
47
48
49
        // delete all unfinished jobs
        AbstractJob* jobToDo = nullptr;
        while (_jobQueue.try_pop(jobToDo)) {
            delete jobToDo;
schultezub's avatar
schultezub committed
50
        }
51

52
        _jobQueue.clear();
53
        _jobPool.recycle();
54
55
56
    }

    void OpenGLJobProcessor::run() {
57
58
59
        cgtAssert(_context != nullptr, "You have to set the context first before calling OpenGLJobProcessor::run()!");
        std::unique_lock<std::mutex> lock(*cgt::GlContextManager::getRef().getGlMutexForContext(_context));
        cgt::GlContextManager::getRef().acquireContext(_context, false);
60
61

        while (! _stopExecution) {
62
63
            bool hadWork = false;

64
65
            AbstractJob* jobToDo = nullptr;
            while (_pause == 0 && !_stopExecution && _jobQueue.try_pop(jobToDo)) {
66
67
                hadWork = true;

68
69
70
                // execute and delete the job
                jobToDo->execute();
                delete jobToDo;
71
            }
72

73
            while (_pause > 0 && !_stopExecution) {
74
                cgt::GlContextManager::getRef().releaseContext(_context, false);
75
                _evaluationCondition.wait(lock);
76
                cgt::GlContextManager::getRef().acquireContext(_context, false);
77
78
                hadWork = true;
            }
79

80
            if (! hadWork && !_stopExecution) {
81
                cgt::GlContextManager::getRef().releaseContext(_context, false);
82
                _evaluationCondition.wait(lock);
83
                cgt::GlContextManager::getRef().acquireContext(_context, false);
84
            }
85
86
87
        }

        // release OpenGL context, so that other threads can access it
88
        cgt::GlContextManager::getRef().releaseContext(_context, false);
89
90
    }

91
92
93
94
95
96
    void OpenGLJobProcessor::pause() {
        ++_pause;
    }

    void OpenGLJobProcessor::resume() {
        if (_pause == 0) {
97
            cgtAssert(false, "Called resume on non-paused job processor!");
98
99
100
101
102
103
104
105
            return;
        }

        --_pause;
        if (_pause == 0)
            _evaluationCondition.notify_all();
    }

106
107
    void OpenGLJobProcessor::enqueueJob(AbstractJob* job) {
        _jobQueue.push(job);
108
109
        _evaluationCondition.notify_all();
    }
110

111
112
    void OpenGLJobProcessor::enqueueJob(std::function<void(void)> fn) {
        enqueueJob(cgt::makeJobOnHeap([fn]() { fn(); }));
113
114
    }

115
116
117
118
    void OpenGLJobProcessor::enqueueJobBlocking(std::function<void(void)> fn) {
        char signalVariable = 0;
        enqueueJob(cgt::makeJobOnHeap([&signalVariable, fn]() { fn(); signalVariable = 1; }));

119
120
        while (signalVariable == 0) {
            _evaluationCondition.notify_all();            
121
            std::this_thread::yield();
122
123
124
125
126
127
128
129
130
131
        }
    }

    void OpenGLJobProcessor::setContext(cgt::GLCanvas* context) {
        cgtAssert(_context == nullptr, "You are trying to change an already set context, thou shalt not do that!");
        _context = context;
    }

    cgt::GLCanvas* OpenGLJobProcessor::getContext() {
        return _context;
132
133
    }

134
135
}