Home | History | Annotate | Download | only in mapi
      1 /*
      2  * Mesa 3-D graphics library
      3  *
      4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
      5  * Copyright (C) 2010 LunarG Inc.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     23  * DEALINGS IN THE SOFTWARE.
     24  *
     25  * Authors:
     26  *    Chia-I Wu <olv (at) lunarg.com>
     27  */
     28 
     29 #include <string.h>
     30 #include <stdlib.h>
     31 #include "glapi/glapi.h"
     32 #include "u_current.h"
     33 #include "table.h" /* for MAPI_TABLE_NUM_SLOTS */
     34 #include "stub.h"
     35 
     36 /*
     37  * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in
     38  * u_current.c.
     39  */
     40 
     41 #ifdef GLX_USE_TLS
     42 /* not used, but defined for compatibility */
     43 const struct _glapi_table *_glapi_Dispatch;
     44 const void *_glapi_Context;
     45 #endif /* GLX_USE_TLS */
     46 
     47 void
     48 _glapi_destroy_multithread(void)
     49 {
     50    u_current_destroy();
     51 }
     52 
     53 void
     54 _glapi_check_multithread(void)
     55 {
     56    u_current_init();
     57 }
     58 
     59 void
     60 _glapi_set_context(void *context)
     61 {
     62    u_current_set_context((const void *) context);
     63 }
     64 
     65 void
     66 _glapi_set_dispatch(struct _glapi_table *dispatch)
     67 {
     68    u_current_set_table((const struct _glapi_table *) dispatch);
     69 }
     70 
     71 /**
     72  * Return size of dispatch table struct as number of functions (or
     73  * slots).
     74  */
     75 unsigned int
     76 _glapi_get_dispatch_table_size(void)
     77 {
     78    return MAPI_TABLE_NUM_SLOTS;
     79 }
     80 
     81 /**
     82  * Fill-in the dispatch stub for the named function.
     83  *
     84  * This function is intended to be called by a hardware driver.  When called,
     85  * a dispatch stub may be created created for the function.  A pointer to this
     86  * dispatch function will be returned by glXGetProcAddress.
     87  *
     88  * \param function_names       Array of pointers to function names that should
     89  *                             share a common dispatch offset.
     90  * \param parameter_signature  String representing the types of the parameters
     91  *                             passed to the named function.  Parameter types
     92  *                             are converted to characters using the following
     93  *                             rules:
     94  *                               - 'i' for \c GLint, \c GLuint, and \c GLenum
     95  *                               - 'p' for any pointer type
     96  *                               - 'f' for \c GLfloat and \c GLclampf
     97  *                               - 'd' for \c GLdouble and \c GLclampd
     98  *
     99  * \returns
    100  * The offset in the dispatch table of the named function.  A pointer to the
    101  * driver's implementation of the named function should be stored at
    102  * \c dispatch_table[\c offset].  Return -1 if error/problem.
    103  *
    104  * \sa glXGetProcAddress
    105  *
    106  * \warning
    107  * This function can only handle up to 8 names at a time.  As far as I know,
    108  * the maximum number of names ever associated with an existing GL function is
    109  * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
    110  * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
    111  * too painful of a limitation.
    112  *
    113  * \todo
    114  * Check parameter_signature.
    115  */
    116 int
    117 _glapi_add_dispatch( const char * const * function_names,
    118 		     const char * parameter_signature )
    119 {
    120    const struct mapi_stub *function_stubs[8];
    121    const struct mapi_stub *alias = NULL;
    122    unsigned i;
    123 
    124    (void) memset(function_stubs, 0, sizeof(function_stubs));
    125 
    126    /* find the missing stubs, and decide the alias */
    127    for (i = 0; function_names[i] != NULL && i < 8; i++) {
    128       const char * funcName = function_names[i];
    129       const struct mapi_stub *stub;
    130       int slot;
    131 
    132       if (!funcName || funcName[0] != 'g' || funcName[1] != 'l')
    133          return -1;
    134       funcName += 2;
    135 
    136       stub = stub_find_public(funcName);
    137       if (!stub)
    138          stub = stub_find_dynamic(funcName, 0);
    139 
    140       slot = (stub) ? stub_get_slot(stub) : -1;
    141       if (slot >= 0) {
    142          if (alias && stub_get_slot(alias) != slot)
    143             return -1;
    144          /* use the first existing stub as the alias */
    145          if (!alias)
    146             alias = stub;
    147 
    148          function_stubs[i] = stub;
    149       }
    150    }
    151 
    152    /* generate missing stubs */
    153    for (i = 0; function_names[i] != NULL && i < 8; i++) {
    154       const char * funcName = function_names[i] + 2;
    155       struct mapi_stub *stub;
    156 
    157       if (function_stubs[i])
    158          continue;
    159 
    160       stub = stub_find_dynamic(funcName, 1);
    161       if (!stub)
    162          return -1;
    163 
    164       stub_fix_dynamic(stub, alias);
    165       if (!alias)
    166          alias = stub;
    167    }
    168 
    169    return (alias) ? stub_get_slot(alias) : -1;
    170 }
    171 
    172 static const struct mapi_stub *
    173 _glapi_get_stub(const char *name, int generate)
    174 {
    175    const struct mapi_stub *stub;
    176 
    177 #ifdef USE_MGL_NAMESPACE
    178    if (name && name[0] == 'm')
    179       name++;
    180 #endif
    181 
    182    if (!name || name[0] != 'g' || name[1] != 'l')
    183       return NULL;
    184    name += 2;
    185 
    186    stub = stub_find_public(name);
    187    if (!stub)
    188       stub = stub_find_dynamic(name, generate);
    189 
    190    return stub;
    191 }
    192 
    193 /**
    194  * Return offset of entrypoint for named function within dispatch table.
    195  */
    196 int
    197 _glapi_get_proc_offset(const char *funcName)
    198 {
    199    const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);
    200    return (stub) ? stub_get_slot(stub) : -1;
    201 }
    202 
    203 /**
    204  * Return pointer to the named function.  If the function name isn't found
    205  * in the name of static functions, try generating a new API entrypoint on
    206  * the fly with assembly language.
    207  */
    208 _glapi_proc
    209 _glapi_get_proc_address(const char *funcName)
    210 {
    211    const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);
    212    return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;
    213 }
    214 
    215 /**
    216  * Return the name of the function at the given dispatch offset.
    217  * This is only intended for debugging.
    218  */
    219 const char *
    220 _glapi_get_proc_name(unsigned int offset)
    221 {
    222    const struct mapi_stub *stub = stub_find_by_slot(offset);
    223    return stub ? stub_get_name(stub) : NULL;
    224 }
    225 
    226 /** Return pointer to new dispatch table filled with no-op functions */
    227 struct _glapi_table *
    228 _glapi_new_nop_table(unsigned num_entries)
    229 {
    230    struct _glapi_table *table;
    231 
    232    if (num_entries > MAPI_TABLE_NUM_SLOTS)
    233       num_entries = MAPI_TABLE_NUM_SLOTS;
    234 
    235    table = malloc(num_entries * sizeof(mapi_func));
    236    if (table) {
    237       memcpy(table, table_noop_array, num_entries * sizeof(mapi_func));
    238    }
    239    return table;
    240 }
    241 
    242 void
    243 _glapi_set_nop_handler(_glapi_nop_handler_proc func)
    244 {
    245    table_set_noop_handler(func);
    246 }
    247 
    248 /**
    249  * This is a deprecated function which should not be used anymore.
    250  * It's only present to satisfy linking with older versions of libGL.
    251  */
    252 unsigned long
    253 _glthread_GetID(void)
    254 {
    255    return 0;
    256 }
    257 
    258 void
    259 _glapi_noop_enable_warnings(unsigned char enable)
    260 {
    261 }
    262 
    263 void
    264 _glapi_set_warning_func(_glapi_proc func)
    265 {
    266 }
    267