Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the 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 NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25.  
  26. /**
  27.  * \file remap.c
  28.  * Remap table management.
  29.  *
  30.  * Entries in the dispatch table are either static or dynamic.  The
  31.  * dispatch table is shared by mesa core and glapi.  When they are
  32.  * built separately, it is possible that a static entry in mesa core
  33.  * is dynamic, or assigned a different static offset, in glapi.  The
  34.  * remap table is in charge of mapping a static entry in mesa core to
  35.  * a dynamic entry, or the corresponding static entry, in glapi.
  36.  */
  37.  
  38. #include "remap.h"
  39. #include "imports.h"
  40. #include "glapi/glapi.h"
  41.  
  42. #define MAX_ENTRY_POINTS 16
  43.  
  44. #define need_MESA_remap_table
  45. #include "main/remap_helper.h"
  46.  
  47.  
  48. /* this is global for quick access */
  49. int driDispatchRemapTable[driDispatchRemapTable_size];
  50.  
  51.  
  52. /**
  53.  * Return the spec string associated with the given function index.
  54.  * The index is available from including remap_helper.h.
  55.  *
  56.  * \param func_index an opaque function index.
  57.  *
  58.  * \return the spec string associated with the function index, or NULL.
  59.  */
  60. const char *
  61. _mesa_get_function_spec(GLint func_index)
  62. {
  63.    if (func_index < Elements(_mesa_function_pool))
  64.       return _mesa_function_pool + func_index;
  65.    else
  66.       return NULL;
  67. }
  68.  
  69.  
  70. /**
  71.  * Map a function by its spec.  The function will be added to glapi,
  72.  * and the dispatch offset will be returned.
  73.  *
  74.  * \param spec a '\0'-separated string array specifying a function.
  75.  *        It begins with the parameter signature of the function,
  76.  *        followed by the names of the entry points.  An empty entry
  77.  *        point name terminates the array.
  78.  *
  79.  * \return the offset of the (re-)mapped function in the dispatch
  80.  *         table, or -1.
  81.  */
  82. GLint
  83. _mesa_map_function_spec(const char *spec)
  84. {
  85.    const char *signature;
  86.    const char *names[MAX_ENTRY_POINTS + 1];
  87.    GLint num_names = 0;
  88.  
  89.    if (!spec)
  90.       return -1;
  91.  
  92.    signature = spec;
  93.    spec += strlen(spec) + 1;
  94.  
  95.    /* spec is terminated by an empty string */
  96.    while (*spec) {
  97.       names[num_names] = spec;
  98.       num_names++;
  99.       if (num_names >= MAX_ENTRY_POINTS)
  100.          break;
  101.       spec += strlen(spec) + 1;
  102.    }
  103.    if (!num_names)
  104.       return -1;
  105.  
  106.    names[num_names] = NULL;
  107.  
  108.    /* add the entry points to the dispatch table */
  109.    return _glapi_add_dispatch(names, signature);
  110. }
  111.  
  112.  
  113. /**
  114.  * Map an array of functions.  This is a convenient function for
  115.  * use with arrays available from including remap_helper.h.
  116.  *
  117.  * Note that the dispatch offsets of the functions are not returned.
  118.  * If they are needed, _mesa_map_function_spec() should be used.
  119.  *
  120.  * \param func_array an array of function remaps.
  121.  */
  122. void
  123. _mesa_map_function_array(const struct gl_function_remap *func_array)
  124. {
  125.    GLint i;
  126.  
  127.    if (!func_array)
  128.       return;
  129.  
  130.    for (i = 0; func_array[i].func_index != -1; i++) {
  131.       const char *spec;
  132.       GLint offset;
  133.  
  134.       spec = _mesa_get_function_spec(func_array[i].func_index);
  135.       if (!spec) {
  136.          _mesa_problem(NULL, "invalid function index %d",
  137.                        func_array[i].func_index);
  138.          continue;
  139.       }
  140.  
  141.       offset = _mesa_map_function_spec(spec);
  142.       /* error checks */
  143.       if (offset < 0) {
  144.          const char *name = spec + strlen(spec) + 1;
  145.          _mesa_warning(NULL, "failed to remap %s", name);
  146.       }
  147.       else if (func_array[i].dispatch_offset >= 0 &&
  148.                offset != func_array[i].dispatch_offset) {
  149.          const char *name = spec + strlen(spec) + 1;
  150.          _mesa_problem(NULL, "%s should be mapped to %d, not %d",
  151.                        name, func_array[i].dispatch_offset, offset);
  152.       }
  153.    }
  154. }
  155.  
  156.  
  157. /**
  158.  * Map the functions which are already static.
  159.  *
  160.  * When a extension function are incorporated into the ABI, the
  161.  * extension suffix is usually stripped.  Mapping such functions
  162.  * makes sure the alternative names are available.
  163.  *
  164.  * Note that functions mapped by _mesa_init_remap_table() are
  165.  * excluded.
  166.  */
  167. void
  168. _mesa_map_static_functions(void)
  169. {
  170.    /* Remap static functions which have alternative names and are in the ABI.
  171.     * This is to be on the safe side.  glapi should have defined those names.
  172.     */
  173.    _mesa_map_function_array(MESA_alt_functions);
  174. }
  175.  
  176.  
  177. /**
  178.  * Initialize the remap table.  This is called in one_time_init().
  179.  * The remap table needs to be initialized before calling the
  180.  * CALL/GET/SET macros defined in main/dispatch.h.
  181.  */
  182. static void
  183. _mesa_do_init_remap_table(const char *pool,
  184.                           int size,
  185.                           const struct gl_function_pool_remap *remap)
  186. {
  187.    static GLboolean initialized = GL_FALSE;
  188.    GLint i;
  189.  
  190.    if (initialized)
  191.       return;
  192.    initialized = GL_TRUE;
  193.  
  194.    /* initialize the remap table */
  195.    for (i = 0; i < size; i++) {
  196.       GLint offset;
  197.       const char *spec;
  198.  
  199.       /* sanity check */
  200.       ASSERT(i == remap[i].remap_index);
  201.       spec = _mesa_function_pool + remap[i].pool_index;
  202.  
  203.       offset = _mesa_map_function_spec(spec);
  204.       /* store the dispatch offset in the remap table */
  205.       driDispatchRemapTable[i] = offset;
  206.       if (offset < 0) {
  207.          const char *name = spec + strlen(spec) + 1;
  208.          _mesa_warning(NULL, "failed to remap %s", name);
  209.       }
  210.    }
  211. }
  212.  
  213.  
  214. void
  215. _mesa_init_remap_table(void)
  216. {
  217.    _mesa_do_init_remap_table(_mesa_function_pool,
  218.                              driDispatchRemapTable_size,
  219.                              MESA_remap_table_functions);
  220. }
  221.