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