tahoma2d/toonz/sources/include/tgldisplaylistsmanager.h

146 lines
4.9 KiB
C
Raw Normal View History

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>
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.
*/
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