diff options
author | icculus <icculus@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-11-28 10:56:27 +0000 |
---|---|---|
committer | icculus <icculus@edf5b092-35ff-0310-97b2-ce42778d08ea> | 2005-11-28 10:56:27 +0000 |
commit | ae241d5adfc665fb5ab1408b64d51c806677bc5b (patch) | |
tree | f70f6683d05f931c93417138121a482b5efdb9ba /code/unix | |
parent | 6fbbf139bb874dfa2f31ab04c68157abcfe20351 (diff) | |
download | ioquake3-aero-ae241d5adfc665fb5ab1408b64d51c806677bc5b.tar.gz ioquake3-aero-ae241d5adfc665fb5ab1408b64d51c806677bc5b.zip |
First shot at SMP renderer with sdl_glimp. Does not work yet!
git-svn-id: svn://svn.icculus.org/quake3/trunk@385 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/unix')
-rw-r--r-- | code/unix/Makefile | 17 | ||||
-rw-r--r-- | code/unix/sdl_glimp.c | 146 |
2 files changed, 116 insertions, 47 deletions
diff --git a/code/unix/Makefile b/code/unix/Makefile index 625fafa..b06c9d3 100644 --- a/code/unix/Makefile +++ b/code/unix/Makefile @@ -326,8 +326,8 @@ ifeq ($(PLATFORM),darwin) $(B)/baseq3/vm/ui.qvm \ $(B)/missionpack/vm/qagame.qvm \ $(B)/missionpack/vm/cgame.qvm \ - $(B)/missionpack/vm/ui.qvm -# $(B)/$(PLATFORM)quake3-smp \ + $(B)/missionpack/vm/ui.qvm \ + $(B)/$(PLATFORM)quake3-smp \ else # ifeq darwin @@ -997,6 +997,18 @@ ifeq ($(PLATFORM),darwin) $(B)/client/linux_snd.o \ $(B)/client/sdl_snd.o \ + Q3POBJ_SMP=\ + $(B)/client/unix_main.o \ + $(B)/client/unix_net.o \ + $(B)/client/unix_shared.o \ + $(B)/client/linux_signals.o \ + $(B)/client/linux_common.o \ + $(B)/client/linux_qgl.o \ + $(B)/client/sdl_glimp_smp.o \ + $(B)/client/linux_joystick.o \ + $(B)/client/linux_snd.o \ + $(B)/client/sdl_snd.o \ + ifeq ($(ARCH),i386) I386OBJS := \ $(B)/client/ftola.o \ @@ -1212,6 +1224,7 @@ $(B)/client/linux_common.o : $(UDIR)/linux_common.c; $(DO_CC) $(B)/client/linux_glimp.o : $(UDIR)/linux_glimp.c; $(DO_CC) $(GL_CFLAGS) $(B)/client/sdl_glimp.o : $(UDIR)/sdl_glimp.c; $(DO_CC) $(GL_CFLAGS) $(B)/client/linux_glimp_smp.o : $(UDIR)/linux_glimp.c; $(DO_SMP_CC) $(GL_CFLAGS) +$(B)/client/sdl_glimp_smp.o : $(UDIR)/sdl_glimp.c; $(DO_SMP_CC) $(GL_CFLAGS) $(B)/client/linux_joystick.o : $(UDIR)/linux_joystick.c; $(DO_CC) $(B)/client/linux_qgl.o : $(UDIR)/linux_qgl.c; $(DO_CC) $(GL_CFLAGS) $(B)/client/linux_input.o : $(UDIR)/linux_input.c; $(DO_CC) diff --git a/code/unix/sdl_glimp.c b/code/unix/sdl_glimp.c index 5c690eb..129d1b8 100644 --- a/code/unix/sdl_glimp.c +++ b/code/unix/sdl_glimp.c @@ -60,6 +60,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "SDL.h" +#ifdef SMP +#include "SDL_thread.h" +#endif + #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -1024,8 +1028,9 @@ void GLimp_EndFrame (void) QGL_EnableLogging( (qboolean)r_logFile->integer ); // bk001205 - was ->value } -// Figure out something to do with this... -#if 0 //def SMP + + +#ifdef SMP /* =========================================================== @@ -1034,53 +1039,104 @@ SMP acceleration =========================================================== */ -static pthread_mutex_t smpMutex = PTHREAD_MUTEX_INITIALIZER; +/* + * I have no idea if this will even work...most platforms don't offer + * thread-safe OpenGL libraries, and it looks like the original Linux + * code counted on each thread claiming the GL context with glXMakeCurrent(), + * which you can't currently do in SDL. We'll just have to hope for the best. + */ -static pthread_cond_t renderCommandsEvent = PTHREAD_COND_INITIALIZER; -static pthread_cond_t renderCompletedEvent = PTHREAD_COND_INITIALIZER; +static SDL_mutex *smpMutex = NULL; +static SDL_cond *renderCommandsEvent = NULL; +static SDL_cond *renderCompletedEvent = NULL; +static void (*glimpRenderThread)( void ) = NULL; +static SDL_Thread *renderThread = NULL; + +static void GLimp_ShutdownRenderThread(void) +{ + if (smpMutex != NULL) + { + SDL_DestroyMutex(smpMutex); + smpMutex = NULL; + } + + if (renderCommandsEvent != NULL) + { + SDL_DestroyCond(renderCommandsEvent); + renderCommandsEvent = NULL; + } + + if (renderCompletedEvent != NULL) + { + SDL_DestroyCond(renderCompletedEvent); + renderCompletedEvent = NULL; + } -static void (*glimpRenderThread)( void ); + glimpRenderThread = NULL; +} -static void *GLimp_RenderThreadWrapper( void *arg ) +static int GLimp_RenderThreadWrapper( void *arg ) { Com_Printf( "Render thread starting\n" ); - glimpRenderThread(); + glimpRenderThread(); - qglXMakeCurrent( dpy, None, NULL ); + //qglXMakeCurrent( dpy, None, NULL ); Com_Printf( "Render thread terminating\n" ); - return arg; + return 0; } qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) { - pthread_t renderThread; - int ret; + if (renderThread != NULL) /* hopefully just a zombie at this point... */ + { + Com_Printf("Already a render thread? Trying to clean it up...\n"); + SDL_WaitThread(renderThread, NULL); + renderThread = NULL; + GLimp_ShutdownRenderThread(); + } - pthread_mutex_init( &smpMutex, NULL ); + smpMutex = SDL_CreateMutex(); + if (smpMutex == NULL) + { + Com_Printf( "smpMutex creation failed: %s\n", SDL_GetError() ); + GLimp_ShutdownRenderThread(); + return qfalse; + } - pthread_cond_init( &renderCommandsEvent, NULL ); - pthread_cond_init( &renderCompletedEvent, NULL ); + renderCommandsEvent = SDL_CreateCond(); + if (renderCommandsEvent == NULL) + { + Com_Printf( "renderCommandsEvent creation failed: %s\n", SDL_GetError() ); + GLimp_ShutdownRenderThread(); + return qfalse; + } - glimpRenderThread = function; + renderCompletedEvent = SDL_CreateCond(); + if (renderCompletedEvent == NULL) + { + Com_Printf( "renderCompletedEvent creation failed: %s\n", SDL_GetError() ); + GLimp_ShutdownRenderThread(); + return qfalse; + } - ret = pthread_create( &renderThread, - NULL, // attributes - GLimp_RenderThreadWrapper, - NULL ); // argument - if ( ret ) { - ri.Printf( PRINT_ALL, "pthread_create returned %d: %s", ret, strerror( ret ) ); - return qfalse; + glimpRenderThread = function; + renderThread = SDL_CreateThread(GLimp_RenderThreadWrapper, NULL); + if ( renderThread == NULL ) { + ri.Printf( PRINT_ALL, "SDL_CreateThread() returned %s", SDL_GetError() ); + GLimp_ShutdownRenderThread(); + return qfalse; } else { - ret = pthread_detach( renderThread ); - if ( ret ) { - ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) ); - } - } + // !!! FIXME: No detach API available in SDL! + //ret = pthread_detach( renderThread ); + //if ( ret ) { + //ri.Printf( PRINT_ALL, "pthread_detach returned %d: %s", ret, strerror( ret ) ); + //} + } - return qtrue; + return qtrue; } static volatile void *smpData = NULL; @@ -1088,58 +1144,58 @@ static volatile qboolean smpDataReady; void *GLimp_RendererSleep( void ) { - void *data; + void *data = NULL; - qglXMakeCurrent( dpy, None, NULL ); + //qglXMakeCurrent( dpy, None, NULL ); - pthread_mutex_lock( &smpMutex ); + SDL_LockMutex(smpMutex); { smpData = NULL; smpDataReady = qfalse; // after this, the front end can exit GLimp_FrontEndSleep - pthread_cond_signal( &renderCompletedEvent ); + SDL_CondSignal(renderCompletedEvent); while ( !smpDataReady ) { - pthread_cond_wait( &renderCommandsEvent, &smpMutex ); + SDL_CondWait(renderCommandsEvent, smpMutex); } data = (void *)smpData; } - pthread_mutex_unlock( &smpMutex ); + SDL_UnlockMutex(smpMutex); - qglXMakeCurrent( dpy, win, ctx ); + //qglXMakeCurrent( dpy, win, ctx ); - return data; + return data; } void GLimp_FrontEndSleep( void ) { - pthread_mutex_lock( &smpMutex ); + SDL_LockMutex(smpMutex); { while ( smpData ) { - pthread_cond_wait( &renderCompletedEvent, &smpMutex ); + SDL_CondWait(renderCompletedEvent, smpMutex); } } - pthread_mutex_unlock( &smpMutex ); + SDL_UnlockMutex(smpMutex); - qglXMakeCurrent( dpy, win, ctx ); + //qglXMakeCurrent( dpy, win, ctx ); } void GLimp_WakeRenderer( void *data ) { - qglXMakeCurrent( dpy, None, NULL ); + //qglXMakeCurrent( dpy, None, NULL ); - pthread_mutex_lock( &smpMutex ); + SDL_LockMutex(smpMutex); { assert( smpData == NULL ); smpData = data; smpDataReady = qtrue; // after this, the renderer can continue through GLimp_RendererSleep - pthread_cond_signal( &renderCommandsEvent ); + SDL_CondSignal(renderCommandsEvent); } - pthread_mutex_unlock( &smpMutex ); + SDL_UnlockMutex(smpMutex); } #else |