2016-05-17 03:04:11 +12:00
|
|
|
#pragma once
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
#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
|
|
|
|
//**************************************************************************************************
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! TGLDisplayListsProxy is a wrapper to a dummy OpenGL context attached to a
|
|
|
|
//! specific display lists space.
|
2016-03-19 06:57:51 +13:00
|
|
|
/*!
|
2016-06-15 18:43:10 +12:00
|
|
|
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
|
2016-03-19 06:57:51 +13:00
|
|
|
making a hidden OpenGL context (the display lists proxy) the \a current one.
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
\note Implementations of the TGLDisplayListsProxy must take ownership of the
|
|
|
|
proxy.
|
2016-03-19 06:57:51 +13:00
|
|
|
*/
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class TGLDisplayListsProxy {
|
|
|
|
QMutex m_mutex;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
virtual ~TGLDisplayListsProxy() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
virtual void makeCurrent() = 0;
|
|
|
|
virtual void doneCurrent() = 0;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
QMutex *mutex() { return &m_mutex; }
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//**************************************************************************************************
|
|
|
|
// TGLDisplayListsProxy template specializations
|
|
|
|
//**************************************************************************************************
|
|
|
|
|
|
|
|
template <typename Context>
|
2016-06-29 18:17:12 +12:00
|
|
|
class TGLDisplayListsProxyT final : public TGLDisplayListsProxy {
|
2016-06-15 18:43:10 +12:00
|
|
|
Context *m_proxy;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
TGLDisplayListsProxyT(Context *proxy) : m_proxy(proxy) {}
|
|
|
|
~TGLDisplayListsProxyT() { delete m_proxy; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-19 20:06:29 +12:00
|
|
|
void makeCurrent() override { m_proxy->makeCurrent(); }
|
|
|
|
void doneCurrent() override { m_proxy->doneCurrent(); }
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//**************************************************************************************************
|
|
|
|
// TGLDisplayListsManager declaration
|
|
|
|
//**************************************************************************************************
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
//! TGLDisplayListsManager is a singleton class used to track OpenGL shared
|
|
|
|
//! display lists spaces.
|
2016-03-19 06:57:51 +13:00
|
|
|
/*!
|
2016-06-15 18:43:10 +12:00
|
|
|
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
|
2016-03-19 06:57:51 +13:00
|
|
|
known context, pretty much the same way a shared smart pointer does.
|
|
|
|
\n\n
|
2016-06-15 18:43:10 +12:00
|
|
|
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
|
2016-03-19 06:57:51 +13:00
|
|
|
to operate on a display lists space.
|
|
|
|
\n\n
|
2016-06-15 18:43:10 +12:00
|
|
|
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.
|
2016-03-19 06:57:51 +13:00
|
|
|
\n\n
|
2016-06-15 18:43:10 +12:00
|
|
|
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
|
2016-03-19 06:57:51 +13:00
|
|
|
contexts could always be current in another thread.
|
|
|
|
\n\n
|
2016-06-15 18:43:10 +12:00
|
|
|
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
|
2016-03-19 06:57:51 +13:00
|
|
|
the user by accessing the proxy's built-in mutex.
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
\warning TGLDisplayListsManager relies on the user to attach a context to the
|
|
|
|
\b correct
|
2016-03-19 06:57:51 +13:00
|
|
|
display lists id.
|
|
|
|
*/
|
|
|
|
|
2016-06-29 18:17:12 +12:00
|
|
|
class DVAPI TGLDisplayListsManager final : public tcg::notifier<> {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
struct Observer : public tcg::observer<TGLDisplayListsManager> {
|
|
|
|
virtual void onDisplayListDestroyed(int dlSpaceId) = 0;
|
|
|
|
};
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
static TGLDisplayListsManager *instance();
|
|
|
|
|
|
|
|
int storeProxy(TGLDisplayListsProxy *proxy); //!< Stores the specified proxy,
|
2016-06-20 14:23:05 +12:00
|
|
|
//! returning its associated
|
|
|
|
//! display
|
2016-06-15 18:43:10 +12:00
|
|
|
//!< lists id. Context attaches should follow.
|
|
|
|
void attachContext(int dlSpaceId, TGlContext context); //!< Attaches the
|
2016-06-20 14:23:05 +12:00
|
|
|
//! specified context
|
|
|
|
//! to a display lists
|
|
|
|
//! space
|
2016-06-15 18:43:10 +12:00
|
|
|
void releaseContext(TGlContext context); //!< Releases a context reference to
|
2016-06-20 14:23:05 +12:00
|
|
|
//! its display lists space
|
2016-06-15 18:43:10 +12:00
|
|
|
int displayListsSpaceId(TGlContext context); //!< Returns the display lists
|
2016-06-20 14:23:05 +12:00
|
|
|
//! space id of a known context,
|
|
|
|
//! or
|
2016-06-15 18:43:10 +12:00
|
|
|
//!< -1 if it did not attach to any known space.
|
|
|
|
TGLDisplayListsProxy *dlProxy(int dlSpaceId); //!< Returns the display lists
|
2016-06-20 14:23:05 +12:00
|
|
|
//! space proxy associated to
|
|
|
|
//! the
|
|
|
|
//!< specified id.
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
#endif // TGLDISPLAYLISTSMANAGER_H
|