/* =============== GLimp_SpawnRenderThread =============== */ qboolean GLimp_SpawnRenderThread( void ( *function )( void ) ) { static qboolean warned = qfalse; if ( !warned ) { Com_Printf( "WARNING: You enable r_smp at your own risk!\n" ); warned = qtrue; } #if !defined( MACOS_X ) && !defined( WIN32 ) && !defined ( SDL_VIDEO_DRIVER_X11 ) && !SDL_VERSION_ATLEAST( 2, 0, 0 ) return qfalse; /* better safe than sorry for now. */ #endif if ( renderThread != NULL ) /* hopefully just a zombie at this point... */ { Com_Printf( "Already a render thread? Trying to clean it up...\n" ); GLimp_ShutdownRenderThread(); } smpMutex = SDL_CreateMutex(); if ( smpMutex == NULL ) { Com_Printf( "smpMutex creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return qfalse; } renderCommandsEvent = SDL_CreateCond(); if ( renderCommandsEvent == NULL ) { Com_Printf( "renderCommandsEvent creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return qfalse; } renderCompletedEvent = SDL_CreateCond(); if ( renderCompletedEvent == NULL ) { Com_Printf( "renderCompletedEvent creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return qfalse; } renderThreadFunction = function; renderThread = SDL_CreateThread( GLimp_RenderThreadWrapper, "render thread", NULL ); if ( renderThread == NULL ) { ri.Printf( PRINT_ALL, "SDL_CreateThread() returned %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return qfalse; } return qtrue; }
/* =============== GLimp_SpawnRenderThread =============== */ qboolean GLimp_SpawnRenderThread(void (*function)(void)) { if (renderThread == (void *)0xdead) { Com_Printf("SMP: Not safe restarting thread.\n"); renderThread = NULL; return qfalse; } if (renderThread != NULL) { Com_Printf("SMP: Render thread still Running.\n"); return qtrue; } smpData = (void *)0xdead; smpMutex = SDL_CreateMutex(); if (!smpMutex) { Com_Printf("SMP: Mutex creation failed: %s\n", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } renderCommandsEvent = SDL_CreateCond(); if (renderCommandsEvent == NULL) { Com_Printf("SMP: CommandEvent creation failed: %s\n", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } renderCompletedEvent = SDL_CreateCond(); if (renderCompletedEvent == NULL) { Com_Printf("SMP: CompletedEvent creation failed: %s\n", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } glimpRenderThread = function; renderThread = SDL_CreateThread(GLimp_RenderThreadWrapper, GLthreadname); if (renderThread == NULL) { ri.Printf(PRINT_ALL, "SDL: CreateThread() returned %s", SDL_GetError()); GLimp_ShutdownRenderThread(); return qfalse; } SDL_LockMutex(smpMutex); while ( smpData ) SDL_CondWait(renderCompletedEvent, smpMutex); SDL_UnlockMutex(smpMutex); return qtrue; }
/* =============== GLimp_SpawnRenderThread =============== */ bool GLimp_SpawnRenderThread( void ( *function )() ) { static bool warned = false; if ( !warned ) { Com_Printf( "WARNING: You enable r_smp at your own risk!\n" ); warned = true; } if ( renderThread != nullptr ) /* hopefully just a zombie at this point... */ { Com_Printf( "Already a render thread? Trying to clean it up...\n" ); GLimp_ShutdownRenderThread(); } smpMutex = SDL_CreateMutex(); if ( smpMutex == nullptr ) { Com_Printf( "smpMutex creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return false; } renderCommandsEvent = SDL_CreateCond(); if ( renderCommandsEvent == nullptr ) { Com_Printf( "renderCommandsEvent creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return false; } renderCompletedEvent = SDL_CreateCond(); if ( renderCompletedEvent == nullptr ) { Com_Printf( "renderCompletedEvent creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return false; } renderThreadFunction = function; renderThread = SDL_CreateThread( GLimp_RenderThreadWrapper, "render thread", nullptr ); if ( renderThread == nullptr ) { ri.Printf( PRINT_ALL, "SDL_CreateThread() returned %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return false; } return true; }
/* =============== GLimp_Shutdown =============== */ void GLimp_Shutdown() { ri.Printf( PRINT_DEVELOPER, "Shutting down OpenGL subsystem\n" ); ri.IN_Shutdown(); #if defined( SMP ) if ( renderThread != nullptr ) { Com_Printf( "Destroying renderer thread...\n" ); GLimp_ShutdownRenderThread(); } #endif if ( glContext ) { SDL_GL_DeleteContext( glContext ); glContext = nullptr; } if ( window ) { SDL_DestroyWindow( window ); window = nullptr; } SDL_QuitSubSystem( SDL_INIT_VIDEO ); Com_Memset( &glConfig, 0, sizeof( glConfig ) ); Com_Memset( &glState, 0, sizeof( glState ) ); }
/* =============== GLimp_Shutdown =============== */ void GLimp_Shutdown(void) { ri.IN_Shutdown(); SDL_QuitSubSystem(SDL_INIT_VIDEO); screen = NULL; #if defined(SMP) if(renderThread != NULL) { Com_Printf("Destroying renderer thread...\n"); GLimp_ShutdownRenderThread(); } #endif Com_Memset(&glConfig, 0, sizeof(glConfig)); Com_Memset(&glState, 0, sizeof(glState)); }
void GLimp_Shutdown( void ) { IN_Shutdown(); if ( glConfig.smpActive && !signalcaught ) { // may already be dead if called from signal handler GLimp_WakeRenderer( (void *)0xdead ); // - and wait for it to return GLimp_FrontEndSleep(); } if ( SDLvidscreen ) SDL_VideoQuit(); if ( SDL_WasInit(SDL_INIT_VIDEO) ) SDL_QuitSubSystem(SDL_INIT_VIDEO); GLimp_ShutdownRenderThread(); SDLvidscreen = NULL; memset( &glConfig, 0, sizeof( glConfig ) ); memset( &glState, 0, sizeof( glState ) ); }
/* =============== GLimp_SpawnRenderThread =============== */ qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) { static qboolean warned = qfalse; if (!warned) { Com_Printf("WARNING: You enable r_smp at your own risk!\n"); warned = qtrue; } #ifndef MACOS_X return qfalse; /* better safe than sorry for now. */ #endif 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(); } smpMutex = SDL_CreateMutex(); if (smpMutex == NULL) { Com_Printf( "smpMutex creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return qfalse; } renderCommandsEvent = SDL_CreateCond(); if (renderCommandsEvent == NULL) { Com_Printf( "renderCommandsEvent creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); return qfalse; } renderCompletedEvent = SDL_CreateCond(); if (renderCompletedEvent == NULL) { Com_Printf( "renderCompletedEvent creation failed: %s\n", SDL_GetError() ); GLimp_ShutdownRenderThread(); 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 { // tma 01/09/07: don't think this is necessary anyway? // // !!! 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; }