mapi_glapi.c revision 848b8605
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@lunarg.com>
27 */
28
29#include <string.h>
30#include "glapi/glapi.h"
31#include "u_current.h"
32#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */
33#include "stub.h"
34
35/*
36 * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in
37 * u_current.c.
38 */
39
40#ifdef GLX_USE_TLS
41/* not used, but defined for compatibility */
42const struct _glapi_table *_glapi_Dispatch;
43const void *_glapi_Context;
44#endif /* GLX_USE_TLS */
45
46void
47_glapi_destroy_multithread(void)
48{
49   u_current_destroy();
50}
51
52void
53_glapi_check_multithread(void)
54{
55   u_current_init();
56}
57
58void
59_glapi_set_context(void *context)
60{
61   u_current_set_context((const void *) context);
62}
63
64void
65_glapi_set_dispatch(struct _glapi_table *dispatch)
66{
67   u_current_set_table((const struct mapi_table *) dispatch);
68}
69
70/**
71 * Return size of dispatch table struct as number of functions (or
72 * slots).
73 */
74unsigned int
75_glapi_get_dispatch_table_size(void)
76{
77   return MAPI_TABLE_NUM_SLOTS;
78}
79
80/**
81 * Fill-in the dispatch stub for the named function.
82 *
83 * This function is intended to be called by a hardware driver.  When called,
84 * a dispatch stub may be created created for the function.  A pointer to this
85 * dispatch function will be returned by glXGetProcAddress.
86 *
87 * \param function_names       Array of pointers to function names that should
88 *                             share a common dispatch offset.
89 * \param parameter_signature  String representing the types of the parameters
90 *                             passed to the named function.  Parameter types
91 *                             are converted to characters using the following
92 *                             rules:
93 *                               - 'i' for \c GLint, \c GLuint, and \c GLenum
94 *                               - 'p' for any pointer type
95 *                               - 'f' for \c GLfloat and \c GLclampf
96 *                               - 'd' for \c GLdouble and \c GLclampd
97 *
98 * \returns
99 * The offset in the dispatch table of the named function.  A pointer to the
100 * driver's implementation of the named function should be stored at
101 * \c dispatch_table[\c offset].  Return -1 if error/problem.
102 *
103 * \sa glXGetProcAddress
104 *
105 * \warning
106 * This function can only handle up to 8 names at a time.  As far as I know,
107 * the maximum number of names ever associated with an existing GL function is
108 * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
109 * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
110 * too painful of a limitation.
111 *
112 * \todo
113 * Check parameter_signature.
114 */
115int
116_glapi_add_dispatch( const char * const * function_names,
117		     const char * parameter_signature )
118{
119   const struct mapi_stub *function_stubs[8];
120   const struct mapi_stub *alias = NULL;
121   unsigned i;
122
123   (void) memset(function_stubs, 0, sizeof(function_stubs));
124
125   /* find the missing stubs, and decide the alias */
126   for (i = 0; function_names[i] != NULL && i < 8; i++) {
127      const char * funcName = function_names[i];
128      const struct mapi_stub *stub;
129      int slot;
130
131      if (!funcName || funcName[0] != 'g' || funcName[1] != 'l')
132         return -1;
133      funcName += 2;
134
135      stub = stub_find_public(funcName);
136      if (!stub)
137         stub = stub_find_dynamic(funcName, 0);
138
139      slot = (stub) ? stub_get_slot(stub) : -1;
140      if (slot >= 0) {
141         if (alias && stub_get_slot(alias) != slot)
142            return -1;
143         /* use the first existing stub as the alias */
144         if (!alias)
145            alias = stub;
146
147         function_stubs[i] = stub;
148      }
149   }
150
151   /* generate missing stubs */
152   for (i = 0; function_names[i] != NULL && i < 8; i++) {
153      const char * funcName = function_names[i] + 2;
154      struct mapi_stub *stub;
155
156      if (function_stubs[i])
157         continue;
158
159      stub = stub_find_dynamic(funcName, 1);
160      if (!stub)
161         return -1;
162
163      stub_fix_dynamic(stub, alias);
164      if (!alias)
165         alias = stub;
166   }
167
168   return (alias) ? stub_get_slot(alias) : -1;
169}
170
171static const struct mapi_stub *
172_glapi_get_stub(const char *name, int generate)
173{
174   const struct mapi_stub *stub;
175
176#ifdef USE_MGL_NAMESPACE
177   if (name)
178      name++;
179#endif
180
181   if (!name || name[0] != 'g' || name[1] != 'l')
182      return NULL;
183   name += 2;
184
185   stub = stub_find_public(name);
186   if (!stub)
187      stub = stub_find_dynamic(name, generate);
188
189   return stub;
190}
191
192/**
193 * Return offset of entrypoint for named function within dispatch table.
194 */
195int
196_glapi_get_proc_offset(const char *funcName)
197{
198   const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);
199   return (stub) ? stub_get_slot(stub) : -1;
200}
201
202/**
203 * Return pointer to the named function.  If the function name isn't found
204 * in the name of static functions, try generating a new API entrypoint on
205 * the fly with assembly language.
206 */
207_glapi_proc
208_glapi_get_proc_address(const char *funcName)
209{
210   const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);
211   return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;
212}
213
214/**
215 * Return the name of the function at the given dispatch offset.
216 * This is only intended for debugging.
217 */
218const char *
219_glapi_get_proc_name(unsigned int offset)
220{
221   const struct mapi_stub *stub = stub_find_by_slot(offset);
222   return stub ? stub_get_name(stub) : NULL;
223}
224
225/**
226 * This is a deprecated function which should not be used anymore.
227 * It's only present to satisfy linking with older versions of libGL.
228 */
229unsigned long
230_glthread_GetID(void)
231{
232   return 0;
233}
234
235void
236_glapi_noop_enable_warnings(unsigned char enable)
237{
238}
239
240void
241_glapi_set_warning_func(_glapi_proc func)
242{
243}
244