Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mapi / glapi / gen / gl_apitemp.py
1 #!/usr/bin/env python
2
3 # (C) Copyright IBM Corporation 2004, 2005
4 # All Rights Reserved.
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 # on the rights to use, copy, modify, merge, publish, distribute, sub
10 # license, and/or sell copies of the Software, and to permit persons to whom
11 # the Software is furnished to do so, subject to the following conditions:
12 #
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
15 # 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
20 # IBM AND/OR ITS SUPPLIERS 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 DEALINGS
23 # IN THE SOFTWARE.
24 #
25 # Authors:
26 #    Ian Romanick <idr@us.ibm.com>
27
28 import gl_XML, glX_XML
29 import license
30 import sys, getopt
31
32 class PrintGlOffsets(gl_XML.gl_print_base):
33         def __init__(self, es=False):
34                 gl_XML.gl_print_base.__init__(self)
35
36                 self.name = "gl_apitemp.py (from Mesa)"
37                 self.license = license.bsd_license_template % ( \
38 """Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
39 (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM")
40
41                 self.es = es
42
43                 self.undef_list.append( "KEYWORD1" )
44                 self.undef_list.append( "KEYWORD1_ALT" )
45                 self.undef_list.append( "KEYWORD2" )
46                 self.undef_list.append( "NAME" )
47                 self.undef_list.append( "DISPATCH" )
48                 self.undef_list.append( "RETURN_DISPATCH" )
49                 self.undef_list.append( "DISPATCH_TABLE_NAME" )
50                 self.undef_list.append( "UNUSED_TABLE_NAME" )
51                 self.undef_list.append( "TABLE_ENTRY" )
52
53
54         def printFunction(self, f, name):
55                 p_string = ""
56                 o_string = ""
57                 t_string = ""
58                 comma = ""
59
60                 if f.is_static_entry_point(name):
61                         keyword = "KEYWORD1"
62                 else:
63                         keyword = "KEYWORD1_ALT"
64
65                 n = f.static_name(name)
66
67                 for p in f.parameterIterator():
68                         if p.is_padding:
69                                 continue
70
71                         if p.is_pointer():
72                                 cast = "(const void *) "
73                         else:
74                                 cast = ""
75
76                         t_string = t_string + comma + p.format_string()
77                         p_string = p_string + comma + p.name
78                         o_string = o_string + comma + cast + p.name
79                         comma = ", "
80
81
82                 if f.return_type != 'void':
83                         dispatch = "RETURN_DISPATCH"
84                 else:
85                         dispatch = "DISPATCH"
86
87                 need_proto = False
88                 if not f.is_static_entry_point(name):
89                         need_proto = True
90                 elif self.es:
91                         cat, num = api.get_category_for_name(name)
92                         if (cat.startswith("es") or cat.startswith("GL_OES")):
93                                 need_proto = True
94                 if need_proto:
95                         print '%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name))
96                         print ''
97
98                 print '%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name))
99                 print '{'
100                 if p_string == "":
101                         print '   %s(%s, (), (F, "gl%s();\\n"));' \
102                                 % (dispatch, f.name, name)
103                 else:
104                         print '   %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \
105                                 % (dispatch, f.name, p_string, name, t_string, o_string)
106                 print '}'
107                 print ''
108                 return
109
110         def printRealHeader(self):
111                 print ''
112                 self.printVisibility( "HIDDEN", "hidden" )
113                 print """
114 /*
115  * This file is a template which generates the OpenGL API entry point
116  * functions.  It should be included by a .c file which first defines
117  * the following macros:
118  *   KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32
119  *   KEYWORD2 - usually nothing, but might be __stdcall on Win32
120  *   NAME(n)  - builds the final function name (usually add "gl" prefix)
121  *   DISPATCH(func, args, msg) - code to do dispatch of named function.
122  *                               msg is a printf-style debug message.
123  *   RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value
124  *
125  * Here is an example which generates the usual OpenGL functions:
126  *   #define KEYWORD1
127  *   #define KEYWORD2
128  *   #define NAME(func)  gl##func
129  *   #define DISPATCH(func, args, msg)                           \\
130  *          struct _glapi_table *dispatch = CurrentDispatch;     \\
131  *          (*dispatch->func) args
132  *   #define RETURN DISPATCH(func, args, msg)                    \\
133  *          struct _glapi_table *dispatch = CurrentDispatch;     \\
134  *          return (*dispatch->func) args
135  *
136  */
137
138
139 #if defined( NAME )
140 #ifndef KEYWORD1
141 #define KEYWORD1
142 #endif
143
144 #ifndef KEYWORD1_ALT
145 #define KEYWORD1_ALT HIDDEN
146 #endif
147
148 #ifndef KEYWORD2
149 #define KEYWORD2
150 #endif
151
152 #ifndef DISPATCH
153 #error DISPATCH must be defined
154 #endif
155
156 #ifndef RETURN_DISPATCH
157 #error RETURN_DISPATCH must be defined
158 #endif
159
160 """
161                 return
162
163     
164
165         def printInitDispatch(self, api):
166                 print """
167 #endif /* defined( NAME ) */
168
169 /*
170  * This is how a dispatch table can be initialized with all the functions
171  * we generated above.
172  */
173 #ifdef DISPATCH_TABLE_NAME
174
175 #ifndef TABLE_ENTRY
176 #error TABLE_ENTRY must be defined
177 #endif
178
179 #ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS
180 #error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined
181 #endif
182
183 _glapi_proc DISPATCH_TABLE_NAME[] = {"""
184                 for f in api.functionIterateByOffset():
185                         print '   TABLE_ENTRY(%s),' % (f.dispatch_name())
186
187                 print '   /* A whole bunch of no-op functions.  These might be called'
188                 print '    * when someone tries to call a dynamically-registered'
189                 print '    * extension function without a current rendering context.'
190                 print '    */'
191                 for i in range(1, 100):
192                         print '   TABLE_ENTRY(Unused),'
193
194                 print '};'
195                 print '#endif /* DISPATCH_TABLE_NAME */'
196                 print ''
197                 return
198
199
200         def printAliasedTable(self, api):
201                 print """
202 /*
203  * This is just used to silence compiler warnings.
204  * We list the functions which are not otherwise used.
205  */
206 #ifdef UNUSED_TABLE_NAME
207 _glapi_proc UNUSED_TABLE_NAME[] = {"""
208
209                 normal_entries = []
210                 proto_entries = []
211                 for f in api.functionIterateByOffset():
212                         normal_ents, proto_ents = self.classifyEntryPoints(f)
213
214                         # exclude f.name
215                         if f.name in normal_ents:
216                                 normal_ents.remove(f.name)
217                         elif f.name in proto_ents:
218                                 proto_ents.remove(f.name)
219
220                         normal_ents = [f.static_name(ent) for ent in normal_ents]
221                         proto_ents = [f.static_name(ent) for ent in proto_ents]
222
223                         normal_entries.extend(normal_ents)
224                         proto_entries.extend(proto_ents)
225
226                 print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS'
227                 for ent in normal_entries:
228                         print '   TABLE_ENTRY(%s),' % (ent)
229                 print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */'
230                 print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS'
231                 for ent in proto_entries:
232                         print '   TABLE_ENTRY(%s),' % (ent)
233                 print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */'
234
235                 print '};'
236                 print '#endif /*UNUSED_TABLE_NAME*/'
237                 print ''
238                 return
239
240
241         def classifyEntryPoints(self, func):
242                 normal_names = []
243                 normal_stubs = []
244                 proto_names = []
245                 proto_stubs = []
246                 # classify the entry points
247                 for name in func.entry_points:
248                         if func.has_different_protocol(name):
249                                 if func.is_static_entry_point(name):
250                                         proto_names.append(name)
251                                 else:
252                                         proto_stubs.append(name)
253                         else:
254                                 if func.is_static_entry_point(name):
255                                         normal_names.append(name)
256                                 else:
257                                         normal_stubs.append(name)
258                 # there can be at most one stub for a function
259                 if normal_stubs:
260                         normal_names.append(normal_stubs[0])
261                 elif proto_stubs:
262                         proto_names.append(proto_stubs[0])
263
264                 return (normal_names, proto_names)
265
266         def printBody(self, api):
267                 normal_entry_points = []
268                 proto_entry_points = []
269                 for func in api.functionIterateByOffset():
270                         normal_ents, proto_ents = self.classifyEntryPoints(func)
271                         normal_entry_points.append((func, normal_ents))
272                         proto_entry_points.append((func, proto_ents))
273
274                 print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS'
275                 print ''
276                 for func, ents in normal_entry_points:
277                         for ent in ents:
278                                 self.printFunction(func, ent)
279                 print ''
280                 print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */'
281                 print ''
282                 print '/* these entry points might require different protocols */'
283                 print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS'
284                 print ''
285                 for func, ents in proto_entry_points:
286                         for ent in ents:
287                                 self.printFunction(func, ent)
288                 print ''
289                 print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */'
290                 print ''
291
292                 self.printInitDispatch(api)
293                 self.printAliasedTable(api)
294                 return
295
296
297 def show_usage():
298         print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0]
299         print "-c          Enable compatibility with OpenGL ES."
300         sys.exit(1)
301
302 if __name__ == '__main__':
303         file_name = "gl_API.xml"
304     
305         try:
306                 (args, trail) = getopt.getopt(sys.argv[1:], "f:c")
307         except Exception,e:
308                 show_usage()
309
310         es = False
311         for (arg,val) in args:
312                 if arg == "-f":
313                         file_name = val
314                 elif arg == "-c":
315                         es = True
316
317         api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
318
319         printer = PrintGlOffsets(es)
320         printer.Print(api)