121 lines
4.6 KiB
C
121 lines
4.6 KiB
C
|
|
||
|
|
||
|
#ifndef TGLDISPLAYLISTSMANAGER_H
|
||
|
#define TGLDISPLAYLISTSMANAGER_H
|
||
|
|
||
|
// TnzCore includes
|
||
|
#include "tgl.h"
|
||
|
|
||
|
// tcg includes
|
||
|
#include "tcg/tcg_observer_notifier.h"
|
||
|
|
||
|
// Qt includes
|
||
|
#include <QMutex>
|
||
|
|
||
|
#undef DVAPI
|
||
|
#undef DVVAR
|
||
|
|
||
|
#ifdef TGL_EXPORTS
|
||
|
#define DVAPI DV_EXPORT_API
|
||
|
#define DVVAR DV_EXPORT_VAR
|
||
|
#else
|
||
|
#define DVAPI DV_IMPORT_API
|
||
|
#define DVVAR DV_IMPORT_VAR
|
||
|
#endif
|
||
|
|
||
|
//**************************************************************************************************
|
||
|
// TGLDisplayListsProxy declaration
|
||
|
//**************************************************************************************************
|
||
|
|
||
|
//! TGLDisplayListsProxy is a wrapper to a dummy OpenGL context attached to a specific display lists space.
|
||
|
/*!
|
||
|
TGLDisplayListsProxy implements the basic functionalities necessary to address a display lists
|
||
|
space without having to access any actual associated OpenGL context. This is equivalent to
|
||
|
making a hidden OpenGL context (the display lists proxy) the \a current one.
|
||
|
|
||
|
\note Implementations of the TGLDisplayListsProxy must take ownership of the proxy.
|
||
|
*/
|
||
|
|
||
|
class TGLDisplayListsProxy
|
||
|
{
|
||
|
QMutex m_mutex;
|
||
|
|
||
|
public:
|
||
|
virtual ~TGLDisplayListsProxy() {}
|
||
|
|
||
|
virtual void makeCurrent() = 0;
|
||
|
virtual void doneCurrent() = 0;
|
||
|
|
||
|
QMutex *mutex() { return &m_mutex; }
|
||
|
};
|
||
|
|
||
|
//**************************************************************************************************
|
||
|
// TGLDisplayListsProxy template specializations
|
||
|
//**************************************************************************************************
|
||
|
|
||
|
template <typename Context>
|
||
|
class TGLDisplayListsProxyT : public TGLDisplayListsProxy
|
||
|
{
|
||
|
Context *m_proxy;
|
||
|
|
||
|
public:
|
||
|
TGLDisplayListsProxyT(Context *proxy) : m_proxy(proxy) {}
|
||
|
~TGLDisplayListsProxyT() { delete m_proxy; }
|
||
|
|
||
|
void makeCurrent() { m_proxy->makeCurrent(); }
|
||
|
void doneCurrent() { m_proxy->doneCurrent(); }
|
||
|
};
|
||
|
|
||
|
//**************************************************************************************************
|
||
|
// TGLDisplayListsManager declaration
|
||
|
//**************************************************************************************************
|
||
|
|
||
|
//! TGLDisplayListsManager is a singleton class used to track OpenGL shared display lists spaces.
|
||
|
/*!
|
||
|
OpenGL contexts can share their display lists space (in particular, this includes texture
|
||
|
objects) with other contexts. Typically, sharing specification happens when a new context
|
||
|
is created - at that point, the new context is allowed to share the lists space of another
|
||
|
known context, pretty much the same way a shared smart pointer does.
|
||
|
\n\n
|
||
|
However, OpenGL provides access to the display lists space \a only through their attached
|
||
|
OpenGL contexts; meaning that an external object has to know at least one associated context
|
||
|
to operate on a display lists space.
|
||
|
\n\n
|
||
|
We'll call such an associated context a \a proxy of the display lists space. It is a dummy
|
||
|
OpenGL context that shares the display lists spaces with those that are attached to it.
|
||
|
\n\n
|
||
|
Observe that the use of one such dummy context, rather than one of the originally
|
||
|
attached ones, is strictly necessary in a multithreaded environment, since <I> an OpenGL
|
||
|
context can be active in exactly one thread at a given time <\I> - and any of the attached
|
||
|
contexts could always be current in another thread.
|
||
|
\n\n
|
||
|
However, the use of a single proxy per display lists space means that multiple threads
|
||
|
could try to access it at the same time. Synchronization in this case must be handled by
|
||
|
the user by accessing the proxy's built-in mutex.
|
||
|
|
||
|
\warning TGLDisplayListsManager relies on the user to attach a context to the \b correct
|
||
|
display lists id.
|
||
|
*/
|
||
|
|
||
|
class DVAPI TGLDisplayListsManager : public tcg::notifier<>
|
||
|
{
|
||
|
public:
|
||
|
struct Observer : public tcg::observer<TGLDisplayListsManager> {
|
||
|
virtual void onDisplayListDestroyed(int dlSpaceId) = 0;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
static TGLDisplayListsManager *instance();
|
||
|
|
||
|
int storeProxy(TGLDisplayListsProxy *proxy); //!< Stores the specified proxy, returning its associated display
|
||
|
//!< lists id. Context attaches should follow.
|
||
|
void attachContext(int dlSpaceId, TGlContext context); //!< Attaches the specified context to a display lists space
|
||
|
void releaseContext(TGlContext context); //!< Releases a context reference to its display lists space
|
||
|
int displayListsSpaceId(TGlContext context); //!< Returns the display lists space id of a known context, or
|
||
|
//!< -1 if it did not attach to any known space.
|
||
|
TGLDisplayListsProxy *dlProxy(int dlSpaceId); //!< Returns the display lists space proxy associated to the
|
||
|
//!< specified id.
|
||
|
};
|
||
|
|
||
|
#endif // TGLDISPLAYLISTSMANAGER_H
|