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