/* ** GLimp_InitGL */ static bool GLimp_InitGL( void ) { int format; EGLConfig config; const int pbufferAttribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; const int contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLSurface surface; glw_state.display = qeglGetDisplay( EGL_DEFAULT_DISPLAY ); if( glw_state.display == EGL_NO_DISPLAY ) { ri.Com_Printf( "GLimp_InitGL() - eglGetDisplay failed\n" ); return false; } if( !qeglInitialize( glw_state.display, NULL, NULL ) ) { ri.Com_Printf( "GLimp_InitGL() - eglInitialize failed\n" ); return false; } GLimp_Android_ChooseConfig(); if( !glw_state.config ) { ri.Com_Printf( "GLimp_InitGL() - GLimp_Android_ChooseConfig failed\n" ); return false; } if ( !qeglGetConfigAttrib( glw_state.display, glw_state.config, EGL_NATIVE_VISUAL_ID, &glw_state.format ) ) { ri.Com_Printf( "GLimp_InitGL() - eglGetConfigAttrib failed\n" ); return false; } glw_state.pbufferSurface = qeglCreatePbufferSurface( glw_state.display, glw_state.config, pbufferAttribs ); if( glw_state.pbufferSurface == EGL_NO_SURFACE ) { ri.Com_Printf( "GLimp_InitGL() - eglCreatePbufferSurface failed\n" ); return false; } glw_state.context = qeglCreateContext( glw_state.display, glw_state.config, EGL_NO_CONTEXT, contextAttribs ); if( glw_state.context == EGL_NO_CONTEXT ) { ri.Com_Printf( "GLimp_InitGL() - eglCreateContext failed\n" ); return false; } glw_state.swapInterval = 1; GLimp_Android_UpdateWindowSurface(); return true; }
/* ** GLimp_Android_ChooseConfig */ static void GLimp_Android_ChooseConfig( void ) { int colorSizes[] = { 8, 4 }, colorSize; int depthSizes[] = { 24, 16, 16 }, depthSize, firstDepthSize = 0; bool depthEncodingSupported = false; int depthEncodings[] = { EGL_DONT_CARE, EGL_DEPTH_ENCODING_NONLINEAR_NV, EGL_DONT_CARE }, depthEncoding; int maxStencilSize = ( ( r_stencilbits->integer >= 8 ) ? 8 : 0 ), stencilSize; int minSwapIntervals[] = { #ifndef PUBLIC_BUILD // Vsync cannot be normally turned off on Android, so the setting must not be available to the user. 0, #endif EGL_DONT_CARE }; int minSwapInterval; const char *extensions = qglGetGLWExtensionsString(); int i, j, k; if( !( ri.Cvar_Get( "gl_ext_depth24", "1", CVAR_ARCHIVE|CVAR_LATCH_VIDEO )->integer ) ) firstDepthSize = 1; if( extensions && strstr( extensions, "EGL_NV_depth_nonlinear" ) && ri.Cvar_Get( "gl_ext_depth_nonlinear", "1", CVAR_ARCHIVE|CVAR_LATCH_VIDEO )->integer ) { depthEncodingSupported = true; } for( i = 0; i < sizeof( colorSizes ) / sizeof( colorSizes[0] ); i++ ) { colorSize = colorSizes[i]; for( j = firstDepthSize; j < sizeof( depthSizes ) / sizeof( depthSizes[0] ); j++ ) { depthEncoding = depthEncodings[j]; if( ( depthEncoding != EGL_DONT_CARE ) && !depthEncodingSupported ) continue; depthSize = depthSizes[j]; for( stencilSize = maxStencilSize; stencilSize >= 0; stencilSize -= 8 ) { for( k = 0; k < sizeof( minSwapIntervals ) / sizeof( minSwapIntervals[0] ); k++ ) { EGLConfig config = GLimp_Android_ChooseVisual( colorSize, depthSize, depthEncoding, stencilSize, minSwapIntervals[k] ); if( config ) { glw_state.config = config; #ifdef PUBLIC_BUILD minSwapInterval = 1; #else qeglGetConfigAttrib( glw_state.display, glw_state.config, EGL_MIN_SWAP_INTERVAL, &minSwapInterval ); #endif ri.Com_Printf( "Got colorbits %i, depthbits %i%s, stencilbits %i" #ifndef PUBLIC_BUILD ", min swap interval %i" #endif "\n" , colorSize * 4, depthSize , ( depthEncoding == EGL_DEPTH_ENCODING_NONLINEAR_NV ) ? " (non-linear)" : "" , stencilSize #ifndef PUBLIC_BUILD , minSwapInterval #endif ); glConfig.stencilBits = stencilSize; ri.Cvar_ForceSet( "r_swapinterval_min", ( minSwapInterval > 0 ) ? "1" : "0" ); return; } } } } } }
/* ** GLimp_InitGL */ static bool GLimp_InitGL( void ) { int format; EGLConfig config; const int contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLSurface surface; glw_state.display = qeglGetDisplay( EGL_DEFAULT_DISPLAY ); if( glw_state.display == EGL_NO_DISPLAY ) { ri.Com_Printf( "GLimp_InitGL() - eglGetDisplay failed\n" ); return false; } if( !qeglInitialize( glw_state.display, NULL, NULL ) ) { ri.Com_Printf( "GLimp_InitGL() - eglInitialize failed\n" ); return false; } GLimp_EGL_ChooseConfig(); if( !glw_state.config ) { ri.Com_Printf( "GLimp_InitGL() - GLimp_EGL_ChooseConfig failed\n" ); return false; } if ( !qeglGetConfigAttrib( glw_state.display, glw_state.config, EGL_NATIVE_VISUAL_ID, &glw_state.format ) ) { ri.Com_Printf( "GLimp_InitGL() - eglGetConfigAttrib failed\n" ); return false; } glw_state.mainThreadPbuffer = GLimp_EGL_CreatePbufferSurface(); if( glw_state.mainThreadPbuffer == EGL_NO_SURFACE ) { ri.Com_Printf( "GLimp_InitGL() - GLimp_EGL_CreatePbufferSurface for mainThreadPbuffer failed\n" ); return false; } glw_state.noWindowPbuffer = GLimp_EGL_CreatePbufferSurface(); if( glw_state.noWindowPbuffer == EGL_NO_SURFACE ) { ri.Com_Printf( "GLimp_InitGL() - GLimp_EGL_CreatePbufferSurface for noWindowPbuffer failed\n" ); return false; } glw_state.context = qeglCreateContext( glw_state.display, glw_state.config, EGL_NO_CONTEXT, contextAttribs ); if( glw_state.context == EGL_NO_CONTEXT ) { ri.Com_Printf( "GLimp_InitGL() - eglCreateContext failed\n" ); return false; } glw_state.windowMutex = ri.Mutex_Create(); glw_state.swapInterval = 1; // Default swap interval for new surfaces // GLimp_EGL_UpdateWindowSurface attaches the surface to the current context, so make one current to initialize qeglMakeCurrent( glw_state.display, glw_state.noWindowPbuffer, glw_state.noWindowPbuffer, glw_state.context ); GLimp_EGL_UpdateWindowSurface(); return true; }