glxscreens.c revision 4642e01f
14642e01fSmrg/* 24642e01fSmrg * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) 34642e01fSmrg * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. 44642e01fSmrg * 54642e01fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 64642e01fSmrg * copy of this software and associated documentation files (the "Software"), 74642e01fSmrg * to deal in the Software without restriction, including without limitation 84642e01fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 94642e01fSmrg * and/or sell copies of the Software, and to permit persons to whom the 104642e01fSmrg * Software is furnished to do so, subject to the following conditions: 114642e01fSmrg * 124642e01fSmrg * The above copyright notice including the dates of first publication and 134642e01fSmrg * either this permission notice or a reference to 144642e01fSmrg * http://oss.sgi.com/projects/FreeB/ 154642e01fSmrg * shall be included in all copies or substantial portions of the Software. 164642e01fSmrg * 174642e01fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 184642e01fSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 194642e01fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 204642e01fSmrg * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 214642e01fSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 224642e01fSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 234642e01fSmrg * SOFTWARE. 244642e01fSmrg * 254642e01fSmrg * Except as contained in this notice, the name of Silicon Graphics, Inc. 264642e01fSmrg * shall not be used in advertising or otherwise to promote the sale, use or 274642e01fSmrg * other dealings in this Software without prior written authorization from 284642e01fSmrg * Silicon Graphics, Inc. 294642e01fSmrg */ 304642e01fSmrg 314642e01fSmrg#ifdef HAVE_DIX_CONFIG_H 324642e01fSmrg#include <dix-config.h> 334642e01fSmrg#endif 344642e01fSmrg 354642e01fSmrg#include <GL/glxtokens.h> 364642e01fSmrg#include <string.h> 374642e01fSmrg#include <windowstr.h> 384642e01fSmrg#include <os.h> 394642e01fSmrg#include <colormapst.h> 404642e01fSmrg 414642e01fSmrg#include "privates.h" 424642e01fSmrg#include "glxserver.h" 434642e01fSmrg#include "glxutil.h" 444642e01fSmrg#include "glxext.h" 454642e01fSmrg 464642e01fSmrgstatic int glxScreenPrivateKeyIndex; 474642e01fSmrgstatic DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKeyIndex; 484642e01fSmrg 494642e01fSmrgconst char GLServerVersion[] = "1.4"; 504642e01fSmrgstatic const char GLServerExtensions[] = 514642e01fSmrg "GL_ARB_depth_texture " 524642e01fSmrg "GL_ARB_draw_buffers " 534642e01fSmrg "GL_ARB_fragment_program " 544642e01fSmrg "GL_ARB_fragment_program_shadow " 554642e01fSmrg "GL_ARB_imaging " 564642e01fSmrg "GL_ARB_multisample " 574642e01fSmrg "GL_ARB_multitexture " 584642e01fSmrg "GL_ARB_occlusion_query " 594642e01fSmrg "GL_ARB_point_parameters " 604642e01fSmrg "GL_ARB_point_sprite " 614642e01fSmrg "GL_ARB_shadow " 624642e01fSmrg "GL_ARB_shadow_ambient " 634642e01fSmrg "GL_ARB_texture_border_clamp " 644642e01fSmrg "GL_ARB_texture_compression " 654642e01fSmrg "GL_ARB_texture_cube_map " 664642e01fSmrg "GL_ARB_texture_env_add " 674642e01fSmrg "GL_ARB_texture_env_combine " 684642e01fSmrg "GL_ARB_texture_env_crossbar " 694642e01fSmrg "GL_ARB_texture_env_dot3 " 704642e01fSmrg "GL_ARB_texture_mirrored_repeat " 714642e01fSmrg "GL_ARB_texture_non_power_of_two " 724642e01fSmrg "GL_ARB_transpose_matrix " 734642e01fSmrg "GL_ARB_vertex_program " 744642e01fSmrg "GL_ARB_window_pos " 754642e01fSmrg "GL_EXT_abgr " 764642e01fSmrg "GL_EXT_bgra " 774642e01fSmrg "GL_EXT_blend_color " 784642e01fSmrg "GL_EXT_blend_equation_separate " 794642e01fSmrg "GL_EXT_blend_func_separate " 804642e01fSmrg "GL_EXT_blend_logic_op " 814642e01fSmrg "GL_EXT_blend_minmax " 824642e01fSmrg "GL_EXT_blend_subtract " 834642e01fSmrg "GL_EXT_clip_volume_hint " 844642e01fSmrg "GL_EXT_copy_texture " 854642e01fSmrg "GL_EXT_draw_range_elements " 864642e01fSmrg "GL_EXT_fog_coord " 874642e01fSmrg "GL_EXT_framebuffer_object " 884642e01fSmrg "GL_EXT_multi_draw_arrays " 894642e01fSmrg "GL_EXT_packed_pixels " 904642e01fSmrg "GL_EXT_paletted_texture " 914642e01fSmrg "GL_EXT_point_parameters " 924642e01fSmrg "GL_EXT_polygon_offset " 934642e01fSmrg "GL_EXT_rescale_normal " 944642e01fSmrg "GL_EXT_secondary_color " 954642e01fSmrg "GL_EXT_separate_specular_color " 964642e01fSmrg "GL_EXT_shadow_funcs " 974642e01fSmrg "GL_EXT_shared_texture_palette " 984642e01fSmrg "GL_EXT_stencil_two_side " 994642e01fSmrg "GL_EXT_stencil_wrap " 1004642e01fSmrg "GL_EXT_subtexture " 1014642e01fSmrg "GL_EXT_texture " 1024642e01fSmrg "GL_EXT_texture3D " 1034642e01fSmrg "GL_EXT_texture_compression_dxt1 " 1044642e01fSmrg "GL_EXT_texture_compression_s3tc " 1054642e01fSmrg "GL_EXT_texture_edge_clamp " 1064642e01fSmrg "GL_EXT_texture_env_add " 1074642e01fSmrg "GL_EXT_texture_env_combine " 1084642e01fSmrg "GL_EXT_texture_env_dot3 " 1094642e01fSmrg "GL_EXT_texture_filter_anisotropic " 1104642e01fSmrg "GL_EXT_texture_lod " 1114642e01fSmrg "GL_EXT_texture_lod_bias " 1124642e01fSmrg "GL_EXT_texture_mirror_clamp " 1134642e01fSmrg "GL_EXT_texture_object " 1144642e01fSmrg "GL_EXT_texture_rectangle " 1154642e01fSmrg "GL_EXT_vertex_array " 1164642e01fSmrg "GL_3DFX_texture_compression_FXT1 " 1174642e01fSmrg "GL_APPLE_packed_pixels " 1184642e01fSmrg "GL_ATI_draw_buffers " 1194642e01fSmrg "GL_ATI_texture_env_combine3 " 1204642e01fSmrg "GL_ATI_texture_mirror_once " 1214642e01fSmrg "GL_HP_occlusion_test " 1224642e01fSmrg "GL_IBM_texture_mirrored_repeat " 1234642e01fSmrg "GL_INGR_blend_func_separate " 1244642e01fSmrg "GL_MESA_pack_invert " 1254642e01fSmrg "GL_MESA_ycbcr_texture " 1264642e01fSmrg "GL_NV_blend_square " 1274642e01fSmrg "GL_NV_depth_clamp " 1284642e01fSmrg "GL_NV_fog_distance " 1294642e01fSmrg "GL_NV_fragment_program " 1304642e01fSmrg "GL_NV_fragment_program_option " 1314642e01fSmrg "GL_NV_fragment_program2 " 1324642e01fSmrg "GL_NV_light_max_exponent " 1334642e01fSmrg "GL_NV_multisample_filter_hint " 1344642e01fSmrg "GL_NV_point_sprite " 1354642e01fSmrg "GL_NV_texgen_reflection " 1364642e01fSmrg "GL_NV_texture_compression_vtc " 1374642e01fSmrg "GL_NV_texture_env_combine4 " 1384642e01fSmrg "GL_NV_texture_expand_normal " 1394642e01fSmrg "GL_NV_texture_rectangle " 1404642e01fSmrg "GL_NV_vertex_program " 1414642e01fSmrg "GL_NV_vertex_program1_1 " 1424642e01fSmrg "GL_NV_vertex_program2 " 1434642e01fSmrg "GL_NV_vertex_program2_option " 1444642e01fSmrg "GL_NV_vertex_program3 " 1454642e01fSmrg "GL_OES_compressed_paletted_texture " 1464642e01fSmrg "GL_SGI_color_matrix " 1474642e01fSmrg "GL_SGI_color_table " 1484642e01fSmrg "GL_SGIS_generate_mipmap " 1494642e01fSmrg "GL_SGIS_multisample " 1504642e01fSmrg "GL_SGIS_point_parameters " 1514642e01fSmrg "GL_SGIS_texture_border_clamp " 1524642e01fSmrg "GL_SGIS_texture_edge_clamp " 1534642e01fSmrg "GL_SGIS_texture_lod " 1544642e01fSmrg "GL_SGIX_depth_texture " 1554642e01fSmrg "GL_SGIX_shadow " 1564642e01fSmrg "GL_SGIX_shadow_ambient " 1574642e01fSmrg "GL_SUN_slice_accum " 1584642e01fSmrg ; 1594642e01fSmrg 1604642e01fSmrg/* 1614642e01fSmrg** We have made the simplifying assuption that the same extensions are 1624642e01fSmrg** supported across all screens in a multi-screen system. 1634642e01fSmrg*/ 1644642e01fSmrgstatic char GLXServerVendorName[] = "SGI"; 1654642e01fSmrgstatic char GLXServerVersion[] = "1.2"; 1664642e01fSmrgstatic char GLXServerExtensions[] = 1674642e01fSmrg "GLX_ARB_multisample " 1684642e01fSmrg "GLX_EXT_visual_info " 1694642e01fSmrg "GLX_EXT_visual_rating " 1704642e01fSmrg "GLX_EXT_import_context " 1714642e01fSmrg "GLX_EXT_texture_from_pixmap " 1724642e01fSmrg "GLX_OML_swap_method " 1734642e01fSmrg "GLX_SGI_make_current_read " 1744642e01fSmrg#ifndef __APPLE__ 1754642e01fSmrg "GLX_SGIS_multisample " 1764642e01fSmrg "GLX_SGIX_hyperpipe " 1774642e01fSmrg "GLX_SGIX_swap_barrier " 1784642e01fSmrg#endif 1794642e01fSmrg "GLX_SGIX_fbconfig " 1804642e01fSmrg "GLX_MESA_copy_sub_buffer " 1814642e01fSmrg ; 1824642e01fSmrg 1834642e01fSmrg/* 1844642e01fSmrg * If your DDX driver wants to register support for swap barriers or hyperpipe 1854642e01fSmrg * topology, it should call __glXHyperpipeInit() or __glXSwapBarrierInit() 1864642e01fSmrg * with a dispatch table of functions to handle the requests. In the XFree86 1874642e01fSmrg * DDX, for example, you would call these near the bottom of the driver's 1884642e01fSmrg * ScreenInit method, after DRI has been initialized. 1894642e01fSmrg * 1904642e01fSmrg * This should be replaced with a better method when we teach the server how 1914642e01fSmrg * to load DRI drivers. 1924642e01fSmrg */ 1934642e01fSmrg 1944642e01fSmrgvoid __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs) 1954642e01fSmrg{ 1964642e01fSmrg __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); 1974642e01fSmrg 1984642e01fSmrg pGlxScreen->hyperpipeFuncs = funcs; 1994642e01fSmrg} 2004642e01fSmrg 2014642e01fSmrgvoid __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs) 2024642e01fSmrg{ 2034642e01fSmrg __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); 2044642e01fSmrg 2054642e01fSmrg pGlxScreen->swapBarrierFuncs = funcs; 2064642e01fSmrg} 2074642e01fSmrg 2084642e01fSmrgstatic Bool 2094642e01fSmrgglxCloseScreen (int index, ScreenPtr pScreen) 2104642e01fSmrg{ 2114642e01fSmrg __GLXscreen *pGlxScreen = glxGetScreen(pScreen); 2124642e01fSmrg 2134642e01fSmrg pScreen->CloseScreen = pGlxScreen->CloseScreen; 2144642e01fSmrg 2154642e01fSmrg pGlxScreen->destroy(pGlxScreen); 2164642e01fSmrg 2174642e01fSmrg return pScreen->CloseScreen(index, pScreen); 2184642e01fSmrg} 2194642e01fSmrg 2204642e01fSmrg__GLXscreen * 2214642e01fSmrgglxGetScreen(ScreenPtr pScreen) 2224642e01fSmrg{ 2234642e01fSmrg return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey); 2244642e01fSmrg} 2254642e01fSmrg 2264642e01fSmrgvoid GlxSetVisualConfigs(int nconfigs, 2274642e01fSmrg __GLXvisualConfig *configs, void **privates) 2284642e01fSmrg{ 2294642e01fSmrg /* We keep this stub around for the DDX drivers that still 2304642e01fSmrg * call it. */ 2314642e01fSmrg} 2324642e01fSmrg 2334642e01fSmrgGLint glxConvertToXVisualType(int visualType) 2344642e01fSmrg{ 2354642e01fSmrg static const int x_visual_types[] = { 2364642e01fSmrg TrueColor, DirectColor, 2374642e01fSmrg PseudoColor, StaticColor, 2384642e01fSmrg GrayScale, StaticGray 2394642e01fSmrg }; 2404642e01fSmrg 2414642e01fSmrg return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 ) 2424642e01fSmrg ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; 2434642e01fSmrg} 2444642e01fSmrg 2454642e01fSmrg/* This code inspired by composite/compinit.c. We could move this to 2464642e01fSmrg * mi/ and share it with composite.*/ 2474642e01fSmrg 2484642e01fSmrgstatic VisualPtr 2494642e01fSmrgAddScreenVisuals(ScreenPtr pScreen, int count, int d) 2504642e01fSmrg{ 2514642e01fSmrg XID *installedCmaps, *vids, vid; 2524642e01fSmrg int numInstalledCmaps, numVisuals, i, j; 2534642e01fSmrg VisualPtr visuals; 2544642e01fSmrg ColormapPtr installedCmap; 2554642e01fSmrg DepthPtr depth; 2564642e01fSmrg 2574642e01fSmrg depth = NULL; 2584642e01fSmrg for (i = 0; i < pScreen->numDepths; i++) { 2594642e01fSmrg if (pScreen->allowedDepths[i].depth == d) { 2604642e01fSmrg depth = &pScreen->allowedDepths[i]; 2614642e01fSmrg break; 2624642e01fSmrg } 2634642e01fSmrg } 2644642e01fSmrg if (depth == NULL) 2654642e01fSmrg return NULL; 2664642e01fSmrg 2674642e01fSmrg /* Find the installed colormaps */ 2684642e01fSmrg installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID)); 2694642e01fSmrg if (!installedCmaps) 2704642e01fSmrg return NULL; 2714642e01fSmrg 2724642e01fSmrg numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, installedCmaps); 2734642e01fSmrg 2744642e01fSmrg /* realloc the visual array to fit the new one in place */ 2754642e01fSmrg numVisuals = pScreen->numVisuals; 2764642e01fSmrg visuals = xrealloc(pScreen->visuals, (numVisuals + count) * sizeof(VisualRec)); 2774642e01fSmrg if (!visuals) { 2784642e01fSmrg xfree(installedCmaps); 2794642e01fSmrg return NULL; 2804642e01fSmrg } 2814642e01fSmrg 2824642e01fSmrg vids = xrealloc(depth->vids, (depth->numVids + count) * sizeof(XID)); 2834642e01fSmrg if (vids == NULL) { 2844642e01fSmrg xfree(installedCmaps); 2854642e01fSmrg xfree(visuals); 2864642e01fSmrg return NULL; 2874642e01fSmrg } 2884642e01fSmrg 2894642e01fSmrg /* 2904642e01fSmrg * Fix up any existing installed colormaps -- we'll assume that 2914642e01fSmrg * the only ones created so far have been installed. If this 2924642e01fSmrg * isn't true, we'll have to walk the resource database looking 2934642e01fSmrg * for all colormaps. 2944642e01fSmrg */ 2954642e01fSmrg for (i = 0; i < numInstalledCmaps; i++) { 2964642e01fSmrg installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP); 2974642e01fSmrg if (!installedCmap) 2984642e01fSmrg continue; 2994642e01fSmrg j = installedCmap->pVisual - pScreen->visuals; 3004642e01fSmrg installedCmap->pVisual = &visuals[j]; 3014642e01fSmrg } 3024642e01fSmrg 3034642e01fSmrg xfree(installedCmaps); 3044642e01fSmrg 3054642e01fSmrg for (i = 0; i < count; i++) { 3064642e01fSmrg vid = FakeClientID(0); 3074642e01fSmrg visuals[pScreen->numVisuals + i].vid = vid; 3084642e01fSmrg vids[depth->numVids + i] = vid; 3094642e01fSmrg } 3104642e01fSmrg 3114642e01fSmrg pScreen->visuals = visuals; 3124642e01fSmrg pScreen->numVisuals += count; 3134642e01fSmrg depth->vids = vids; 3144642e01fSmrg depth->numVids += count; 3154642e01fSmrg 3164642e01fSmrg /* Return a pointer to the first of the added visuals. */ 3174642e01fSmrg return pScreen->visuals + pScreen->numVisuals - count; 3184642e01fSmrg} 3194642e01fSmrg 3204642e01fSmrgstatic int 3214642e01fSmrgfindFirstSet(unsigned int v) 3224642e01fSmrg{ 3234642e01fSmrg int i; 3244642e01fSmrg 3254642e01fSmrg for (i = 0; i < 32; i++) 3264642e01fSmrg if (v & (1 << i)) 3274642e01fSmrg return i; 3284642e01fSmrg 3294642e01fSmrg return -1; 3304642e01fSmrg} 3314642e01fSmrg 3324642e01fSmrgstatic void 3334642e01fSmrginitGlxVisual(VisualPtr visual, __GLXconfig *config) 3344642e01fSmrg{ 3354642e01fSmrg int maxBits; 3364642e01fSmrg maxBits = max(config->redBits, max(config->greenBits, config->blueBits)); 3374642e01fSmrg 3384642e01fSmrg config->visualID = visual->vid; 3394642e01fSmrg visual->class = glxConvertToXVisualType(config->visualType); 3404642e01fSmrg visual->bitsPerRGBValue = maxBits; 3414642e01fSmrg visual->ColormapEntries = 1 << maxBits; 3424642e01fSmrg visual->nplanes = config->redBits + config->greenBits + config->blueBits; 3434642e01fSmrg 3444642e01fSmrg visual->redMask = config->redMask; 3454642e01fSmrg visual->greenMask = config->greenMask; 3464642e01fSmrg visual->blueMask = config->blueMask; 3474642e01fSmrg visual->offsetRed = findFirstSet(config->redMask); 3484642e01fSmrg visual->offsetGreen = findFirstSet(config->greenMask); 3494642e01fSmrg visual->offsetBlue = findFirstSet(config->blueMask); 3504642e01fSmrg} 3514642e01fSmrg 3524642e01fSmrgstatic __GLXconfig * 3534642e01fSmrgpickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual) 3544642e01fSmrg{ 3554642e01fSmrg __GLXconfig *best = NULL, *config; 3564642e01fSmrg int best_score = 0; 3574642e01fSmrg 3584642e01fSmrg for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { 3594642e01fSmrg int score = 0; 3604642e01fSmrg 3614642e01fSmrg if (config->redMask != visual->redMask || 3624642e01fSmrg config->greenMask != visual->greenMask || 3634642e01fSmrg config->blueMask != visual->blueMask) 3644642e01fSmrg continue; 3654642e01fSmrg if (config->visualRating != GLX_NONE) 3664642e01fSmrg continue; 3674642e01fSmrg if (glxConvertToXVisualType(config->visualType) != visual->class) 3684642e01fSmrg continue; 3694642e01fSmrg /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */ 3704642e01fSmrg if (visual->nplanes == 32 && config->rgbBits != 32) 3714642e01fSmrg continue; 3724642e01fSmrg /* Can't use the same FBconfig for multiple X visuals. I think. */ 3734642e01fSmrg if (config->visualID != 0) 3744642e01fSmrg continue; 3754642e01fSmrg 3764642e01fSmrg if (config->doubleBufferMode > 0) 3774642e01fSmrg score += 8; 3784642e01fSmrg if (config->depthBits > 0) 3794642e01fSmrg score += 4; 3804642e01fSmrg if (config->stencilBits > 0) 3814642e01fSmrg score += 2; 3824642e01fSmrg if (config->alphaBits > 0) 3834642e01fSmrg score++; 3844642e01fSmrg 3854642e01fSmrg if (score > best_score) { 3864642e01fSmrg best = config; 3874642e01fSmrg best_score = score; 3884642e01fSmrg } 3894642e01fSmrg } 3904642e01fSmrg 3914642e01fSmrg return best; 3924642e01fSmrg} 3934642e01fSmrg 3944642e01fSmrgvoid __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) 3954642e01fSmrg{ 3964642e01fSmrg __GLXconfig *m; 3974642e01fSmrg __GLXconfig *config; 3984642e01fSmrg int i; 3994642e01fSmrg 4004642e01fSmrg pGlxScreen->pScreen = pScreen; 4014642e01fSmrg pGlxScreen->GLextensions = xstrdup(GLServerExtensions); 4024642e01fSmrg pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); 4034642e01fSmrg pGlxScreen->GLXversion = xstrdup(GLXServerVersion); 4044642e01fSmrg pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); 4054642e01fSmrg 4064642e01fSmrg pGlxScreen->CloseScreen = pScreen->CloseScreen; 4074642e01fSmrg pScreen->CloseScreen = glxCloseScreen; 4084642e01fSmrg 4094642e01fSmrg i = 0; 4104642e01fSmrg for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { 4114642e01fSmrg m->fbconfigID = FakeClientID(0); 4124642e01fSmrg m->visualID = 0; 4134642e01fSmrg i++; 4144642e01fSmrg } 4154642e01fSmrg pGlxScreen->numFBConfigs = i; 4164642e01fSmrg 4174642e01fSmrg pGlxScreen->visuals = 4184642e01fSmrg xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *)); 4194642e01fSmrg 4204642e01fSmrg /* First, try to choose featureful FBconfigs for the existing X visuals. 4214642e01fSmrg * Note that if multiple X visuals end up with the same FBconfig being 4224642e01fSmrg * chosen, the later X visuals don't get GLX visuals (because we want to 4234642e01fSmrg * prioritize the root visual being GLX). 4244642e01fSmrg */ 4254642e01fSmrg for (i = 0; i < pScreen->numVisuals; i++) { 4264642e01fSmrg VisualPtr visual = &pScreen->visuals[i]; 4274642e01fSmrg 4284642e01fSmrg config = pickFBConfig(pGlxScreen, visual); 4294642e01fSmrg if (config) { 4304642e01fSmrg pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; 4314642e01fSmrg config->visualID = visual->vid; 4324642e01fSmrg } 4334642e01fSmrg } 4344642e01fSmrg 4354642e01fSmrg /* Then, add new visuals corresponding to all FBconfigs that didn't have 4364642e01fSmrg * an existing, appropriate visual. 4374642e01fSmrg */ 4384642e01fSmrg for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { 4394642e01fSmrg int depth; 4404642e01fSmrg 4414642e01fSmrg VisualPtr visual; 4424642e01fSmrg 4434642e01fSmrg if (config->visualID != 0) 4444642e01fSmrg continue; 4454642e01fSmrg 4464642e01fSmrg /* Only count RGB bits and not alpha, as we're not trying to create 4474642e01fSmrg * visuals for compositing (that's what the 32-bit composite visual 4484642e01fSmrg * set up above is for. 4494642e01fSmrg */ 4504642e01fSmrg depth = config->redBits + config->greenBits + config->blueBits; 4514642e01fSmrg 4524642e01fSmrg /* Make sure that our FBconfig's depth can actually be displayed 4534642e01fSmrg * (corresponds to an existing visual). 4544642e01fSmrg */ 4554642e01fSmrg for (i = 0; i < pScreen->numVisuals; i++) { 4564642e01fSmrg if (depth == pScreen->visuals[i].nplanes) 4574642e01fSmrg break; 4584642e01fSmrg } 4594642e01fSmrg if (i == pScreen->numVisuals) 4604642e01fSmrg continue; 4614642e01fSmrg 4624642e01fSmrg /* Create a new X visual for our FBconfig. */ 4634642e01fSmrg visual = AddScreenVisuals(pScreen, 1, depth); 4644642e01fSmrg if (visual == NULL) 4654642e01fSmrg continue; 4664642e01fSmrg 4674642e01fSmrg pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; 4684642e01fSmrg initGlxVisual(visual, config); 4694642e01fSmrg } 4704642e01fSmrg 4714642e01fSmrg dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen); 4724642e01fSmrg} 4734642e01fSmrg 4744642e01fSmrgvoid __glXScreenDestroy(__GLXscreen *screen) 4754642e01fSmrg{ 4764642e01fSmrg xfree(screen->GLXvendor); 4774642e01fSmrg xfree(screen->GLXversion); 4784642e01fSmrg xfree(screen->GLXextensions); 4794642e01fSmrg xfree(screen->GLextensions); 4804642e01fSmrg} 481