static void configure_with(struct state_decompress *decompressor, struct video_desc desc) { enum dxt_type type; #ifndef HAVE_MACOSX printf("[RTDXT] Trying OpenGL 3.1 context first.\n"); decompressor->gl_context = glx_init(MK_OPENGL_VERSION(3,1)); decompressor->legacy = FALSE; if(!decompressor->gl_context) { fprintf(stderr, "[RTDXT] OpenGL 3.1 profile failed to initialize, falling back to legacy profile.\n"); decompressor->gl_context = glx_init(OPENGL_VERSION_UNSPECIFIED); decompressor->legacy = TRUE; } glx_validate(decompressor->gl_context); #else decompressor->gl_context = NULL; if(get_mac_kernel_version_major() >= 11) { printf("[RTDXT] Mac 10.7 or latter detected. Trying OpenGL 3.2 Core profile first.\n"); decompressor->gl_context = mac_gl_init(MAC_GL_PROFILE_3_2); if(!decompressor->gl_context) { fprintf(stderr, "[RTDXT] OpenGL 3.2 Core profile failed to initialize, falling back to legacy profile.\n"); } else { decompressor->legacy = FALSE; } } if(!decompressor->gl_context) { decompressor->gl_context = mac_gl_init(MAC_GL_PROFILE_LEGACY); decompressor->legacy = TRUE; } #endif if(!decompressor->gl_context) { fprintf(stderr, "[RTDXT decompress] Failed to create GL context."); exit_uv(128); decompressor->compressed_len = 0; return; } if(desc.color_spec == DXT5) { type = DXT_TYPE_DXT5_YCOCG; } else if(desc.color_spec == DXT1) { type = DXT_TYPE_DXT1; } else if(desc.color_spec == DXT1_YUV) { type = DXT_TYPE_DXT1_YUV; } else { fprintf(stderr, "Wrong compressiong to decompress.\n"); return; } decompressor->desc = desc; decompressor->decoder = dxt_decoder_create(type, desc.width, desc.height, decompressor->out_codec == RGBA ? DXT_FORMAT_RGBA : DXT_FORMAT_YUV422, decompressor->legacy); assert(decompressor->decoder != NULL); decompressor->compressed_len = dxt_get_size(desc.width, desc.height, type); decompressor->configured = TRUE; }
bool init_gl_context(struct gl_context *context, int which) { context->context = NULL; #ifdef HAVE_LINUX x11_enter_thread(); if(which == GL_CONTEXT_ANY) { printf("Trying OpenGL 3.1 first.\n"); context->context = glx_init(MK_OPENGL_VERSION(3,1)); context->legacy = FALSE; } if(!context->context) { if(which != GL_CONTEXT_LEGACY) { fprintf(stderr, "[RTDXT] OpenGL 3.1 profile failed to initialize, falling back to legacy profile.\n"); } context->context = glx_init(OPENGL_VERSION_UNSPECIFIED); context->legacy = TRUE; } if(context->context) { glx_validate(context->context); } #elif defined HAVE_MACOSX if(which == GL_CONTEXT_ANY) { if(get_mac_kernel_version_major() >= 11) { printf("[RTDXT] Mac 10.7 or latter detected. Trying OpenGL 3.2 Core profile first.\n"); context->context = mac_gl_init(MAC_GL_PROFILE_3_2); if(!context->context) { fprintf(stderr, "[RTDXT] OpenGL 3.2 Core profile failed to initialize, falling back to legacy profile.\n"); } else { context->legacy = FALSE; } } } if(!context->context) { context->context = mac_gl_init(MAC_GL_PROFILE_LEGACY); context->legacy = TRUE; } #else // WIN32 if(which == GL_CONTEXT_ANY) { context->context = win32_context_init(OPENGL_VERSION_UNSPECIFIED); } else if(which == GL_CONTEXT_LEGACY) { context->context = win32_context_init(OPENGL_VERSION_LEGACY); } context->legacy = TRUE; #endif if(context->context) { return true; } else { return false; } }
/** * @brief initializes specified OpenGL context * * @note * After this call, context is current for calling thread. * * @param[out] context newly created context * @param which OpenGL version specifier * @return info if context creation succeeded or failed */ bool init_gl_context(struct gl_context *context, int which) { context->context = NULL; #ifdef HAVE_LINUX x11_enter_thread(); if(which == GL_CONTEXT_ANY) { debug_msg("Trying OpenGL 3.1 first.\n"); context->context = glx_init(MK_OPENGL_VERSION(3,1)); context->legacy = FALSE; } if(!context->context) { if(which != GL_CONTEXT_LEGACY) { debug_msg("OpenGL 3.1 profile failed to initialize, falling back to legacy profile.\n"); } context->context = glx_init(OPENGL_VERSION_UNSPECIFIED); context->legacy = TRUE; } if(context->context) { glx_validate(context->context); } #elif defined HAVE_MACOSX if(which == GL_CONTEXT_ANY) { if(get_mac_kernel_version_major() >= 11) { debug_msg("Mac 10.7 or latter detected. Trying OpenGL 3.2 Core profile first.\n"); context->context = mac_gl_init(MAC_GL_PROFILE_3_2); if(!context->context) { debug_msg("OpenGL 3.2 Core profile failed to initialize, falling back to legacy profile.\n"); } else { context->legacy = FALSE; } } } if(!context->context) { context->context = mac_gl_init(MAC_GL_PROFILE_LEGACY); context->legacy = TRUE; } #else // WIN32 if(which == GL_CONTEXT_ANY) { context->context = win32_context_init(OPENGL_VERSION_UNSPECIFIED); } else if(which == GL_CONTEXT_LEGACY) { context->context = win32_context_init(OPENGL_VERSION_LEGACY); } context->legacy = TRUE; #endif { char *save_ptr; const char *gl_ver = (const char *) glGetString(GL_VERSION); if (!gl_ver) { fprintf(stderr, "Unable to determine OpenGL version!\n"); return false; } char *tmp = strdup(gl_ver); char *item = strtok_r(tmp, ".", &save_ptr); if (!item) { fprintf(stderr, "Unable to determine OpenGL version!\n"); free(tmp); return false; } context->gl_major = atoi(item); item = strtok_r(NULL, ".", &save_ptr); if (!item) { fprintf(stderr, "Unable to determine OpenGL version!\n"); free(tmp); return false; } context->gl_minor = atoi(item); free(tmp); } if(context->context) { return true; } else { return false; } }
void *glx_init(glx_opengl_version_t version) { Display *display; struct state_glx *context; context = (struct state_glx *) malloc(sizeof(struct state_glx)); context->magic = GLX_MAGIC; x11_lock(); display = x11_acquire_display(); if(!display) { free(context); x11_unlock(); return NULL; } #ifdef HAVE_GPUPERFAPI GPA_Status gpa_status; gpa_status = GPA_Initialize(); assert(gpa_status == GPA_STATUS_OK); #endif // Get a matching FB config static int visual_attribs[] = { GLX_X_RENDERABLE , True, GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, GLX_RENDER_TYPE , GLX_RGBA_BIT, GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, GLX_RED_SIZE , 8, GLX_GREEN_SIZE , 8, GLX_BLUE_SIZE , 8, GLX_ALPHA_SIZE , 8, GLX_DEPTH_SIZE , 24, GLX_STENCIL_SIZE , 8, GLX_DOUBLEBUFFER , True, //GLX_SAMPLE_BUFFERS , 1, //GLX_SAMPLES , 4, None }; int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if ( !glXQueryVersion( display, &glx_major, &glx_minor ) || ( ( glx_major == 1 ) && ( glx_minor < 3 ) ) || ( glx_major < 1 ) ) { printf( "Invalid GLX version" ); goto error; } printf( "Getting matching framebuffer configs\n" ); int fbcount; GLXFBConfig *fbc = glXChooseFBConfig( display, DefaultScreen( display ), visual_attribs, &fbcount ); if ( !fbc ) { printf( "Failed to retrieve a framebuffer config\n" ); goto error; } printf( "Found %d matching FB configs.\n", fbcount ); // Pick the FB config/visual with the most samples per pixel printf( "Getting XVisualInfos\n" ); int best_fbc = -1, worst_fbc = -1, best_num_samp = -1, worst_num_samp = 999; int i; for ( i = 0; i < fbcount; i++ ) { XVisualInfo *vi = glXGetVisualFromFBConfig( display, fbc[i] ); if ( vi ) { int samp_buf, samples; glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf ); glXGetFBConfigAttrib( display, fbc[i], GLX_SAMPLES , &samples ); printf( " Matching fbconfig %d, visual ID 0x%2x: SAMPLE_BUFFERS = %d," " SAMPLES = %d\n", i, (unsigned int) vi -> visualid, samp_buf, samples ); if ( best_fbc < 0 || (samp_buf && samples > best_num_samp )) best_fbc = i, best_num_samp = samples; if ( worst_fbc < 0 || !samp_buf || samples < worst_num_samp ) worst_fbc = i, worst_num_samp = samples; } XFree( vi ); } GLXFBConfig bestFbc = fbc[ best_fbc ]; // Be sure to free the FBConfig list allocated by glXChooseFBConfig() XFree( fbc ); // Get a visual XVisualInfo *vi = glXGetVisualFromFBConfig( display, bestFbc ); printf( "Chosen visual ID = 0x%x\n", (unsigned int) vi->visualid ); printf( "Creating colormap\n" ); XSetWindowAttributes swa; swa.colormap = context->cmap = XCreateColormap( display, RootWindow( display, vi->screen ), vi->visual, AllocNone ); swa.background_pixmap = None ; swa.border_pixel = 0; swa.event_mask = StructureNotifyMask; printf( "Creating window\n" ); context->win = XCreateWindow( display, RootWindow( display, vi->screen ), 0, 0, 1920, 1080, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa ); XMoveWindow(display, context->win, 0, 0); if ( !context->win ) { printf( "Failed to create window.\n" ); goto error; } // Done with the visual info data XFree( vi ); /* We don't need this for UG */ /*XStoreName( display, win, "GL 3.0 Window" ); printf( "Mapping window\n" ); XMapWindow( display, win );*/ // Get the default screen's GLX extension list const char *glxExts = glXQueryExtensionsString( display, DefaultScreen( display ) ); // NOTE: It is not necessary to create or make current to a context before // calling glXGetProcAddressARB glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0; glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB( (const GLubyte *) "glXCreateContextAttribsARB" ); context->ctx = 0; // Install an X error handler so the application won't exit if GL 3.0 // context allocation fails. // // Note this error handler is global. All display connections in all threads // of a process use the same error handler, so be sure to guard against other // threads issuing X commands while this code is running. ctxErrorOccurred = FALSE; int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler); // Check for the GLX_ARB_create_context extension string and the function. // If either is not present, use GLX 1.3 context creation method. if ( !isExtensionSupported( glxExts, "GLX_ARB_create_context" ) || !glXCreateContextAttribsARB ) { printf( "glXCreateContextAttribsARB() not found" " ... using old-style GLX context\n" ); context->ctx = glXCreateNewContext( display, bestFbc, GLX_RGBA_TYPE, 0, True ); if(!VERSION_IS_UNSPECIFIED(version)) { return NULL; } } // If it does, try to get a GL 3.0 context! else { int context_attribs[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 0, //GLX_CONTEXT_FLAGS_ARB , GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; if(!VERSION_IS_UNSPECIFIED(version)) { context_attribs[1] = VERSION_GET_MAJOR(version); context_attribs[3] = VERSION_GET_MINOR(version); } printf( "Creating context\n" ); context->ctx = glXCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs ); // Sync to ensure any errors generated are processed. XSync( display, False ); if ( !ctxErrorOccurred && context->ctx ) printf( "Created GL %d.%d context\n", context_attribs[1], context_attribs[3]); else { if(VERSION_IS_UNSPECIFIED(version)) { // Couldn't create GL 3.0 context. Fall back to old-style 2.x context. // When a context version below 3.0 is requested, implementations will // return the newest context version compatible with OpenGL versions less // than version 3.0. // GLX_CONTEXT_MAJOR_VERSION_ARB = 1 context_attribs[1] = 1; // GLX_CONTEXT_MINOR_VERSION_ARB = 0 context_attribs[3] = 0; ctxErrorOccurred = FALSE; printf( "Failed to create GL 3.0 context" " ... using old-style GLX context\n" ); context->ctx = glXCreateContextAttribsARB( display, bestFbc, 0, True, context_attribs ); } else { // we explicitly requested context which we cannot obtain - return error then goto error; } } } // Sync to ensure any errors generated are processed. XSync( display, False ); // Restore the original error handler XSetErrorHandler( oldHandler ); if ( ctxErrorOccurred || !context->ctx ) { printf( "Failed to create an OpenGL context\n" ); goto error; } // Verifying that context is a direct context if ( ! glXIsDirect ( display, context->ctx ) ) { printf( "Indirect GLX rendering context obtained\n" ); } else { printf( "Direct GLX rendering context obtained\n" ); } printf( "Making context current\n" ); glXMakeCurrent( display, context->win, context->ctx ); glewInit(); x11_unlock(); glx_validate(context); #ifdef HAVE_GPUPERFAPI gpa_status = GPA_OpenContext( context->ctx ); assert(gpa_status == GPA_STATUS_OK); #endif return (void *) context; error: free(context); x11_unlock(); return NULL; }