Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * (C) Copyright IBM Corporation 2002, 2004
  3.  * 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.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  9.  * license, and/or sell copies of the Software, and to permit persons to whom
  10.  * the Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /**
  26.  * \file glxextensions.c
  27.  *
  28.  * \author Ian Romanick <idr@us.ibm.com>
  29.  */
  30.  
  31. #include "glxclient.h"
  32. #include <X11/extensions/extutil.h>
  33. #include <X11/extensions/Xext.h>
  34. #include <string.h>
  35. #include "glxextensions.h"
  36.  
  37.  
  38. #define SET_BIT(m,b)   (m[ (b) / 8 ] |=  (1U << ((b) % 8)))
  39. #define CLR_BIT(m,b)   (m[ (b) / 8 ] &= ~(1U << ((b) % 8)))
  40. #define IS_SET(m,b)    ((m[ (b) / 8 ] & (1U << ((b) % 8))) != 0)
  41. #define CONCAT(a,b) a ## b
  42. #define GLX(n) "GLX_" # n, 4 + sizeof( # n ) - 1, CONCAT(n,_bit)
  43. #define GL(n)  "GL_" # n,  3 + sizeof( # n ) - 1, GL_ ## n ## _bit
  44. #define VER(a,b)  a, b
  45. #define Y  1
  46. #define N  0
  47. #define EXT_ENABLED(bit,supported) (IS_SET( supported, bit ))
  48.  
  49.  
  50. struct extension_info
  51. {
  52.    const char *const name;
  53.    unsigned name_len;
  54.  
  55.    unsigned char bit;
  56.  
  57.    /* This is the lowest version of GLX that "requires" this extension.
  58.     * For example, GLX 1.3 requires SGIX_fbconfig, SGIX_pbuffer, and
  59.     * SGI_make_current_read.  If the extension is not required by any known
  60.     * version of GLX, use 0, 0.
  61.     */
  62.    unsigned char version_major;
  63.    unsigned char version_minor;
  64.  
  65.    /**
  66.     * The client (i.e., libGL) supports this extension.
  67.     *
  68.     * Except during bring up, all extensions should have this set to Y.  There
  69.     * are a few cases of extensions that have partial (or speculative)
  70.     * support, but these are rare.  There also shouldn't be any new ones
  71.     * added.
  72.     *
  73.     * Generally, extensions require server support and ::client_support to be
  74.     * enabled.  If the display is capable of direct rendering,
  75.     * ::direct_support is also required.
  76.     *
  77.     * \sa ::client_only
  78.     */
  79.    unsigned char client_support;
  80.  
  81.    /**
  82.     * The direct-renderer (e.g., i965_dri.so) supports this extension.
  83.     *
  84.     * For cases where all of the infrastructure to support the extension is a
  85.     * required part of the loader/driver interface, this can default to Y.
  86.     * For most cases, extended functionality, usually in the form of DRI2
  87.     * extensions, is necessary to support the extension.  The loader will set
  88.     * the flag true if all the requirements are met.
  89.     *
  90.     * If the display is capable of direct rendering, ::direct_support is
  91.     * required for the extension to be enabled.
  92.     */
  93.    unsigned char direct_support;
  94.  
  95.    /**
  96.     * The extension depends only on client support.
  97.     *
  98.     * This is for extensions like GLX_ARB_get_proc_address that are contained
  99.     * entirely in the client library.  There is no dependency on the server or
  100.     * the direct-renderer.
  101.     *
  102.     * These extensions will be enabled if ::client_support is set.
  103.     *
  104.     * \note
  105.     * An extension \b cannot be both client-only and direct-only because being
  106.     * direct-only implies a dependency on the direct renderer.
  107.     *
  108.     * \sa ::client_support, ::direct_only
  109.     */
  110.    unsigned char client_only;
  111.  
  112.    /**
  113.     * The extension only functions with direct-rendering contexts
  114.     *
  115.     * The extension has no GLX protocol, and, therefore, no explicit
  116.     * dependency on the server.  The functionality is contained entirely in
  117.     * the client library and the direct renderer.  A few of the swap-related
  118.     * extensions are intended to behave this way.
  119.     *
  120.     * These extensions will be enabled if both ::client_support and
  121.     * ::direct_support are set.
  122.     *
  123.     * \note
  124.     * An extension \b cannot be both client-only and direct-only because being
  125.     * client-only implies that all functionality is outside the
  126.     * direct-renderer.
  127.     *
  128.     * \sa ::direct_support, ::client_only
  129.     */
  130.    unsigned char direct_only;
  131. };
  132.  
  133. /* *INDENT-OFF* */
  134. static const struct extension_info known_glx_extensions[] = {
  135.    { GLX(ARB_create_context),          VER(0,0), Y, N, N, N },
  136.    { GLX(ARB_create_context_profile),  VER(0,0), Y, N, N, N },
  137.    { GLX(ARB_create_context_robustness), VER(0,0), Y, N, N, N },
  138.    { GLX(ARB_fbconfig_float),          VER(0,0), Y, Y, N, N },
  139.    { GLX(ARB_framebuffer_sRGB),        VER(0,0), Y, Y, N, N },
  140.    { GLX(ARB_get_proc_address),        VER(1,4), Y, N, Y, N },
  141.    { GLX(ARB_multisample),             VER(1,4), Y, Y, N, N },
  142.    { GLX(ATI_pixel_format_float),      VER(0,0), N, N, N, N },
  143.    { GLX(EXT_import_context),          VER(0,0), Y, Y, N, N },
  144.    { GLX(EXT_visual_info),             VER(0,0), Y, Y, N, N },
  145.    { GLX(EXT_visual_rating),           VER(0,0), Y, Y, N, N },
  146.    { GLX(EXT_fbconfig_packed_float),   VER(0,0), Y, Y, N, N },
  147.    { GLX(EXT_framebuffer_sRGB),        VER(0,0), Y, Y, N, N },
  148.    { GLX(EXT_create_context_es2_profile), VER(0,0), Y, N, N, N },
  149.    { GLX(MESA_copy_sub_buffer),        VER(0,0), Y, N, N, N },
  150.    { GLX(MESA_multithread_makecurrent),VER(0,0), Y, N, Y, N },
  151.    { GLX(MESA_query_renderer),         VER(0,0), Y, N, N, Y },
  152.    { GLX(MESA_swap_control),           VER(0,0), Y, N, N, Y },
  153.    { GLX(NV_float_buffer),             VER(0,0), N, N, N, N },
  154.    { GLX(OML_swap_method),             VER(0,0), Y, Y, N, N },
  155.    { GLX(OML_sync_control),            VER(0,0), Y, N, N, Y },
  156.    { GLX(SGI_make_current_read),       VER(1,3), Y, N, N, N },
  157.    { GLX(SGI_swap_control),            VER(0,0), Y, N, N, N },
  158.    { GLX(SGI_video_sync),              VER(0,0), Y, N, N, Y },
  159.    { GLX(SGIS_multisample),            VER(0,0), Y, Y, N, N },
  160.    { GLX(SGIX_fbconfig),               VER(1,3), Y, Y, N, N },
  161.    { GLX(SGIX_pbuffer),                VER(1,3), Y, Y, N, N },
  162.    { GLX(SGIX_swap_barrier),           VER(0,0), N, N, N, N },
  163.    { GLX(SGIX_swap_group),             VER(0,0), N, N, N, N },
  164.    { GLX(SGIX_visual_select_group),    VER(0,0), Y, Y, N, N },
  165.    { GLX(EXT_texture_from_pixmap),     VER(0,0), Y, N, N, N },
  166.    { GLX(INTEL_swap_event),            VER(0,0), Y, N, N, N },
  167.    { GLX(EXT_buffer_age),              VER(0,0), Y, N, N, Y },
  168.    { NULL }
  169. };
  170.  
  171. static const struct extension_info known_gl_extensions[] = {
  172.    { GL(ARB_depth_texture),              VER(1,4), Y, N, N, N },
  173.    { GL(ARB_draw_buffers),               VER(0,0), Y, N, N, N },
  174.    { GL(ARB_fragment_program),           VER(0,0), Y, N, N, N },
  175.    { GL(ARB_fragment_program_shadow),    VER(0,0), Y, N, N, N },
  176.    { GL(ARB_framebuffer_object),         VER(0,0), Y, N, N, N },
  177.    { GL(ARB_imaging),                    VER(0,0), Y, N, N, N },
  178.    { GL(ARB_multisample),                VER(1,3), Y, N, N, N },
  179.    { GL(ARB_multitexture),               VER(1,3), Y, N, N, N },
  180.    { GL(ARB_occlusion_query),            VER(1,5), Y, N, N, N },
  181.    { GL(ARB_point_parameters),           VER(1,4), Y, N, N, N },
  182.    { GL(ARB_point_sprite),               VER(0,0), Y, N, N, N },
  183.    { GL(ARB_shadow),                     VER(1,4), Y, N, N, N },
  184.    { GL(ARB_shadow_ambient),             VER(0,0), Y, N, N, N },
  185.    { GL(ARB_texture_border_clamp),       VER(1,3), Y, N, N, N },
  186.    { GL(ARB_texture_compression),        VER(1,3), Y, N, N, N },
  187.    { GL(ARB_texture_cube_map),           VER(1,3), Y, N, N, N },
  188.    { GL(ARB_texture_env_add),            VER(1,3), Y, N, N, N },
  189.    { GL(ARB_texture_env_combine),        VER(1,3), Y, N, N, N },
  190.    { GL(ARB_texture_env_crossbar),       VER(1,4), Y, N, N, N },
  191.    { GL(ARB_texture_env_dot3),           VER(1,3), Y, N, N, N },
  192.    { GL(ARB_texture_mirrored_repeat),    VER(1,4), Y, N, N, N },
  193.    { GL(ARB_texture_non_power_of_two),   VER(1,5), Y, N, N, N },
  194.    { GL(ARB_texture_rectangle),          VER(0,0), Y, N, N, N },
  195.    { GL(ARB_texture_rg),                 VER(0,0), Y, N, N, N },
  196.    { GL(ARB_transpose_matrix),           VER(1,3), Y, N, Y, N },
  197.    { GL(ARB_vertex_buffer_object),       VER(1,5), N, N, N, N },
  198.    { GL(ARB_vertex_program),             VER(0,0), Y, N, N, N },
  199.    { GL(ARB_window_pos),                 VER(1,4), Y, N, N, N },
  200.    { GL(EXT_abgr),                       VER(0,0), Y, N, N, N },
  201.    { GL(EXT_bgra),                       VER(1,2), Y, N, N, N },
  202.    { GL(EXT_blend_color),                VER(1,4), Y, N, N, N },
  203.    { GL(EXT_blend_equation_separate),    VER(0,0), Y, N, N, N },
  204.    { GL(EXT_blend_func_separate),        VER(1,4), Y, N, N, N },
  205.    { GL(EXT_blend_logic_op),             VER(1,4), Y, N, N, N },
  206.    { GL(EXT_blend_minmax),               VER(1,4), Y, N, N, N },
  207.    { GL(EXT_blend_subtract),             VER(1,4), Y, N, N, N },
  208.    { GL(EXT_clip_volume_hint),           VER(0,0), Y, N, N, N },
  209.    { GL(EXT_compiled_vertex_array),      VER(0,0), N, N, N, N },
  210.    { GL(EXT_convolution),                VER(0,0), N, N, N, N },
  211.    { GL(EXT_copy_texture),               VER(1,1), Y, N, N, N },
  212.    { GL(EXT_cull_vertex),                VER(0,0), N, N, N, N },
  213.    { GL(EXT_depth_bounds_test),          VER(0,0), N, N, N, N },
  214.    { GL(EXT_draw_range_elements),        VER(1,2), Y, N, Y, N },
  215.    { GL(EXT_fog_coord),                  VER(1,4), Y, N, N, N },
  216.    { GL(EXT_framebuffer_blit),           VER(0,0), Y, N, N, N },
  217.    { GL(EXT_framebuffer_multisample),    VER(0,0), Y, N, N, N },
  218.    { GL(EXT_framebuffer_object),         VER(0,0), Y, N, N, N },
  219.    { GL(EXT_framebuffer_sRGB),           VER(0,0), Y, N, N, N },
  220.    { GL(EXT_multi_draw_arrays),          VER(1,4), Y, N, Y, N },
  221.    { GL(EXT_packed_depth_stencil),       VER(0,0), Y, N, N, N },
  222.    { GL(EXT_packed_pixels),              VER(1,2), Y, N, N, N },
  223.    { GL(EXT_paletted_texture),           VER(0,0), Y, N, N, N },
  224.    { GL(EXT_pixel_buffer_object),        VER(0,0), N, N, N, N },
  225.    { GL(EXT_point_parameters),           VER(1,4), Y, N, N, N },
  226.    { GL(EXT_polygon_offset),             VER(1,1), Y, N, N, N },
  227.    { GL(EXT_rescale_normal),             VER(1,2), Y, N, N, N },
  228.    { GL(EXT_secondary_color),            VER(1,4), Y, N, N, N },
  229.    { GL(EXT_separate_specular_color),    VER(1,2), Y, N, N, N },
  230.    { GL(EXT_shadow_funcs),               VER(1,5), Y, N, N, N },
  231.    { GL(EXT_shared_texture_palette),     VER(0,0), Y, N, N, N },
  232.    { GL(EXT_stencil_two_side),           VER(0,0), Y, N, N, N },
  233.    { GL(EXT_stencil_wrap),               VER(1,4), Y, N, N, N },
  234.    { GL(EXT_subtexture),                 VER(1,1), Y, N, N, N },
  235.    { GL(EXT_texture),                    VER(1,1), Y, N, N, N },
  236.    { GL(EXT_texture3D),                  VER(1,2), Y, N, N, N },
  237.    { GL(EXT_texture_compression_dxt1),   VER(0,0), Y, N, N, N },
  238.    { GL(EXT_texture_compression_s3tc),   VER(0,0), Y, N, N, N },
  239.    { GL(EXT_texture_edge_clamp),         VER(1,2), Y, N, N, N },
  240.    { GL(EXT_texture_env_add),            VER(1,3), Y, N, N, N },
  241.    { GL(EXT_texture_env_combine),        VER(1,3), Y, N, N, N },
  242.    { GL(EXT_texture_env_dot3),           VER(0,0), Y, N, N, N },
  243.    { GL(EXT_texture_filter_anisotropic), VER(0,0), Y, N, N, N },
  244.    { GL(EXT_texture_lod),                VER(1,2), Y, N, N, N },
  245.    { GL(EXT_texture_lod_bias),           VER(1,4), Y, N, N, N },
  246.    { GL(EXT_texture_mirror_clamp),       VER(0,0), Y, N, N, N },
  247.    { GL(EXT_texture_object),             VER(1,1), Y, N, N, N },
  248.    { GL(EXT_texture_rectangle),          VER(0,0), Y, N, N, N },
  249.    { GL(EXT_vertex_array),               VER(0,0), Y, N, N, N },
  250.    { GL(3DFX_texture_compression_FXT1),  VER(0,0), Y, N, N, N },
  251.    { GL(APPLE_packed_pixels),            VER(1,2), Y, N, N, N },
  252.    { GL(APPLE_ycbcr_422),                VER(0,0), Y, N, N, N },
  253.    { GL(ATI_draw_buffers),               VER(0,0), Y, N, N, N },
  254.    { GL(ATI_text_fragment_shader),       VER(0,0), Y, N, N, N },
  255.    { GL(ATI_texture_env_combine3),       VER(0,0), Y, N, N, N },
  256.    { GL(ATI_texture_float),              VER(0,0), Y, N, N, N },
  257.    { GL(ATI_texture_mirror_once),        VER(0,0), Y, N, N, N },
  258.    { GL(ATIX_texture_env_combine3),      VER(0,0), Y, N, N, N },
  259.    { GL(HP_convolution_border_modes),    VER(0,0), Y, N, N, N },
  260.    { GL(HP_occlusion_test),              VER(0,0), Y, N, N, N },
  261.    { GL(IBM_cull_vertex),                VER(0,0), Y, N, N, N },
  262.    { GL(IBM_pixel_filter_hint),          VER(0,0), Y, N, N, N },
  263.    { GL(IBM_rasterpos_clip),             VER(0,0), Y, N, N, N },
  264.    { GL(IBM_texture_clamp_nodraw),       VER(0,0), Y, N, N, N },
  265.    { GL(IBM_texture_mirrored_repeat),    VER(0,0), Y, N, N, N },
  266.    { GL(INGR_blend_func_separate),       VER(0,0), Y, N, N, N },
  267.    { GL(INGR_interlace_read),            VER(0,0), Y, N, N, N },
  268.    { GL(MESA_pack_invert),               VER(0,0), Y, N, N, N },
  269.    { GL(MESA_ycbcr_texture),             VER(0,0), Y, N, N, N },
  270.    { GL(NV_blend_square),                VER(1,4), Y, N, N, N },
  271.    { GL(NV_copy_depth_to_color),         VER(0,0), Y, N, N, N },
  272.    { GL(NV_depth_clamp),                 VER(0,0), Y, N, N, N },
  273.    { GL(NV_fog_distance),                VER(0,0), Y, N, N, N },
  274.    { GL(NV_fragment_program),            VER(0,0), Y, N, N, N },
  275.    { GL(NV_fragment_program_option),     VER(0,0), Y, N, N, N },
  276.    { GL(NV_fragment_program2),           VER(0,0), Y, N, N, N },
  277.    { GL(NV_light_max_exponent),          VER(0,0), Y, N, N, N },
  278.    { GL(NV_multisample_filter_hint),     VER(0,0), Y, N, N, N },
  279.    { GL(NV_packed_depth_stencil),        VER(0,0), Y, N, N, N },
  280.    { GL(NV_point_sprite),                VER(0,0), Y, N, N, N },
  281.    { GL(NV_texgen_reflection),           VER(0,0), Y, N, N, N },
  282.    { GL(NV_texture_compression_vtc),     VER(0,0), Y, N, N, N },
  283.    { GL(NV_texture_env_combine4),        VER(0,0), Y, N, N, N },
  284.    { GL(NV_texture_rectangle),           VER(0,0), Y, N, N, N },
  285.    { GL(NV_vertex_program),              VER(0,0), Y, N, N, N },
  286.    { GL(NV_vertex_program1_1),           VER(0,0), Y, N, N, N },
  287.    { GL(NV_vertex_program2),             VER(0,0), Y, N, N, N },
  288.    { GL(NV_vertex_program2_option),      VER(0,0), Y, N, N, N },
  289.    { GL(NV_vertex_program3),             VER(0,0), Y, N, N, N },
  290.    { GL(OES_read_format),                VER(0,0), Y, N, N, N },
  291.    { GL(OES_compressed_paletted_texture),VER(0,0), Y, N, N, N },
  292.    { GL(SGI_color_matrix),               VER(0,0), Y, N, N, N },
  293.    { GL(SGI_color_table),                VER(0,0), Y, N, N, N },
  294.    { GL(SGI_texture_color_table),        VER(0,0), Y, N, N, N },
  295.    { GL(SGIS_generate_mipmap),           VER(1,4), Y, N, N, N },
  296.    { GL(SGIS_multisample),               VER(0,0), Y, N, N, N },
  297.    { GL(SGIS_texture_border_clamp),      VER(1,3), Y, N, N, N },
  298.    { GL(SGIS_texture_edge_clamp),        VER(1,2), Y, N, N, N },
  299.    { GL(SGIS_texture_lod),               VER(1,2), Y, N, N, N },
  300.    { GL(SGIX_blend_alpha_minmax),        VER(0,0), Y, N, N, N },
  301.    { GL(SGIX_clipmap),                   VER(0,0), Y, N, N, N },
  302.    { GL(SGIX_depth_texture),             VER(0,0), Y, N, N, N },
  303.    { GL(SGIX_fog_offset),                VER(0,0), Y, N, N, N },
  304.    { GL(SGIX_shadow),                    VER(0,0), Y, N, N, N },
  305.    { GL(SGIX_shadow_ambient),            VER(0,0), Y, N, N, N },
  306.    { GL(SGIX_texture_coordinate_clamp),  VER(0,0), Y, N, N, N },
  307.    { GL(SGIX_texture_lod_bias),          VER(0,0), Y, N, N, N },
  308.    { GL(SGIX_texture_range),             VER(0,0), Y, N, N, N },
  309.    { GL(SGIX_texture_scale_bias),        VER(0,0), Y, N, N, N },
  310.    { GL(SGIX_vertex_preclip),            VER(0,0), Y, N, N, N },
  311.    { GL(SGIX_vertex_preclip_hint),       VER(0,0), Y, N, N, N },
  312.    { GL(SGIX_ycrcb),                     VER(0,0), Y, N, N, N },
  313.    { GL(SUN_convolution_border_modes),   VER(0,0), Y, N, N, N },
  314.    { GL(SUN_multi_draw_arrays),          VER(0,0), Y, N, Y, N },
  315.    { GL(SUN_slice_accum),                VER(0,0), Y, N, N, N },
  316.    { NULL }
  317. };
  318. /* *INDENT-ON* */
  319.  
  320.  
  321. /* global bit-fields of available extensions and their characteristics */
  322. static unsigned char client_glx_support[8];
  323. static unsigned char client_glx_only[8];
  324. static unsigned char direct_glx_only[8];
  325. static unsigned char client_gl_support[__GL_EXT_BYTES];
  326. static unsigned char client_gl_only[__GL_EXT_BYTES];
  327.  
  328. /**
  329.  * Bits representing the set of extensions that are enabled by default in all
  330.  * direct rendering drivers.
  331.  */
  332. static unsigned char direct_glx_support[8];
  333.  
  334. /**
  335.  * Highest core GL version that can be supported for indirect rendering.
  336.  */
  337. static const unsigned gl_major = 1;
  338. static const unsigned gl_minor = 4;
  339.  
  340. /* client extensions string */
  341. static const char *__glXGLXClientExtensions = NULL;
  342.  
  343. static void __glXExtensionsCtr(void);
  344. static void __glXExtensionsCtrScreen(struct glx_screen * psc);
  345. static void __glXProcessServerString(const struct extension_info *ext,
  346.                                      const char *server_string,
  347.                                      unsigned char *server_support);
  348.  
  349. /**
  350.  * Set the state of a GLX extension.
  351.  *
  352.  * \param name      Name of the extension.
  353.  * \param name_len  Length, in characters, of the extension name.
  354.  * \param state     New state (either enabled or disabled) of the extension.
  355.  * \param supported Table in which the state of the extension is to be set.
  356.  */
  357. static void
  358. set_glx_extension(const struct extension_info *ext,
  359.                   const char *name, unsigned name_len, GLboolean state,
  360.                   unsigned char *supported)
  361. {
  362.    unsigned i;
  363.  
  364.  
  365.    for (i = 0; ext[i].name != NULL; i++) {
  366.       if ((name_len == ext[i].name_len)
  367.           && (strncmp(ext[i].name, name, name_len) == 0)) {
  368.          if (state) {
  369.             SET_BIT(supported, ext[i].bit);
  370.          }
  371.          else {
  372.             CLR_BIT(supported, ext[i].bit);
  373.          }
  374.  
  375.          return;
  376.       }
  377.    }
  378. }
  379.  
  380.  
  381. #define NUL '\0'
  382. #define SEPARATOR ' '
  383.  
  384. /**
  385.  * Convert the server's extension string to a bit-field.
  386.  *
  387.  * \param server_string   GLX extension string from the server.
  388.  * \param server_support  Bit-field of supported extensions.
  389.  *
  390.  * \note
  391.  * This function is used to process both GLX and GL extension strings.  The
  392.  * bit-fields used to track each of these have different sizes.  Therefore,
  393.  * the data pointed by \c server_support must be preinitialized to zero.
  394.  */
  395. static void
  396. __glXProcessServerString(const struct extension_info *ext,
  397.                          const char *server_string,
  398.                          unsigned char *server_support)
  399. {
  400.    unsigned base;
  401.    unsigned len;
  402.  
  403.    for (base = 0; server_string[base] != NUL; /* empty */ ) {
  404.       /* Determine the length of the next extension name.
  405.        */
  406.       for (len = 0; (server_string[base + len] != SEPARATOR)
  407.            && (server_string[base + len] != NUL); len++) {
  408.          /* empty */
  409.       }
  410.  
  411.       /* Set the bit for the extension in the server_support table.
  412.        */
  413.       set_glx_extension(ext, &server_string[base], len, GL_TRUE,
  414.                         server_support);
  415.  
  416.  
  417.       /* Advance to the next extension string.  This means that we skip
  418.        * over the previous string and any trialing white-space.
  419.        */
  420.       for (base += len; (server_string[base] == SEPARATOR)
  421.            && (server_string[base] != NUL); base++) {
  422.          /* empty */
  423.       }
  424.    }
  425. }
  426.  
  427. void
  428. __glXEnableDirectExtension(struct glx_screen * psc, const char *name)
  429. {
  430.    __glXExtensionsCtr();
  431.    __glXExtensionsCtrScreen(psc);
  432.  
  433.    set_glx_extension(known_glx_extensions,
  434.                      name, strlen(name), GL_TRUE, psc->direct_support);
  435. }
  436.  
  437. /**
  438.  * Initialize global extension support tables.
  439.  */
  440.  
  441. static void
  442. __glXExtensionsCtr(void)
  443. {
  444.    unsigned i;
  445.    static GLboolean ext_list_first_time = GL_TRUE;
  446.  
  447.  
  448.    if (ext_list_first_time) {
  449.       ext_list_first_time = GL_FALSE;
  450.  
  451.       (void) memset(client_glx_support, 0, sizeof(client_glx_support));
  452.       (void) memset(direct_glx_support, 0, sizeof(direct_glx_support));
  453.       (void) memset(client_glx_only, 0, sizeof(client_glx_only));
  454.       (void) memset(direct_glx_only, 0, sizeof(direct_glx_only));
  455.  
  456.       (void) memset(client_gl_support, 0, sizeof(client_gl_support));
  457.       (void) memset(client_gl_only, 0, sizeof(client_gl_only));
  458.  
  459.       for (i = 0; known_glx_extensions[i].name != NULL; i++) {
  460.          const unsigned bit = known_glx_extensions[i].bit;
  461.  
  462.          if (known_glx_extensions[i].client_support) {
  463.             SET_BIT(client_glx_support, bit);
  464.          }
  465.  
  466.          if (known_glx_extensions[i].direct_support) {
  467.             SET_BIT(direct_glx_support, bit);
  468.          }
  469.  
  470.          if (known_glx_extensions[i].client_only) {
  471.             SET_BIT(client_glx_only, bit);
  472.          }
  473.  
  474.          if (known_glx_extensions[i].direct_only) {
  475.             SET_BIT(direct_glx_only, bit);
  476.          }
  477.       }
  478.  
  479.       for (i = 0; known_gl_extensions[i].name != NULL; i++) {
  480.          const unsigned bit = known_gl_extensions[i].bit;
  481.  
  482.          if (known_gl_extensions[i].client_support) {
  483.             SET_BIT(client_gl_support, bit);
  484.          }
  485.  
  486.          if (known_gl_extensions[i].client_only) {
  487.             SET_BIT(client_gl_only, bit);
  488.          }
  489.       }
  490.  
  491. #if 0
  492.       fprintf(stderr, "[%s:%u] Maximum client library version: %u.%u\n",
  493.               __func__, __LINE__, gl_major, gl_minor);
  494. #endif
  495.    }
  496. }
  497.  
  498.  
  499. /**
  500.  * Make sure that per-screen direct-support table is initialized.
  501.  *
  502.  * \param psc  Pointer to GLX per-screen record.
  503.  */
  504.  
  505. static void
  506. __glXExtensionsCtrScreen(struct glx_screen * psc)
  507. {
  508.    if (psc->ext_list_first_time) {
  509.       psc->ext_list_first_time = GL_FALSE;
  510.       (void) memcpy(psc->direct_support, direct_glx_support,
  511.                     sizeof(direct_glx_support));
  512.    }
  513. }
  514.  
  515.  
  516. /**
  517.  * Check if a certain extension is enabled on a given screen.
  518.  *
  519.  * \param psc  Pointer to GLX per-screen record.
  520.  * \param bit  Bit index in the direct-support table.
  521.  * \returns If the extension bit is enabled for the screen, \c GL_TRUE is
  522.  *          returned.  If the extension bit is not enabled or if \c psc is
  523.  *          \c NULL, then \c GL_FALSE is returned.
  524.  */
  525. GLboolean
  526. __glXExtensionBitIsEnabled(struct glx_screen * psc, unsigned bit)
  527. {
  528.    GLboolean enabled = GL_FALSE;
  529.  
  530.    if (psc != NULL) {
  531.       __glXExtensionsCtr();
  532.       __glXExtensionsCtrScreen(psc);
  533.       enabled = EXT_ENABLED(bit, psc->direct_support);
  534.    }
  535.  
  536.    return enabled;
  537. }
  538.  
  539.  
  540. /**
  541.  * Check if a certain extension is enabled in a given context.
  542.  *
  543.  */
  544. GLboolean
  545. __glExtensionBitIsEnabled(struct glx_context *gc, unsigned bit)
  546. {
  547.    GLboolean enabled = GL_FALSE;
  548.  
  549.    if (gc != NULL) {
  550.       enabled = EXT_ENABLED(bit, gc->gl_extension_bits);
  551.    }
  552.  
  553.    return enabled;
  554. }
  555.  
  556.  
  557.  
  558. /**
  559.  * Convert a bit-field to a string of supported extensions.
  560.  */
  561. static char *
  562. __glXGetStringFromTable(const struct extension_info *ext,
  563.                         const unsigned char *supported)
  564. {
  565.    unsigned i;
  566.    unsigned ext_str_len;
  567.    char *ext_str;
  568.    char *point;
  569.  
  570.  
  571.    ext_str_len = 0;
  572.    for (i = 0; ext[i].name != NULL; i++) {
  573.       if (EXT_ENABLED(ext[i].bit, supported)) {
  574.          ext_str_len += ext[i].name_len + 1;
  575.       }
  576.    }
  577.  
  578.    ext_str = malloc(ext_str_len + 1);
  579.    if (ext_str != NULL) {
  580.       point = ext_str;
  581.  
  582.       for (i = 0; ext[i].name != NULL; i++) {
  583.          if (EXT_ENABLED(ext[i].bit, supported)) {
  584.             (void) memcpy(point, ext[i].name, ext[i].name_len);
  585.             point += ext[i].name_len;
  586.  
  587.             *point = ' ';
  588.             point++;
  589.          }
  590.       }
  591.  
  592.       *point = '\0';
  593.    }
  594.  
  595.    return ext_str;
  596. }
  597.  
  598.  
  599. /**
  600.  * Get the string of client library supported extensions.
  601.  */
  602. const char *
  603. __glXGetClientExtensions(void)
  604. {
  605.    if (__glXGLXClientExtensions == NULL) {
  606.       __glXExtensionsCtr();
  607.       __glXGLXClientExtensions = __glXGetStringFromTable(known_glx_extensions,
  608.                                                          client_glx_support);
  609.    }
  610.  
  611.    return __glXGLXClientExtensions;
  612. }
  613.  
  614.  
  615. /**
  616.  * Calculate the list of application usable extensions.  The resulting
  617.  * string is stored in \c psc->effectiveGLXexts.
  618.  *
  619.  * \param psc                        Pointer to GLX per-screen record.
  620.  * \param display_is_direct_capable  True if the display is capable of
  621.  *                                   direct rendering.
  622.  * \param minor_version              GLX minor version from the server.
  623.  */
  624.  
  625. void
  626. __glXCalculateUsableExtensions(struct glx_screen * psc,
  627.                                GLboolean display_is_direct_capable,
  628.                                int minor_version)
  629. {
  630.    unsigned char server_support[8];
  631.    unsigned char usable[8];
  632.    unsigned i;
  633.  
  634.    __glXExtensionsCtr();
  635.    __glXExtensionsCtrScreen(psc);
  636.  
  637.    (void) memset(server_support, 0, sizeof(server_support));
  638.    __glXProcessServerString(known_glx_extensions,
  639.                             psc->serverGLXexts, server_support);
  640.  
  641.  
  642.    /* This is a hack.  Some servers support GLX 1.3 but don't export
  643.     * all of the extensions implied by GLX 1.3.  If the server claims
  644.     * support for GLX 1.3, enable support for the extensions that can be
  645.     * "emulated" as well.
  646.     */
  647. #ifndef GLX_USE_APPLEGL
  648.    if (minor_version >= 3) {
  649.       SET_BIT(server_support, EXT_visual_info_bit);
  650.       SET_BIT(server_support, EXT_visual_rating_bit);
  651.       SET_BIT(server_support, SGI_make_current_read_bit);
  652.       SET_BIT(server_support, SGIX_fbconfig_bit);
  653.       SET_BIT(server_support, SGIX_pbuffer_bit);
  654.  
  655.       /* This one is a little iffy.  GLX 1.3 doesn't incorporate all of this
  656.        * extension.  However, the only part that is not strictly client-side
  657.        * is shared.  That's the glXQueryContext / glXQueryContextInfoEXT
  658.        * function.
  659.        */
  660.  
  661.       SET_BIT(server_support, EXT_import_context_bit);
  662.    }
  663. #endif
  664.  
  665.    /* An extension is supported if the client-side (i.e., libGL) supports
  666.     * it and the "server" supports it.  In this case that means that either
  667.     * the true server supports it or it is only for direct-rendering and
  668.     * the direct rendering driver supports it.
  669.     *
  670.     * If the display is not capable of direct rendering, then the extension
  671.     * is enabled if and only if the client-side library and the server
  672.     * support it.
  673.     */
  674.  
  675.    if (display_is_direct_capable) {
  676.       for (i = 0; i < 8; i++) {
  677.          usable[i] = (client_glx_support[i] & client_glx_only[i])
  678.             | (client_glx_support[i] & psc->direct_support[i] &
  679.                server_support[i])
  680.             | (client_glx_support[i] & psc->direct_support[i] &
  681.                direct_glx_only[i]);
  682.       }
  683.    }
  684.    else {
  685.       for (i = 0; i < 8; i++) {
  686.          usable[i] = (client_glx_support[i] & client_glx_only[i])
  687.             | (client_glx_support[i] & server_support[i]);
  688.       }
  689.    }
  690.  
  691.    psc->effectiveGLXexts = __glXGetStringFromTable(known_glx_extensions,
  692.                                                    usable);
  693. }
  694.  
  695.  
  696. /**
  697.  * Calculate the list of application usable extensions.  The resulting
  698.  * string is stored in \c gc->extensions.
  699.  *
  700.  * \param gc             Pointer to GLX context.
  701.  * \param server_string  Extension string from the server.
  702.  * \param major_version  GL major version from the server.
  703.  * \param minor_version  GL minor version from the server.
  704.  */
  705.  
  706. void
  707. __glXCalculateUsableGLExtensions(struct glx_context * gc,
  708.                                  const char *server_string,
  709.                                  int major_version, int minor_version)
  710. {
  711.    unsigned char server_support[__GL_EXT_BYTES];
  712.    unsigned char usable[__GL_EXT_BYTES];
  713.    unsigned i;
  714.  
  715.  
  716.    __glXExtensionsCtr();
  717.  
  718.    (void) memset(server_support, 0, sizeof(server_support));
  719.    __glXProcessServerString(known_gl_extensions, server_string,
  720.                             server_support);
  721.  
  722.  
  723.    /* Handle lazy servers that don't export all the extensions strings that
  724.     * are part of the GL core version that they support.
  725.     */
  726.  
  727.    for (i = 0; i < __GL_EXT_BYTES; i++) {
  728.       if ((known_gl_extensions[i].version_major != 0)
  729.           && ((major_version > known_gl_extensions[i].version_major)
  730.               || ((major_version == known_gl_extensions[i].version_major)
  731.                   && (minor_version >=
  732.                       known_gl_extensions[i].version_minor)))) {
  733.          SET_BIT(server_support, known_gl_extensions[i].bit);
  734.       }
  735.    }
  736.  
  737.  
  738.    /* An extension is supported if the client-side (i.e., libGL) supports
  739.     * it and the server supports it or the client-side library supports it
  740.     * and it only needs client-side support.
  741.     */
  742.  
  743.    for (i = 0; i < __GL_EXT_BYTES; i++) {
  744.       usable[i] = (client_gl_support[i] & client_gl_only[i])
  745.          | (client_gl_support[i] & server_support[i]);
  746.    }
  747.  
  748.    gc->extensions = (unsigned char *)
  749.       __glXGetStringFromTable(known_gl_extensions, usable);
  750.    (void) memcpy(gc->gl_extension_bits, usable, sizeof(usable));
  751. }
  752.  
  753.  
  754. /**
  755.  * Calculates the maximum core GL version that can be supported for indirect
  756.  * rendering.
  757.  */
  758. void
  759. __glXGetGLVersion(int *major_version, int *minor_version)
  760. {
  761.    __glXExtensionsCtr();
  762.    *major_version = gl_major;
  763.    *minor_version = gl_minor;
  764. }
  765.  
  766.  
  767. /**
  768.  * Get a string representing the set of extensions supported by the client
  769.  * library.  This is currently only used to send the list of extensions
  770.  * supported by the client to the server.
  771.  */
  772. char *
  773. __glXGetClientGLExtensionString(void)
  774. {
  775.    __glXExtensionsCtr();
  776.    return __glXGetStringFromTable(known_gl_extensions, client_gl_support);
  777. }
  778.