00001
00002
00003
00004
00005 #ifndef _GL_ASYNC_H_
00006 #define _GL_ASYNC_H_
00007
00008 #include <list>
00009 #include <vector>
00010 #include <GL/glx.h>
00011 #include <X11/X.h>
00012 #include <X11/Xlib.h>
00013 #include <X11/XUtil.h>
00014
00015 #define GL_GLEXT_PROTOTYPES
00016 #include <GL/glext.h>
00017
00018 #ifdef __GNUC__ // GCC 3.1 and later
00019 # include <ext/hash_map>
00020 namespace Sgi = ::__gnu_cxx;
00021 #else // other compilers
00022 # include <hash_map>
00023 namespace Sgi = std;
00024 #endif
00025
00026
00047 namespace glAsync
00048 {
00060 Bool XMapContext( Display* display, XVisualInfo* visInfo,
00061 GLXContext context );
00062
00076 void XUnmapContext( Display* display, GLXContext context );
00077
00086 Bool XMakeCurrent( Display* display, GLXContext context );
00087
00088
00095 void bindTexture( GLenum target, GLuint texture );
00096
00103 GLuint texImage2D( GLenum target, GLint level, GLint internalformat,
00104 GLsizei width, GLsizei height, GLint border,
00105 GLenum format, GLenum type, const GLvoid *pixels );
00106
00113 GLuint texImage3D( GLenum target, GLint level, GLint internalformat,
00114 GLsizei width, GLsizei height, GLsizei depth,
00115 GLint border, GLenum format, GLenum type,
00116 const GLvoid *pixels );
00117
00125 Bool poll( GLuint marker );
00126
00134 Bool isIdle();
00135
00143 void finish( GLuint marker );
00144
00148 void finishAll();
00149
00157 class Thread
00158 {
00159 public:
00160 Bool XMapContext( Display* display, XVisualInfo* visInfo,
00161 GLXContext context );
00162 void XUnmapContext( Display* display, GLXContext context );
00163 Bool XMakeCurrent( Display* display, GLXContext context );
00164
00165 void bindTexture( GLenum target, GLuint texture );
00166 GLuint texImage2D( GLenum target, GLint level, GLint internalformat,
00167 GLsizei width, GLsizei height, GLint border,
00168 GLenum format, GLenum type, const GLvoid *pixels );
00169 GLuint texImage3D( GLenum target, GLint level, GLint internalformat,
00170 GLsizei width, GLsizei height, GLsizei depth,
00171 GLint border, GLenum format, GLenum type,
00172 const GLvoid *pixels );
00173
00174 Bool poll( GLuint marker );
00175 Bool isIdle();
00176
00177 void finish( GLuint marker );
00178 void finishAll();
00179
00180 private:
00181 pthread_t _thread;
00182
00183 GLuint _marker;
00184 GLuint _markerCompleted;
00185
00186 struct ContextInfo
00187 {
00188 Display* display;
00189 GLXContext context;
00190 XID drawable;
00191 };
00192
00193 struct ContextKey
00194 {
00195 Display* display;
00196 GLXContext context;
00197 };
00198
00199 struct HashContextKey
00200 {
00201 size_t operator()(const ContextKey& ctx) const
00202 {
00203 return ((size_t)(ctx.context));
00204 }
00205
00206 bool operator()(const ContextKey& ctx1,const ContextKey& ctx2) const
00207 {
00208 return ( ctx1.display == ctx2.display &&
00209 ctx1.context == ctx2.context );
00210 }
00211 };
00212
00213 struct Command
00214 {
00215 public:
00216 enum ID
00217 {
00218 ID_XMAKECURRENT,
00219 ID_BINDTEXTURE,
00220 ID_TEXIMAGE2D,
00221 ID_TEXIMAGE3D,
00222 ID_ALL
00223 };
00224
00225 Command( ID commandID ) : id(commandID) {}
00226
00227 ID id;
00228 GLuint marker;
00229 union
00230 {
00231 struct
00232 {
00233 ContextKey key;
00234 } XMakeCurrent;
00235
00236 struct
00237 {
00238 GLenum target;
00239 GLuint texture;
00240 } bindTexture;
00241
00242 struct
00243 {
00244 GLuint texture;
00245 GLenum target;
00246 GLint level;
00247 GLint internalformat;
00248 GLsizei width;
00249 GLsizei height;
00250 GLint border;
00251 GLenum format;
00252 GLenum type;
00253 const GLvoid *pixels;
00254 } texImage2D;
00255
00256 struct
00257 {
00258 GLuint texture;
00259 GLenum target;
00260 GLint level;
00261 GLint internalformat;
00262 GLsizei width;
00263 GLsizei height;
00264 GLsizei depth;
00265 GLint border;
00266 GLenum format;
00267 GLenum type;
00268 const GLvoid *pixels;
00269 } texImage3D;
00270 } data;
00271 };
00272
00273 typedef
00274 Sgi::hash_map<ContextKey, ContextInfo, HashContextKey, HashContextKey>
00275 ContextMap;
00276
00277 ContextMap _mappedContexts;
00278
00279 std::list<Command*> _commands;
00280 std::vector<Command*> _commandCache;
00281
00282 class Sync
00283 {
00284 public:
00285 Sync()
00286 {
00287 pthread_mutex_init( &mutex, NULL );
00288 pthread_cond_init( &cond, NULL );
00289 }
00290 ~Sync()
00291 {
00292 pthread_cond_destroy( &cond );
00293 pthread_mutex_destroy( &mutex );
00294 }
00295
00296 pthread_mutex_t mutex;
00297 pthread_cond_t cond;
00298 };
00299
00300 Sync _commandSync, _markerSync;
00301
00302 #ifdef GL_APPLE_fence
00303
00304 bool _useAPPLE_fence;
00306 std::list<GLuint> _pendingFences;
00308 std::vector<GLuint> _fenceCache;
00309 #endif
00310
00311 Command* _newCommand( Command::ID commandID );
00312
00313
00314 static void* _childEntry( void* arg );
00315 void* _child();
00316 void _initChild();
00317 void _syncCommand( const uint currentMarker );
00318
00319
00320 #ifdef GL_APPLE_fence
00321 GLuint _newFence();
00322 void _finishAllFences();
00323 #endif
00324
00325 void _XMakeCurrent( Command* command );
00326 void _bindTexture( Command* command );
00327 void _texImage2D( Command* command );
00328 void _texImage3D( Command* command );
00329
00330 void (glAsync::Thread::*_cmdHandler[Command::ID_ALL])( Command* command );
00331 };
00332 }
00333
00334 #endif // _GL_ASYNC_H_