xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

glxscreens.c (13956B)


      1 /*
      2  * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
      3  * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice including the dates of first publication and
     13  * either this permission notice or a reference to
     14  * http://oss.sgi.com/projects/FreeB/
     15  * shall be included in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     20  * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     21  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     22  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE.
     24  *
     25  * Except as contained in this notice, the name of Silicon Graphics, Inc.
     26  * shall not be used in advertising or otherwise to promote the sale, use or
     27  * other dealings in this Software without prior written authorization from
     28  * Silicon Graphics, Inc.
     29  */
     30 
     31 #ifdef HAVE_DIX_CONFIG_H
     32 #include <dix-config.h>
     33 #endif
     34 
     35 #include <GL/glxtokens.h>
     36 #include <string.h>
     37 #include <windowstr.h>
     38 #include <os.h>
     39 #include <colormapst.h>
     40 
     41 #include "extinit.h"
     42 #include "privates.h"
     43 #include "glxserver.h"
     44 #include "glxutil.h"
     45 #include "glxext.h"
     46 #include "protocol-versions.h"
     47 
     48 #ifdef COMPOSITE
     49 #include "compositeext.h"
     50 #endif
     51 
     52 static DevPrivateKeyRec glxScreenPrivateKeyRec;
     53 
     54 #define glxScreenPrivateKey (&glxScreenPrivateKeyRec)
     55 
     56 const char GLServerVersion[] = "1.4";
     57 static const char GLServerExtensions[] =
     58     "GL_ARB_depth_texture "
     59     "GL_ARB_draw_buffers "
     60     "GL_ARB_fragment_program "
     61     "GL_ARB_fragment_program_shadow "
     62     "GL_ARB_imaging "
     63     "GL_ARB_multisample "
     64     "GL_ARB_multitexture "
     65     "GL_ARB_occlusion_query "
     66     "GL_ARB_point_parameters "
     67     "GL_ARB_point_sprite "
     68     "GL_ARB_shadow "
     69     "GL_ARB_shadow_ambient "
     70     "GL_ARB_texture_border_clamp "
     71     "GL_ARB_texture_compression "
     72     "GL_ARB_texture_cube_map "
     73     "GL_ARB_texture_env_add "
     74     "GL_ARB_texture_env_combine "
     75     "GL_ARB_texture_env_crossbar "
     76     "GL_ARB_texture_env_dot3 "
     77     "GL_ARB_texture_mirrored_repeat "
     78     "GL_ARB_texture_non_power_of_two "
     79     "GL_ARB_transpose_matrix "
     80     "GL_ARB_vertex_program "
     81     "GL_ARB_window_pos "
     82     "GL_EXT_abgr "
     83     "GL_EXT_bgra "
     84     "GL_EXT_blend_color "
     85     "GL_EXT_blend_equation_separate "
     86     "GL_EXT_blend_func_separate "
     87     "GL_EXT_blend_logic_op "
     88     "GL_EXT_blend_minmax "
     89     "GL_EXT_blend_subtract "
     90     "GL_EXT_clip_volume_hint "
     91     "GL_EXT_copy_texture "
     92     "GL_EXT_draw_range_elements "
     93     "GL_EXT_fog_coord "
     94     "GL_EXT_framebuffer_object "
     95     "GL_EXT_multi_draw_arrays "
     96     "GL_EXT_packed_pixels "
     97     "GL_EXT_paletted_texture "
     98     "GL_EXT_point_parameters "
     99     "GL_EXT_polygon_offset "
    100     "GL_EXT_rescale_normal "
    101     "GL_EXT_secondary_color "
    102     "GL_EXT_separate_specular_color "
    103     "GL_EXT_shadow_funcs "
    104     "GL_EXT_shared_texture_palette "
    105     "GL_EXT_stencil_two_side "
    106     "GL_EXT_stencil_wrap "
    107     "GL_EXT_subtexture "
    108     "GL_EXT_texture "
    109     "GL_EXT_texture3D "
    110     "GL_EXT_texture_compression_dxt1 "
    111     "GL_EXT_texture_compression_s3tc "
    112     "GL_EXT_texture_edge_clamp "
    113     "GL_EXT_texture_env_add "
    114     "GL_EXT_texture_env_combine "
    115     "GL_EXT_texture_env_dot3 "
    116     "GL_EXT_texture_filter_anisotropic "
    117     "GL_EXT_texture_lod "
    118     "GL_EXT_texture_lod_bias "
    119     "GL_EXT_texture_mirror_clamp "
    120     "GL_EXT_texture_object "
    121     "GL_EXT_texture_rectangle "
    122     "GL_EXT_vertex_array "
    123     "GL_3DFX_texture_compression_FXT1 "
    124     "GL_APPLE_packed_pixels "
    125     "GL_ATI_draw_buffers "
    126     "GL_ATI_texture_env_combine3 "
    127     "GL_ATI_texture_mirror_once "
    128     "GL_HP_occlusion_test "
    129     "GL_IBM_texture_mirrored_repeat "
    130     "GL_INGR_blend_func_separate "
    131     "GL_MESA_pack_invert "
    132     "GL_MESA_ycbcr_texture "
    133     "GL_NV_blend_square "
    134     "GL_NV_depth_clamp "
    135     "GL_NV_fog_distance "
    136     "GL_NV_fragment_program_option "
    137     "GL_NV_fragment_program2 "
    138     "GL_NV_light_max_exponent "
    139     "GL_NV_multisample_filter_hint "
    140     "GL_NV_point_sprite "
    141     "GL_NV_texgen_reflection "
    142     "GL_NV_texture_compression_vtc "
    143     "GL_NV_texture_env_combine4 "
    144     "GL_NV_texture_expand_normal "
    145     "GL_NV_texture_rectangle "
    146     "GL_NV_vertex_program2_option "
    147     "GL_NV_vertex_program3 "
    148     "GL_OES_compressed_paletted_texture "
    149     "GL_SGI_color_matrix "
    150     "GL_SGI_color_table "
    151     "GL_SGIS_generate_mipmap "
    152     "GL_SGIS_multisample "
    153     "GL_SGIS_point_parameters "
    154     "GL_SGIS_texture_border_clamp "
    155     "GL_SGIS_texture_edge_clamp "
    156     "GL_SGIS_texture_lod "
    157     "GL_SGIX_depth_texture "
    158     "GL_SGIX_shadow "
    159     "GL_SGIX_shadow_ambient "
    160     "GL_SUN_slice_accum ";
    161 
    162 static Bool
    163 glxCloseScreen(ScreenPtr pScreen)
    164 {
    165     __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
    166 
    167     pScreen->CloseScreen = pGlxScreen->CloseScreen;
    168 
    169     pGlxScreen->destroy(pGlxScreen);
    170 
    171     return pScreen->CloseScreen(pScreen);
    172 }
    173 
    174 __GLXscreen *
    175 glxGetScreen(ScreenPtr pScreen)
    176 {
    177     return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
    178 }
    179 
    180 GLint
    181 glxConvertToXVisualType(int visualType)
    182 {
    183     static const int x_visual_types[] = {
    184         TrueColor, DirectColor,
    185         PseudoColor, StaticColor,
    186         GrayScale, StaticGray
    187     };
    188 
    189     return ((unsigned) (visualType - GLX_TRUE_COLOR) < 6)
    190         ? x_visual_types[visualType - GLX_TRUE_COLOR] : -1;
    191 }
    192 
    193 /* This code inspired by composite/compinit.c.  We could move this to
    194  * mi/ and share it with composite.*/
    195 
    196 static VisualPtr
    197 AddScreenVisuals(ScreenPtr pScreen, int count, int d)
    198 {
    199     int i;
    200     DepthPtr depth;
    201 
    202     depth = NULL;
    203     for (i = 0; i < pScreen->numDepths; i++) {
    204         if (pScreen->allowedDepths[i].depth == d) {
    205             depth = &pScreen->allowedDepths[i];
    206             break;
    207         }
    208     }
    209     if (depth == NULL)
    210         return NULL;
    211 
    212     if (ResizeVisualArray(pScreen, count, depth) == FALSE)
    213         return NULL;
    214 
    215     /* Return a pointer to the first of the added visuals. */
    216     return pScreen->visuals + pScreen->numVisuals - count;
    217 }
    218 
    219 static int
    220 findFirstSet(unsigned int v)
    221 {
    222     int i;
    223 
    224     for (i = 0; i < 32; i++)
    225         if (v & (1 << i))
    226             return i;
    227 
    228     return -1;
    229 }
    230 
    231 static void
    232 initGlxVisual(VisualPtr visual, __GLXconfig * config)
    233 {
    234     int maxBits;
    235 
    236     maxBits = max(config->redBits, max(config->greenBits, config->blueBits));
    237 
    238     config->visualID = visual->vid;
    239     visual->class = glxConvertToXVisualType(config->visualType);
    240     visual->bitsPerRGBValue = maxBits;
    241     visual->ColormapEntries = 1 << maxBits;
    242     visual->nplanes = config->redBits + config->greenBits + config->blueBits;
    243 
    244     visual->redMask = config->redMask;
    245     visual->greenMask = config->greenMask;
    246     visual->blueMask = config->blueMask;
    247     visual->offsetRed = findFirstSet(config->redMask);
    248     visual->offsetGreen = findFirstSet(config->greenMask);
    249     visual->offsetBlue = findFirstSet(config->blueMask);
    250 }
    251 
    252 static __GLXconfig *
    253 pickFBConfig(__GLXscreen * pGlxScreen, VisualPtr visual)
    254 {
    255     __GLXconfig *best = NULL, *config;
    256     int best_score = 0;
    257 
    258     for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
    259         int score = 0;
    260 
    261         if (config->redMask != visual->redMask ||
    262             config->greenMask != visual->greenMask ||
    263             config->blueMask != visual->blueMask)
    264             continue;
    265         if (config->visualRating != GLX_NONE)
    266             continue;
    267         /* Ignore multisampled configs */
    268         if (config->sampleBuffers)
    269             continue;
    270         if (glxConvertToXVisualType(config->visualType) != visual->class)
    271             continue;
    272         /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */
    273         if (visual->nplanes == 32 && config->rgbBits != 32)
    274             continue;
    275         /* If it's the 32-bit RGBA visual, do not pick sRGB capable config.
    276          * This can cause issues with compositors that are not sRGB aware.
    277          */
    278         if (visual->nplanes == 32 && config->sRGBCapable == GL_TRUE)
    279             continue;
    280         /* Can't use the same FBconfig for multiple X visuals.  I think. */
    281         if (config->visualID != 0)
    282             continue;
    283 #ifdef COMPOSITE
    284         if (!noCompositeExtension) {
    285             /* Use only duplicated configs for compIsAlternateVisuals */
    286             if (!!compIsAlternateVisual(pGlxScreen->pScreen, visual->vid) !=
    287                 !!config->duplicatedForComp)
    288                 continue;
    289         }
    290 #endif
    291         /*
    292          * If possible, use the same swapmethod for all built-in visual
    293          * fbconfigs, to avoid getting the 32-bit composite visual when
    294          * requesting, for example, a SWAP_COPY fbconfig.
    295          */
    296         if (config->swapMethod == GLX_SWAP_UNDEFINED_OML)
    297             score += 32;
    298         if (config->swapMethod == GLX_SWAP_EXCHANGE_OML)
    299             score += 16;
    300         if (config->doubleBufferMode > 0)
    301             score += 8;
    302         if (config->depthBits > 0)
    303             score += 4;
    304         if (config->stencilBits > 0)
    305             score += 2;
    306         if (config->alphaBits > 0)
    307             score++;
    308 
    309         if (score > best_score) {
    310             best = config;
    311             best_score = score;
    312         }
    313     }
    314 
    315     return best;
    316 }
    317 
    318 void
    319 __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
    320 {
    321     __GLXconfig *m;
    322     __GLXconfig *config;
    323     int i;
    324 
    325     if (!dixRegisterPrivateKey(&glxScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
    326         return;
    327 
    328     pGlxScreen->pScreen = pScreen;
    329     pGlxScreen->GLextensions = strdup(GLServerExtensions);
    330     pGlxScreen->GLXextensions = NULL;
    331 
    332     pGlxScreen->CloseScreen = pScreen->CloseScreen;
    333     pScreen->CloseScreen = glxCloseScreen;
    334 
    335     i = 0;
    336     for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
    337         m->fbconfigID = FakeClientID(0);
    338         m->visualID = 0;
    339         i++;
    340     }
    341     pGlxScreen->numFBConfigs = i;
    342 
    343     pGlxScreen->visuals =
    344         calloc(pGlxScreen->numFBConfigs, sizeof(__GLXconfig *));
    345 
    346     /* First, try to choose featureful FBconfigs for the existing X visuals.
    347      * Note that if multiple X visuals end up with the same FBconfig being
    348      * chosen, the later X visuals don't get GLX visuals (because we want to
    349      * prioritize the root visual being GLX).
    350      */
    351     for (i = 0; i < pScreen->numVisuals; i++) {
    352         VisualPtr visual = &pScreen->visuals[i];
    353 
    354         config = pickFBConfig(pGlxScreen, visual);
    355         if (config) {
    356             pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
    357             config->visualID = visual->vid;
    358 #ifdef COMPOSITE
    359             if (!noCompositeExtension) {
    360                 if (compIsAlternateVisual(pScreen, visual->vid))
    361                     config->visualSelectGroup++;
    362             }
    363 #endif
    364         }
    365     }
    366 
    367     /* Then, add new visuals corresponding to all FBconfigs that didn't have
    368      * an existing, appropriate visual.
    369      */
    370     for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
    371         int depth;
    372 
    373         VisualPtr visual;
    374 
    375         if (config->visualID != 0)
    376             continue;
    377 
    378         /* Only count RGB bits and not alpha, as we're not trying to create
    379          * visuals for compositing (that's what the 32-bit composite visual
    380          * set up above is for.
    381          */
    382         depth = config->redBits + config->greenBits + config->blueBits;
    383 #ifdef COMPOSITE
    384         if (!noCompositeExtension) {
    385             if (config->duplicatedForComp) {
    386                     depth += config->alphaBits;
    387                     config->visualSelectGroup++;
    388             }
    389         }
    390 #endif
    391         /* Make sure that our FBconfig's depth can actually be displayed
    392          * (corresponds to an existing visual).
    393          */
    394         for (i = 0; i < pScreen->numVisuals; i++) {
    395             if (depth == pScreen->visuals[i].nplanes)
    396                 break;
    397         }
    398         /* if it can't, fix up the fbconfig to not advertise window support */
    399         if (i == pScreen->numVisuals)
    400             config->drawableType &= ~(GLX_WINDOW_BIT);
    401 
    402         /* fbconfig must support window drawables */
    403         if (!(config->drawableType & GLX_WINDOW_BIT)) {
    404             config->visualID = 0;
    405             continue;
    406         }
    407 
    408         /* Create a new X visual for our FBconfig. */
    409         visual = AddScreenVisuals(pScreen, 1, depth);
    410         if (visual == NULL)
    411             continue;
    412 
    413 #ifdef COMPOSITE
    414         if (!noCompositeExtension) {
    415             if (config->duplicatedForComp)
    416                 (void) CompositeRegisterAlternateVisuals(pScreen, &visual->vid, 1);
    417         }
    418 #endif
    419         pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
    420         initGlxVisual(visual, config);
    421     }
    422 
    423     dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
    424 
    425     if (pGlxScreen->glvnd)
    426         __glXEnableExtension(pGlxScreen->glx_enable_bits, "GLX_EXT_libglvnd");
    427 
    428     i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL);
    429     if (i > 0) {
    430         pGlxScreen->GLXextensions = xnfalloc(i);
    431         (void) __glXGetExtensionString(pGlxScreen->glx_enable_bits,
    432                                        pGlxScreen->GLXextensions);
    433     }
    434 
    435 }
    436 
    437 void
    438 __glXScreenDestroy(__GLXscreen * screen)
    439 {
    440     __GLXconfig *config, *next;
    441 
    442     free(screen->glvnd);
    443     free(screen->GLXextensions);
    444     free(screen->GLextensions);
    445     free(screen->visuals);
    446 
    447     for (config = screen->fbconfigs; config != NULL; config = next) {
    448         next = config->next;
    449         free(config);
    450     }
    451 }