opengljobprocessor.h 5.38 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
27
// 
// ================================================================================================

#ifndef OPENGLJOBPROCESSOR_H__
#define OPENGLJOBPROCESSOR_H__

28
29
30
31
32
#include "cgt/glcontextmanager.h"
#include "cgt/job.h"
#include "cgt/runnable.h"
#include "cgt/singleton.h"
#include "cgt/singleton.h"
33

34
#include <ext/threading.h>
35

36
#define TBB_PREVIEW_MEMORY_POOL 1
37
38
39
40
#include <tbb/atomic.h>
#include <tbb/concurrent_queue.h>
#include <tbb/concurrent_hash_map.h>
#include <tbb/concurrent_vector.h>
41
#include <tbb/memory_pool.h>
42

43

44
namespace cgt {
45
46
47
    class GLCanvas;

    /**
48
     * This job processor singleton can be used to execute jobs that need an OpenGL context.
schultezub's avatar
schultezub committed
49
     * 
50
51
52
     * Implementing the Runnable interface, the OpenGLJobProcessor runs a background thread having
     * and acquired OpenGL context. You can execute OpenGL calls asynchroniously using enqueueJob()
     * or synchronously using the ScopedSynchronousGlJobExecution guard.
53
     */
54
55
    class CGT_API OpenGLJobProcessor : public cgt::Singleton<OpenGLJobProcessor>, public cgt::Runnable {
        friend class cgt::Singleton<OpenGLJobProcessor>;    ///< CRTP
56
        friend class AbstractJob;                           ///< so the custom new/delete operator can access the memory pool
57
58

    public:
59
60
61
62
63
64
        /**
         * Scope guard to ensure that encapsulated job is synchronously executed in an arbitrary OpenGL context.
         * This scope guard checks whether current thread is OpenGLJobProcessor thread. If so, it
         * does nothing. If this thread is not the OpenGL thread, the OpenGLJobProcessor is paused,
         * an arbitrary OpenGL context acquired. Upon destruction the OpenGLJobProcessor is resumed.
         */
65
        class CGT_API ScopedSynchronousGlJobExecution {
66
67
68
69
70
        public:
            ScopedSynchronousGlJobExecution();
            ~ScopedSynchronousGlJobExecution();

        private:
71
            cgt::GLContextScopedLock* _lock;
72
73
        };

74

schultezub's avatar
schultezub committed
75
76
77
        /**
         * Destructor, deletes all unfinished jobs.
         */
78
79
80
        virtual ~OpenGLJobProcessor();


schultezub's avatar
schultezub committed
81
82
83
84
        /**
         * Registers the given OpenGL context, so that it gets its own job queue.
         * \param   context     OpenGL context to register.
         */
85
        void setContext(cgt::GLCanvas* context);
86

87
88
89
90
        /**
         * Returns the OpenGL context of this object..
         * \return  _context
         */
91
        cgt::GLCanvas* getContext();
92

93
94
95
96
        /// \see Runnable::stop
        void stop();
        
        /**
schultezub's avatar
schultezub committed
97
         * Performs the job processing using conditional wait.
98
99
100
101
         * \sa Runnable::run
         */
        void run();

102
103
104
105
106
107
108
109
110
111
        /**
         * Pauses the job processor as at the next possible moment.
         */
        void pause();

        /**
         * Resume the execution of the job processor.
         */
        void resume();

112
        /**
113
         * Enqueues the given job.
114
115
116
117
         * 
         * \note    OpenGLJobProcessor takes ownership of \a job.
         * \param   job         Job to enqueue, PriorityPool takes ownership of this Job!
         */
118
        void enqueueJob(AbstractJob* job);
119

120
121
122
123
124
        /**
         * Enqueue OpenGL Garbage collection job
         */
        void enqueueGarbageCollection();

125
126

    protected:
127
128
129
130
131
        /**
         * Performs a OpenGL Garbage Collection if necessary.
         */
        void performGarbageCollectionIfNecessary();

132
        // Protected constructor since it's a singleton
133
134
        OpenGLJobProcessor();

135
        cgt::GLCanvas* _context;                        ///< The OpenGL context to use
136
        tbb::concurrent_queue<AbstractJob*> _jobQueue;  ///< The OpenGL job queue
137
        tbb::atomic<bool> _performGarbageCollection;    ///< Flag whether to perform garbage cxollection
138

139
        tbb::atomic<int> _pause;                        ///< Counter of pause requests
140
        std::condition_variable _evaluationCondition;   ///< conditional wait to be used when there are currently no jobs to process
141

142
    private:
143
        typedef std::allocator<AbstractJob> pool_allocator_t;
144
        tbb::memory_pool<pool_allocator_t> _jobPool;    ///< Memory pool for the signals
145
146
147
148
    };

}

149
#define GLJobProc cgt::Singleton<cgt::OpenGLJobProcessor>::getRef()
150
151

#endif // OPENGLJOBPROCESSOR_H__