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

glcontextmanager.h 4.57 KB
Newer Older
1
2
3
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef GLCONTEXTMANAGER_H__
#define GLCONTEXTMANAGER_H__

#include "tgt/singleton.h"
#include "tgt/glcanvas.h"
#include <tbb/mutex.h>  // TODO: TBB dependency in TGT is not that beautiful...
#include <map>
#include <string>

class QWidget;

namespace tgt {
    class GLCanvas;

    /**
     * Manages multiple shared OpenGL contexts and offers methods to ensure that only one context is active at a time.
     */
    class GlContextManager : public Singleton<GlContextManager> {
    public:
        /**
         * Creates a new QtGLContext for the OpenGL context of \a canvas.
         * \param   canvas  QtCanvas with the OpenGL context to manage
         */
        GlContextManager();

        /**
         * Destructor
         */
        virtual ~GlContextManager();

        /**
         * Get Pointer of the actual class
         * @return Pointer of the actual class
         */
        static GlContextManager* getPtr();

        /**
         * Get reference of the actual class
         * @return reference of the actual class
        */
        static GlContextManager& getRef();

        /**
         * Has the actual class been inited?
         */
        static bool isInited();

        /**
         * Creates a new OpenGL context in a QtThreadedCanvas with the given arguments.
         * Parameters are the same as in QtThreadedCanvas() but context sharing is enables per default.
         * 
         * \note    Must be called with the OpenGL mutex acquired!
         * 
         * \note    The created canvas/context is owned by this ContextManager. Hence, you may not
         *          delete it yourself!
         * 
         * \param   key     Key of the context to create, must be unique.
         * \param   title   Window title
         * \param   size    Window size
         * \return  The newly created QtThreadedCanvas.
         */
        virtual GLCanvas* createContext(
            const std::string& key,
            const std::string& title = "",
            const ivec2& size = ivec2(GLCanvas::DEFAULT_WINDOW_WIDTH, GLCanvas::DEFAULT_WINDOW_HEIGHT),
            const GLCanvas::Buffers buffers = GLCanvas::RGBADD,
            bool shared = true) = 0;
68
69
70
71
72
73
74


        /**
         * Removes the OpenGL context \a context from the list of managed contexts.
         * \param   context Context to remove.
         */
        virtual void removeContext(GLCanvas* context);
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
        
        /**
         * Returns the OpenGL context with the given key \a key, 0 if no such context exists.
         * \param   key     Key of the context to return.
         * \return  The OpenGL context with the given key \a key, 0 if no such context exists.
         */
        GLCanvas* getContextByKey(const std::string& key);

        GLCanvas* getCurrentContext() const;

        tbb::mutex& getGlMutex();

        void acquireContext(GLCanvas* context);

        void releaseCurrentContext();


        void lockAndAcquire(GLCanvas* context);

        void releaseAndUnlock();
        
    protected:
        /**
         * Sets the given context \a context as the current context for the OpenGL device.
         * If \a context is already the current context, nothing will happen.
         * \param   context     Context to set as current.
         */
        virtual void setCurrent(GLCanvas* context) = 0;

        /**
         * Locks the OpenGL device for other threads acessing the ContextManager.
         * \see GlContextManager::release
         */
        void lock();

        /**
         * Releases the lock on the OpenGL device
         * \see GlContextManager::lock
         */
        void unlock();


        std::map<std::string, GLCanvas*> _contexts;  ///< Map of all OpenGL contexts
        GLCanvas* _currentContext;                   ///< Current active OpenGL context
119
120
121
        tbb::mutex _glMutex;                         ///< Mutex protecting OpenGL for multi-threaded access

        tbb::mutex _localMutex;                      ///< local mutex to prodect _contexts
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150

        static GlContextManager* singletonClass_;
    };

    
    /**
     * Scoped lockAndAcquire for a GLContext, that automatically unlocks the context on destruction.
     */
    class TGT_API GLContextScopedLock {
    public:
        GLContextScopedLock(GLCanvas* context)
            : _context(context)
        {
            if (_context) {
                GlContextManager::getRef().lockAndAcquire(context);
            }
        };
        ~GLContextScopedLock() {
            if (_context)
                GlContextManager::getRef().releaseAndUnlock();
        }
    private:
        GLCanvas* _context;
    };

} // namespace tgt


#endif // GLCONTEXTMANAGER_H__