glcontextmanager.h 4.6 KB
Newer Older
1
2
3
4
5
#ifndef GLCONTEXTMANAGER_H__
#define GLCONTEXTMANAGER_H__

#include "tgt/singleton.h"
#include "tgt/glcanvas.h"
6
#include "tgt/types.h"
7
8
9
10
11
12
13
14
15
16
17
18
#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.
     */
19
    class TGT_API GlContextManager : public Singleton<GlContextManager> {
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
68
    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;
69
70
71
72
73
74
75


        /**
         * Removes the OpenGL context \a context from the list of managed contexts.
         * \param   context Context to remove.
         */
        virtual void removeContext(GLCanvas* context);
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
119
        
        /**
         * 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
120
121
122
        tbb::mutex _glMutex;                         ///< Mutex protecting OpenGL for multi-threaded access

        tbb::mutex _localMutex;                      ///< local mutex to prodect _contexts
123
124
125
126

        static GlContextManager* singletonClass_;
    };

127

128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    /**
     * 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__