Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 2009 Chia-I Wu <olv (at) 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 <stdbool.h>
     39 #include "remap.h"
     40 #include "imports.h"
     41 #include "glapi/glapi.h"
     42 
     43 #define MAX_ENTRY_POINTS 16
     44 
     45 #define need_MESA_remap_table
     46 #include "main/remap_helper.h"
     47 
     48 
     49 /* this is global for quick access */
     50 int driDispatchRemapTable[driDispatchRemapTable_size];
     51 
     52 
     53 /**
     54  * Map a function by its spec.  The function will be added to glapi,
     55  * and the dispatch offset will be returned.
     56  *
     57  * \param spec a '\0'-separated string array specifying a function.
     58  *        It begins with the parameter signature of the function,
     59  *        followed by the names of the entry points.  An empty entry
     60  *        point name terminates the array.
     61  *
     62  * \return the offset of the (re-)mapped function in the dispatch
     63  *         table, or -1.
     64  */
     65 static int
     66 map_function_spec(const char *spec)
     67 {
     68    const char *signature;
     69    const char *names[MAX_ENTRY_POINTS + 1];
     70    int num_names = 0;
     71 
     72    if (!spec)
     73       return -1;
     74 
     75    signature = spec;
     76    spec += strlen(spec) + 1;
     77 
     78    /* spec is terminated by an empty string */
     79    while (*spec) {
     80       names[num_names] = spec;
     81       num_names++;
     82       if (num_names >= MAX_ENTRY_POINTS)
     83          break;
     84       spec += strlen(spec) + 1;
     85    }
     86    if (!num_names)
     87       return -1;
     88 
     89    names[num_names] = NULL;
     90 
     91    /* add the entry points to the dispatch table */
     92    return _glapi_add_dispatch(names, signature);
     93 }
     94 
     95 
     96 /**
     97  * Initialize the remap table.  This is called in one_time_init().
     98  * The remap table needs to be initialized before calling the
     99  * CALL/GET/SET macros defined in main/dispatch.h.
    100  */
    101 void
    102 _mesa_init_remap_table(void)
    103 {
    104    static bool initialized = false;
    105    GLint i;
    106 
    107    if (initialized)
    108       return;
    109    initialized = true;
    110 
    111    /* initialize the MESA_remap_table_functions table */
    112    for (i = 0; i < driDispatchRemapTable_size; i++) {
    113       int offset;
    114       const char *spec;
    115 
    116       /* sanity check */
    117       assert(i == MESA_remap_table_functions[i].remap_index);
    118       spec = _mesa_function_pool + MESA_remap_table_functions[i].pool_index;
    119 
    120       offset = map_function_spec(spec);
    121       /* store the dispatch offset in the MESA_remap_table_functions table */
    122       driDispatchRemapTable[i] = offset;
    123       if (offset < 0) {
    124          const char *name = spec + strlen(spec) + 1;
    125          _mesa_warning(NULL, "failed to remap %s", name);
    126       }
    127    }
    128 }
    129