/* ** GLimp_Shutdown ** ** This routine does all OS specific shutdown procedures for the OpenGL ** subsystem. The state structure is also nulled out. ** */ void GLimp_Shutdown( void ) { if( glw_state.windowMutex ) ri.Mutex_Destroy( &glw_state.windowMutex ); if( glw_state.context != EGL_NO_CONTEXT ) { qeglMakeCurrent( glw_state.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); qeglDestroyContext( glw_state.display, glw_state.context ); glw_state.context = EGL_NO_CONTEXT; } if( glw_state.surface != EGL_NO_SURFACE ) { qeglDestroySurface( glw_state.display, glw_state.surface ); glw_state.surface = EGL_NO_SURFACE; } if( glw_state.noWindowPbuffer != EGL_NO_SURFACE ) { qeglDestroySurface( glw_state.display, glw_state.noWindowPbuffer ); glw_state.noWindowPbuffer = EGL_NO_SURFACE; } if( glw_state.mainThreadPbuffer != EGL_NO_SURFACE ) { qeglDestroySurface( glw_state.display, glw_state.mainThreadPbuffer ); glw_state.mainThreadPbuffer = EGL_NO_SURFACE; } if( glw_state.display != EGL_NO_DISPLAY ) { qeglTerminate( glw_state.display ); glw_state.display = EGL_NO_DISPLAY; } }
/** * Recreates and selects the surface for the newly created window, or selects a dummy buffer when there's no window. */ static void GLimp_Android_UpdateWindowSurface( void ) { ANativeWindow *window = glw_state.window; if( glw_state.surface != EGL_NO_SURFACE ) { qeglDestroySurface( glw_state.display, glw_state.surface ); glw_state.surface = EGL_NO_SURFACE; } if( !window ) { qeglMakeCurrent( glw_state.display, glw_state.pbufferSurface, glw_state.pbufferSurface, glw_state.context ); return; } ANativeWindow_setBuffersGeometry( window, glConfig.width, glConfig.height, glw_state.format ); if( glConfig.stereoEnabled ) { const char *extensions = qglGetGLWExtensionsString(); if( extensions && strstr( extensions, "EGL_EXT_multiview_window" ) ) { int attribs[] = { EGL_MULTIVIEW_VIEW_COUNT_EXT, 2, EGL_NONE }; glw_state.surface = qeglCreateWindowSurface( glw_state.display, glw_state.config, glw_state.window, attribs ); } } if( glw_state.surface == EGL_NO_SURFACE ) // Try to create a non-stereo surface. { glConfig.stereoEnabled = false; glw_state.surface = qeglCreateWindowSurface( glw_state.display, glw_state.config, glw_state.window, NULL ); } if( glw_state.surface == EGL_NO_SURFACE ) { ri.Com_Printf( "GLimp_Android_UpdateWindowSurface() - GLimp_Android_CreateWindowSurface failed\n" ); return; } if( !qeglMakeCurrent( glw_state.display, glw_state.surface, glw_state.surface, glw_state.context ) ) { ri.Com_Printf( "GLimp_Android_UpdateWindowSurface() - eglMakeCurrent failed\n" ); qeglDestroySurface( glw_state.display, glw_state.surface ); glw_state.surface = EGL_NO_SURFACE; return; } qeglSwapInterval( glw_state.display, glw_state.swapInterval ); }
/* ** GLimp_SharedContext_Create */ bool GLimp_SharedContext_Create( void **context, void **surface ) { const int contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLSurface pbuffer = EGL_NO_SURFACE; EGLContext ctx; if( surface ) { pbuffer = GLimp_EGL_CreatePbufferSurface(); if( pbuffer == EGL_NO_SURFACE ) return false; } ctx = qeglCreateContext( glw_state.display, glw_state.config, glw_state.context, contextAttribs ); if( !ctx ) { if( pbuffer != EGL_NO_SURFACE ) qeglDestroySurface( glw_state.display, pbuffer ); return false; } *context = ctx; if( surface ) *surface = pbuffer; return true; }
/** * Recreates and selects the surface for the newly created window, or selects a dummy buffer when there's no window. */ static void GLimp_EGL_UpdateWindowSurface( void ) { EGLNativeWindowType window = glw_state.window; EGLContext context = qeglGetCurrentContext(); if( context == EGL_NO_CONTEXT ) return; if( glw_state.surface != EGL_NO_SURFACE ) { qeglMakeCurrent( glw_state.display, glw_state.noWindowPbuffer, glw_state.noWindowPbuffer, context ); qeglDestroySurface( glw_state.display, glw_state.surface ); glw_state.surface = EGL_NO_SURFACE; } if( !window ) return; #ifdef __ANDROID__ ANativeWindow_setBuffersGeometry( window, glConfig.width, glConfig.height, glw_state.format ); #endif glw_state.surface = qeglCreateWindowSurface( glw_state.display, glw_state.config, window, NULL ); if( glw_state.surface == EGL_NO_SURFACE ) { ri.Com_Printf( "GLimp_EGL_UpdateWindowSurface() - GLimp_EGL_CreateWindowSurface failed\n" ); return; } qeglMakeCurrent( glw_state.display, glw_state.surface, glw_state.surface, context ); qeglSwapInterval( glw_state.display, glw_state.swapInterval ); }
/* ** GLimp_Shutdown ** ** This routine does all OS specific shutdown procedures for the OpenGL ** subsystem. Under OpenGL this means NULLing out the current DC and ** HGLRC, deleting the rendering context, and releasing the DC acquired ** for the window. The state structure is also nulled out. ** */ void GLimp_Shutdown( void ) { if( glw_state.context != EGL_NO_CONTEXT ) { qeglMakeCurrent( glw_state.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); qeglDestroyContext( glw_state.display, glw_state.context ); glw_state.context = EGL_NO_CONTEXT; } if( glw_state.surface != EGL_NO_SURFACE ) { qeglDestroySurface( glw_state.display, glw_state.surface ); glw_state.surface = EGL_NO_SURFACE; } if( glw_state.pbufferSurface != EGL_NO_SURFACE ) { qeglDestroySurface( glw_state.display, glw_state.pbufferSurface ); glw_state.surface = EGL_NO_SURFACE; } if( glw_state.display != EGL_NO_DISPLAY ) { qeglTerminate( glw_state.display ); glw_state.display = EGL_NO_DISPLAY; } }
/* ** GLimp_SharedContext_Destroy */ void GLimp_SharedContext_Destroy( void *context, void *surface ) { qeglDestroyContext( glw_state.display, context ); qeglDestroySurface( glw_state.display, surface ); }