summaryrefslogtreecommitdiff
path: root/src/mapi/mapi_glapi.c
blob: 9f02edb7cd3a9e9ed7d8617e21b8aae1ba3aad97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
 * Mesa 3-D graphics library
 *
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
 * Copyright (C) 2010 LunarG Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 *    Chia-I Wu <olv@lunarg.com>
 */

#include <string.h>
#include <stdlib.h>
#include "glapi/glapi.h"
#include "u_current.h"
#include "table.h" /* for MAPI_TABLE_NUM_SLOTS */
#include "stub.h"

/*
 * Global variables, _glapi_get_context, and _glapi_get_dispatch are defined in
 * u_current.c.
 */

#ifdef GLX_USE_TLS
/* not used, but defined for compatibility */
const struct _glapi_table *_glapi_Dispatch;
const void *_glapi_Context;
#endif /* GLX_USE_TLS */

void
_glapi_destroy_multithread(void)
{
   u_current_destroy();
}

void
_glapi_check_multithread(void)
{
   u_current_init();
}

void
_glapi_set_context(void *context)
{
   u_current_set_context((const void *) context);
}

void
_glapi_set_dispatch(struct _glapi_table *dispatch)
{
   u_current_set_table((const struct mapi_table *) dispatch);
}

/**
 * Return size of dispatch table struct as number of functions (or
 * slots).
 */
unsigned int
_glapi_get_dispatch_table_size(void)
{
   return MAPI_TABLE_NUM_SLOTS;
}

/**
 * Fill-in the dispatch stub for the named function.
 *
 * This function is intended to be called by a hardware driver.  When called,
 * a dispatch stub may be created created for the function.  A pointer to this
 * dispatch function will be returned by glXGetProcAddress.
 *
 * \param function_names       Array of pointers to function names that should
 *                             share a common dispatch offset.
 * \param parameter_signature  String representing the types of the parameters
 *                             passed to the named function.  Parameter types
 *                             are converted to characters using the following
 *                             rules:
 *                               - 'i' for \c GLint, \c GLuint, and \c GLenum
 *                               - 'p' for any pointer type
 *                               - 'f' for \c GLfloat and \c GLclampf
 *                               - 'd' for \c GLdouble and \c GLclampd
 *
 * \returns
 * The offset in the dispatch table of the named function.  A pointer to the
 * driver's implementation of the named function should be stored at
 * \c dispatch_table[\c offset].  Return -1 if error/problem.
 *
 * \sa glXGetProcAddress
 *
 * \warning
 * This function can only handle up to 8 names at a time.  As far as I know,
 * the maximum number of names ever associated with an existing GL function is
 * 4 (\c glPointParameterfSGIS, \c glPointParameterfEXT,
 * \c glPointParameterfARB, and \c glPointParameterf), so this should not be
 * too painful of a limitation.
 *
 * \todo
 * Check parameter_signature.
 */
int
_glapi_add_dispatch( const char * const * function_names,
		     const char * parameter_signature )
{
   const struct mapi_stub *function_stubs[8];
   const struct mapi_stub *alias = NULL;
   unsigned i;

   (void) memset(function_stubs, 0, sizeof(function_stubs));

   /* find the missing stubs, and decide the alias */
   for (i = 0; function_names[i] != NULL && i < 8; i++) {
      const char * funcName = function_names[i];
      const struct mapi_stub *stub;
      int slot;

      if (!funcName || funcName[0] != 'g' || funcName[1] != 'l')
         return -1;
      funcName += 2;

      stub = stub_find_public(funcName);
      if (!stub)
         stub = stub_find_dynamic(funcName, 0);

      slot = (stub) ? stub_get_slot(stub) : -1;
      if (slot >= 0) {
         if (alias && stub_get_slot(alias) != slot)
            return -1;
         /* use the first existing stub as the alias */
         if (!alias)
            alias = stub;

         function_stubs[i] = stub;
      }
   }

   /* generate missing stubs */
   for (i = 0; function_names[i] != NULL && i < 8; i++) {
      const char * funcName = function_names[i] + 2;
      struct mapi_stub *stub;

      if (function_stubs[i])
         continue;

      stub = stub_find_dynamic(funcName, 1);
      if (!stub)
         return -1;

      stub_fix_dynamic(stub, alias);
      if (!alias)
         alias = stub;
   }

   return (alias) ? stub_get_slot(alias) : -1;
}

static const struct mapi_stub *
_glapi_get_stub(const char *name, int generate)
{
   const struct mapi_stub *stub;

#ifdef USE_MGL_NAMESPACE
   if (name && name[0] == 'm')
      name++;
#endif

   if (!name || name[0] != 'g' || name[1] != 'l')
      return NULL;
   name += 2;

   stub = stub_find_public(name);
   if (!stub)
      stub = stub_find_dynamic(name, generate);

   return stub;
}

/**
 * Return offset of entrypoint for named function within dispatch table.
 */
int
_glapi_get_proc_offset(const char *funcName)
{
   const struct mapi_stub *stub = _glapi_get_stub(funcName, 0);
   return (stub) ? stub_get_slot(stub) : -1;
}

/**
 * Return pointer to the named function.  If the function name isn't found
 * in the name of static functions, try generating a new API entrypoint on
 * the fly with assembly language.
 */
_glapi_proc
_glapi_get_proc_address(const char *funcName)
{
   const struct mapi_stub *stub = _glapi_get_stub(funcName, 1);
   return (stub) ? (_glapi_proc) stub_get_addr(stub) : NULL;
}

/**
 * Return the name of the function at the given dispatch offset.
 * This is only intended for debugging.
 */
const char *
_glapi_get_proc_name(unsigned int offset)
{
   const struct mapi_stub *stub = stub_find_by_slot(offset);
   return stub ? stub_get_name(stub) : NULL;
}

/** Return pointer to new dispatch table filled with no-op functions */
struct _glapi_table *
_glapi_new_nop_table(unsigned num_entries)
{
   struct _glapi_table *table;

   if (num_entries > MAPI_TABLE_NUM_SLOTS)
      num_entries = MAPI_TABLE_NUM_SLOTS;

   table = malloc(num_entries * sizeof(mapi_func));
   if (table) {
      memcpy(table, table_noop_array, num_entries * sizeof(mapi_func));
   }
   return table;
}

void
_glapi_set_nop_handler(_glapi_nop_handler_proc func)
{
   table_set_noop_handler(func);
}

/**
 * This is a deprecated function which should not be used anymore.
 * It's only present to satisfy linking with older versions of libGL.
 */
unsigned long
_glthread_GetID(void)
{
   return 0;
}

void
_glapi_noop_enable_warnings(unsigned char enable)
{
}

void
_glapi_set_warning_func(_glapi_proc func)
{
}