2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

opengljobprocessor.cpp 5.43 KB
Newer Older
1
2
// ================================================================================================
// 
schultezub's avatar
schultezub committed
3
// This file is part of the CAMPVis Software Framework.
4
// 
5
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
schultezub's avatar
schultezub committed
6
//      Christian Schulte zu Berge <christian.szb@in.tum.de>
7
//      Chair for Computer Aided Medical Procedures
8
9
//      Technische Universitaet Muenchen
//      Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
10
// 
schultezub's avatar
schultezub committed
11
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
12
// 
13
14
15
16
// 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
17
// 
18
19
20
21
// 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.
22
23
24
25
26
// 
// ================================================================================================

#include "opengljobprocessor.h"

27
28
#include <tbb/tick_count.h>

29
#include "tgt/assert.h"
30
31
#include "tgt/logmanager.h"
#include "tgt/openglgarbagecollector.h"
32
#include "tgt/glcontextmanager.h"
33

34
namespace tgt {
35

36
37
38
    OpenGLJobProcessor::ScopedSynchronousGlJobExecution::ScopedSynchronousGlJobExecution()
        : _lock(nullptr)
    {
39
        if (! GLCtxtMgr.checkWhetherThisThreadHasAcquiredOpenGlContext()) {
40
            GLJobProc.pause();
41
            _lock = new tgt::GLContextScopedLock(GLJobProc.getContext());
42
43
44
45
46
47
48
49
50
51
52
53
        }
    }

    OpenGLJobProcessor::ScopedSynchronousGlJobExecution::~ScopedSynchronousGlJobExecution() {
        if (_lock != nullptr) {
            delete _lock;
            GLJobProc.resume();
        }
    }

// ================================================================================================
    
54
55
    OpenGLJobProcessor::OpenGLJobProcessor()
    {
56
        _pause = 0;
57
        _context= nullptr;
58
        _performGarbageCollection = false;
59
60
61
    }

    OpenGLJobProcessor::~OpenGLJobProcessor() {
62
63
64
65
        // delete all unfinished jobs
        AbstractJob* jobToDo = nullptr;
        while (_jobQueue.try_pop(jobToDo)) {
            delete jobToDo;
schultezub's avatar
schultezub committed
66
        }
67

68
        _jobQueue.clear();
69
        _jobPool.recycle();
70
71
72
73
74
    }

    void OpenGLJobProcessor::stop() {
        _stopExecution = true;
        _evaluationCondition.notify_all();
75
76

        Runnable::stop();
77
78
79
    }

    void OpenGLJobProcessor::run() {
80
81
82
        tgtAssert(_context != nullptr, "You have to set the context first before calling OpenGLJobProcessor::run()!");
        std::unique_lock<std::mutex> lock(*tgt::GlContextManager::getRef().getGlMutexForContext(_context));
        tgt::GlContextManager::getRef().acquireContext(_context, false);
83
84

        while (! _stopExecution) {
85
86
            bool hadWork = false;

87
88
            AbstractJob* jobToDo = nullptr;
            while (_pause == 0 && !_stopExecution && _jobQueue.try_pop(jobToDo)) {
89
90
                hadWork = true;

91
92
93
                // execute and delete the job
                jobToDo->execute();
                delete jobToDo;
94
95

                performGarbageCollectionIfNecessary();
96
            }
97

98
99
            while (_pause > 0 && !_stopExecution) {
                performGarbageCollectionIfNecessary();
100
                tgt::GlContextManager::getRef().releaseContext(_context, false);
101
                _evaluationCondition.wait(lock);
102
                tgt::GlContextManager::getRef().acquireContext(_context, false);
103
104
                hadWork = true;
            }
105

106
107
            if (! hadWork && !_stopExecution) {
                performGarbageCollectionIfNecessary();
108
                tgt::GlContextManager::getRef().releaseContext(_context, false);
109
                _evaluationCondition.wait(lock);
110
                tgt::GlContextManager::getRef().acquireContext(_context, false);
111
            }
112
113
114
        }

        // release OpenGL context, so that other threads can access it
115
        tgt::GlContextManager::getRef().releaseContext(_context, false);
116
117
    }

118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    void OpenGLJobProcessor::pause() {
        ++_pause;
    }

    void OpenGLJobProcessor::resume() {
        if (_pause == 0) {
            tgtAssert(false, "Called resume on non-paused job processor!");
            return;
        }

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

133
134
    void OpenGLJobProcessor::enqueueJob(AbstractJob* job) {
        _jobQueue.push(job);
135
136
        _evaluationCondition.notify_all();
    }
137

138
139
140
    void OpenGLJobProcessor::setContext(tgt::GLCanvas* context) {
        tgtAssert(_context == nullptr, "You are trying to change an already set context, thou shalt not do that!");
        _context = context;
141
142
    }

143
    tgt::GLCanvas* OpenGLJobProcessor::getContext() {
144
        return _context;
145
146
    }

147
148
149
150
151
152
153
154
155
156
157
158
    void OpenGLJobProcessor::enqueueGarbageCollection() {
        _performGarbageCollection = true;
        _evaluationCondition.notify_all();
    }

    void OpenGLJobProcessor::performGarbageCollectionIfNecessary() {
        if (_performGarbageCollection && tgt::OpenGLGarbageCollector::isInited()) {
            _performGarbageCollection = false;
            GLGC.deleteGarbage();
        }
    }

159

160
161
}