Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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)
  321.