📄 fakeglx.c
字号:
*/ return deepvis;}/**********************************************************************//*** Display-related functions ***//**********************************************************************//** * Free all XMesaVisuals which are associated with the given display. */static voiddestroy_visuals_on_display(Display *dpy){ int i; for (i = 0; i < NumVisuals; i++) { if (VisualTable[i]->display == dpy) { /* remove this visual */ int j; free(VisualTable[i]); for (j = i; j < NumVisuals - 1; j++) VisualTable[j] = VisualTable[j + 1]; NumVisuals--; } }}/** * Called from XCloseDisplay() to let us free our display-related data. */static intclose_display_callback(Display *dpy, XExtCodes *codes){ destroy_visuals_on_display(dpy); xmesa_destroy_buffers_on_display(dpy); return 0;}/** * Look for the named extension on given display and return a pointer * to the _XExtension data, or NULL if extension not found. */static _XExtension *lookup_extension(Display *dpy, const char *extName){ _XExtension *ext; for (ext = dpy->ext_procs; ext; ext = ext->next) { if (ext->name && strcmp(ext->name, extName) == 0) { return ext; } } return NULL;}/** * Whenever we're given a new Display pointer, call this function to * register our close_display_callback function. */static voidregister_with_display(Display *dpy){ const char *extName = "MesaGLX"; _XExtension *ext; ext = lookup_extension(dpy, extName); if (!ext) { XExtCodes *c = XAddExtension(dpy); ext = dpy->ext_procs; /* new extension is at head of list */ assert(c->extension == ext->codes.extension); ext->name = _mesa_strdup(extName); ext->close_display = close_display_callback; }}/**********************************************************************//*** Begin Fake GLX API Functions ***//**********************************************************************//** * Helper used by glXChooseVisual and glXChooseFBConfig. * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for * the later. * In either case, the attribute list is terminated with the value 'None'. */static XMesaVisualchoose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ){ const GLboolean rgbModeDefault = fbConfig; const int *parselist; XVisualInfo *vis; int min_ci = 0; int min_red=0, min_green=0, min_blue=0; GLboolean rgb_flag = rgbModeDefault; GLboolean alpha_flag = GL_FALSE; GLboolean double_flag = GL_FALSE; GLboolean stereo_flag = GL_FALSE; GLint depth_size = 0; GLint stencil_size = 0; GLint accumRedSize = 0; GLint accumGreenSize = 0; GLint accumBlueSize = 0; GLint accumAlphaSize = 0; int level = 0; int visual_type = DONT_CARE; int trans_type = DONT_CARE; int trans_value = DONT_CARE; GLint caveat = DONT_CARE; XMesaVisual xmvis = NULL; int desiredVisualID = -1; int numAux = 0; parselist = list; while (*parselist) { switch (*parselist) { case GLX_USE_GL: if (fbConfig) { /* invalid token */ return NULL; } else { /* skip */ parselist++; } break; case GLX_BUFFER_SIZE: parselist++; min_ci = *parselist++; break; case GLX_LEVEL: parselist++; level = *parselist++; break; case GLX_RGBA: if (fbConfig) { /* invalid token */ return NULL; } else { rgb_flag = GL_TRUE; parselist++; } break; case GLX_DOUBLEBUFFER: parselist++; if (fbConfig) { double_flag = *parselist++; } else { double_flag = GL_TRUE; } break; case GLX_STEREO: parselist++; if (fbConfig) { stereo_flag = *parselist++; } else { stereo_flag = GL_TRUE; } break; case GLX_AUX_BUFFERS: parselist++; numAux = *parselist++; if (numAux > MAX_AUX_BUFFERS) return NULL; break; case GLX_RED_SIZE: parselist++; min_red = *parselist++; break; case GLX_GREEN_SIZE: parselist++; min_green = *parselist++; break; case GLX_BLUE_SIZE: parselist++; min_blue = *parselist++; break; case GLX_ALPHA_SIZE: parselist++; { GLint size = *parselist++; alpha_flag = size ? GL_TRUE : GL_FALSE; } break; case GLX_DEPTH_SIZE: parselist++; depth_size = *parselist++; break; case GLX_STENCIL_SIZE: parselist++; stencil_size = *parselist++; break; case GLX_ACCUM_RED_SIZE: parselist++; { GLint size = *parselist++; accumRedSize = MAX2( accumRedSize, size ); } break; case GLX_ACCUM_GREEN_SIZE: parselist++; { GLint size = *parselist++; accumGreenSize = MAX2( accumGreenSize, size ); } break; case GLX_ACCUM_BLUE_SIZE: parselist++; { GLint size = *parselist++; accumBlueSize = MAX2( accumBlueSize, size ); } break; case GLX_ACCUM_ALPHA_SIZE: parselist++; { GLint size = *parselist++; accumAlphaSize = MAX2( accumAlphaSize, size ); } break; /* * GLX_EXT_visual_info extension */ case GLX_X_VISUAL_TYPE_EXT: parselist++; visual_type = *parselist++; break; case GLX_TRANSPARENT_TYPE_EXT: parselist++; trans_type = *parselist++; break; case GLX_TRANSPARENT_INDEX_VALUE_EXT: parselist++; trans_value = *parselist++; break; case GLX_TRANSPARENT_RED_VALUE_EXT: case GLX_TRANSPARENT_GREEN_VALUE_EXT: case GLX_TRANSPARENT_BLUE_VALUE_EXT: case GLX_TRANSPARENT_ALPHA_VALUE_EXT: /* ignore */ parselist++; parselist++; break; /* * GLX_EXT_visual_info extension */ case GLX_VISUAL_CAVEAT_EXT: parselist++; caveat = *parselist++; /* ignored for now */ break; /* * GLX_ARB_multisample */ case GLX_SAMPLE_BUFFERS_ARB: case GLX_SAMPLES_ARB: parselist++; if (*parselist++ != 0) /* ms not supported */ return NULL; break; /* * FBConfig attribs. */ case GLX_RENDER_TYPE: if (!fbConfig) return NULL; parselist++; if (*parselist == GLX_RGBA_BIT) { rgb_flag = GL_TRUE; } else if (*parselist == GLX_COLOR_INDEX_BIT) { rgb_flag = GL_FALSE; } else if (*parselist == 0) { rgb_flag = GL_TRUE; } parselist++; break; case GLX_DRAWABLE_TYPE: if (!fbConfig) return NULL; parselist++; if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { return NULL; /* bad bit */ } parselist++; break; case GLX_FBCONFIG_ID: if (!fbConfig) return NULL; parselist++; desiredVisualID = *parselist++; break; case GLX_X_RENDERABLE: if (!fbConfig) return NULL; parselist += 2; /* ignore */ break;#ifdef GLX_EXT_texture_from_pixmap case GLX_BIND_TO_TEXTURE_RGB_EXT: parselist++; /*skip*/ break; case GLX_BIND_TO_TEXTURE_RGBA_EXT: parselist++; /*skip*/ break; case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: parselist++; /*skip*/ break; case GLX_BIND_TO_TEXTURE_TARGETS_EXT: parselist++; if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT)) { /* invalid bit */ return NULL; } break; case GLX_Y_INVERTED_EXT: parselist++; /*skip*/ break;#endif case None: /* end of list */ break; default: /* undefined attribute */ _mesa_warning(NULL, "unexpected attrib 0x%x in choose_visual()", *parselist); return NULL; } } (void) caveat; /* * Since we're only simulating the GLX extension this function will never * find any real GL visuals. Instead, all we can do is try to find an RGB * or CI visual of appropriate depth. Other requested attributes such as * double buffering, depth buffer, etc. will be associated with the X * visual and stored in the VisualTable[]. */ if (desiredVisualID != -1) { /* try to get a specific visual, by visualID */ XVisualInfo temp; int n; temp.visualid = desiredVisualID; temp.screen = screen; vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); if (vis) { /* give the visual some useful GLX attributes */ double_flag = GL_TRUE; if (vis->depth > 8) rgb_flag = GL_TRUE; depth_size = default_depth_bits(); stencil_size = STENCIL_BITS; /* XXX accum??? */ } } else if (level==0) { /* normal color planes */ if (rgb_flag) { /* Get an RGB visual */ int min_rgb = min_red + min_green + min_blue; if (min_rgb>1 && min_rgb<8) { /* a special case to be sure we can get a monochrome visual */ min_rgb = 1; } vis = choose_x_visual( dpy, screen, rgb_flag, min_rgb, visual_type ); } else { /* Get a color index visual */ vis = choose_x_visual( dpy, screen, rgb_flag, min_ci, visual_type ); accumRedSize = accumGreenSize = accumBlueSize = accumAlphaSize = 0; } } else { /* over/underlay planes */ if (rgb_flag) { /* rgba overlay */ int min_rgb = min_red + min_green + min_blue; if (min_rgb>1 && min_rgb<8) { /* a special case to be sure we can get a monochrome visual */ min_rgb = 1; } vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, trans_type, trans_value, min_rgb, visual_type ); } else { /* color index overlay */ vis = choose_x_overlay_visual( dpy, screen, rgb_flag, level, trans_type, trans_value, min_ci, visual_type ); } } if (vis) { /* Note: we're not exactly obeying the glXChooseVisual rules here. * When GLX_DEPTH_SIZE = 1 is specified we're supposed to choose the * largest depth buffer size, which is 32bits/value. Instead, we * return 16 to maintain performance with earlier versions of Mesa. */ if (depth_size > 24) depth_size = 32; else if (depth_size > 16) depth_size = 24; else if (depth_size > 0) { depth_size = default_depth_bits(); } if (!alpha_flag) { alpha_flag = default_alpha_bits() > 0; } /* we only support one size of stencil and accum buffers. */ if (stencil_size > 0) stencil_size = STENCIL_BITS; if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || accumAlphaSize > 0) { accumRedSize = accumGreenSize = accumBlueSize = default_accum_bits(); accumAlphaSize = alpha_flag ? accumRedSize : 0; } xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, stereo_flag, depth_size, stencil_size, accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize, level, numAux ); } return xmvis;}static XVisualInfo *Fake_glXChooseVisual( Display *dpy, int screen, int *list ){ XMesaVisual xmvis; /* register ourselves as an extension on this display */ register_with_display(dpy);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -