Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | 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.         silence = ''
  68.         space = ''
  69.         for p in f.parameterIterator(name):
  70.             if p.is_padding:
  71.                 continue
  72.  
  73.             if p.is_pointer():
  74.                 cast = "(const void *) "
  75.             else:
  76.                 cast = ""
  77.  
  78.             t_string = t_string + comma + p.format_string()
  79.             p_string = p_string + comma + p.name
  80.             o_string = o_string + comma + cast + p.name
  81.             comma = ", "
  82.  
  83.             silence += "%s(void) %s;" % (space, p.name);
  84.             space = ' '
  85.  
  86.  
  87.         if f.return_type != 'void':
  88.             dispatch = "RETURN_DISPATCH"
  89.         else:
  90.             dispatch = "DISPATCH"
  91.  
  92.         need_proto = False
  93.         if not f.is_static_entry_point(name):
  94.             need_proto = True
  95.         elif self.es:
  96.             cat, num = api.get_category_for_name(name)
  97.             if (cat.startswith("es") or cat.startswith("GL_OES")):
  98.                 need_proto = True
  99.         if need_proto:
  100.             print '%s %s KEYWORD2 NAME(%s)(%s);' % (keyword, f.return_type, n, f.get_parameter_string(name))
  101.             print ''
  102.  
  103.         print '%s %s KEYWORD2 NAME(%s)(%s)' % (keyword, f.return_type, n, f.get_parameter_string(name))
  104.         print '{'
  105.         if silence:
  106.             print '    %s' % (silence)
  107.         if p_string == "":
  108.             print '   %s(%s, (), (F, "gl%s();\\n"));' \
  109.                     % (dispatch, f.name, name)
  110.         else:
  111.             print '   %s(%s, (%s), (F, "gl%s(%s);\\n", %s));' \
  112.                     % (dispatch, f.name, p_string, name, t_string, o_string)
  113.         print '}'
  114.         print ''
  115.         return
  116.  
  117.     def printRealHeader(self):
  118.         print ''
  119.         self.printVisibility( "HIDDEN", "hidden" )
  120.         print """
  121. /*
  122. * This file is a template which generates the OpenGL API entry point
  123. * functions.  It should be included by a .c file which first defines
  124. * the following macros:
  125. *   KEYWORD1 - usually nothing, but might be __declspec(dllexport) on Win32
  126. *   KEYWORD2 - usually nothing, but might be __stdcall on Win32
  127. *   NAME(n)  - builds the final function name (usually add "gl" prefix)
  128. *   DISPATCH(func, args, msg) - code to do dispatch of named function.
  129. *                               msg is a printf-style debug message.
  130. *   RETURN_DISPATCH(func, args, msg) - code to do dispatch with a return value
  131. *
  132. * Here is an example which generates the usual OpenGL functions:
  133. *   #define KEYWORD1
  134. *   #define KEYWORD2
  135. *   #define NAME(func)  gl##func
  136. *   #define DISPATCH(func, args, msg)                           \\
  137. *          struct _glapi_table *dispatch = CurrentDispatch;     \\
  138. *          (*dispatch->func) args
  139. *   #define RETURN DISPATCH(func, args, msg)                    \\
  140. *          struct _glapi_table *dispatch = CurrentDispatch;     \\
  141. *          return (*dispatch->func) args
  142. *
  143. */
  144.  
  145.  
  146. #if defined( NAME )
  147. #ifndef KEYWORD1
  148. #define KEYWORD1
  149. #endif
  150.  
  151. #ifndef KEYWORD1_ALT
  152. #define KEYWORD1_ALT HIDDEN
  153. #endif
  154.  
  155. #ifndef KEYWORD2
  156. #define KEYWORD2
  157. #endif
  158.  
  159. #ifndef DISPATCH
  160. #error DISPATCH must be defined
  161. #endif
  162.  
  163. #ifndef RETURN_DISPATCH
  164. #error RETURN_DISPATCH must be defined
  165. #endif
  166.  
  167. """
  168.         return
  169.  
  170.  
  171.  
  172.     def printInitDispatch(self, api):
  173.         print """
  174. #endif /* defined( NAME ) */
  175.  
  176. /*
  177. * This is how a dispatch table can be initialized with all the functions
  178. * we generated above.
  179. */
  180. #ifdef DISPATCH_TABLE_NAME
  181.  
  182. #ifndef TABLE_ENTRY
  183. #error TABLE_ENTRY must be defined
  184. #endif
  185.  
  186. #ifdef _GLAPI_SKIP_NORMAL_ENTRY_POINTS
  187. #error _GLAPI_SKIP_NORMAL_ENTRY_POINTS must not be defined
  188. #endif
  189.  
  190. _glapi_proc DISPATCH_TABLE_NAME[] = {"""
  191.         for f in api.functionIterateByOffset():
  192.             print '   TABLE_ENTRY(%s),' % (f.dispatch_name())
  193.  
  194.         print '   /* A whole bunch of no-op functions.  These might be called'
  195.         print '    * when someone tries to call a dynamically-registered'
  196.         print '    * extension function without a current rendering context.'
  197.         print '    */'
  198.         for i in range(1, 100):
  199.             print '   TABLE_ENTRY(Unused),'
  200.  
  201.         print '};'
  202.         print '#endif /* DISPATCH_TABLE_NAME */'
  203.         print ''
  204.         return
  205.  
  206.  
  207.     def printAliasedTable(self, api):
  208.         print """
  209. /*
  210. * This is just used to silence compiler warnings.
  211. * We list the functions which are not otherwise used.
  212. */
  213. #ifdef UNUSED_TABLE_NAME
  214. _glapi_proc UNUSED_TABLE_NAME[] = {"""
  215.  
  216.         normal_entries = []
  217.         proto_entries = []
  218.         for f in api.functionIterateByOffset():
  219.             normal_ents, proto_ents = self.classifyEntryPoints(f)
  220.  
  221.             # exclude f.name
  222.             if f.name in normal_ents:
  223.                 normal_ents.remove(f.name)
  224.             elif f.name in proto_ents:
  225.                 proto_ents.remove(f.name)
  226.  
  227.             normal_ents = [f.static_name(ent) for ent in normal_ents]
  228.             proto_ents = [f.static_name(ent) for ent in proto_ents]
  229.  
  230.             normal_entries.extend(normal_ents)
  231.             proto_entries.extend(proto_ents)
  232.  
  233.         print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS'
  234.         for ent in normal_entries:
  235.             print '   TABLE_ENTRY(%s),' % (ent)
  236.         print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */'
  237.         print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS'
  238.         for ent in proto_entries:
  239.             print '   TABLE_ENTRY(%s),' % (ent)
  240.         print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */'
  241.  
  242.         print '};'
  243.         print '#endif /*UNUSED_TABLE_NAME*/'
  244.         print ''
  245.         return
  246.  
  247.  
  248.     def classifyEntryPoints(self, func):
  249.         normal_names = []
  250.         normal_stubs = []
  251.         proto_names = []
  252.         proto_stubs = []
  253.         # classify the entry points
  254.         for name in func.entry_points:
  255.             if func.has_different_protocol(name):
  256.                 if func.is_static_entry_point(name):
  257.                     proto_names.append(name)
  258.                 else:
  259.                     proto_stubs.append(name)
  260.             else:
  261.                 if func.is_static_entry_point(name):
  262.                     normal_names.append(name)
  263.                 else:
  264.                     normal_stubs.append(name)
  265.         # there can be at most one stub for a function
  266.         if normal_stubs:
  267.             normal_names.append(normal_stubs[0])
  268.         elif proto_stubs:
  269.             proto_names.append(proto_stubs[0])
  270.  
  271.         return (normal_names, proto_names)
  272.  
  273.     def printBody(self, api):
  274.         normal_entry_points = []
  275.         proto_entry_points = []
  276.         for func in api.functionIterateByOffset():
  277.             normal_ents, proto_ents = self.classifyEntryPoints(func)
  278.             normal_entry_points.append((func, normal_ents))
  279.             proto_entry_points.append((func, proto_ents))
  280.  
  281.         print '#ifndef _GLAPI_SKIP_NORMAL_ENTRY_POINTS'
  282.         print ''
  283.         for func, ents in normal_entry_points:
  284.             for ent in ents:
  285.                 self.printFunction(func, ent)
  286.         print ''
  287.         print '#endif /* _GLAPI_SKIP_NORMAL_ENTRY_POINTS */'
  288.         print ''
  289.         print '/* these entry points might require different protocols */'
  290.         print '#ifndef _GLAPI_SKIP_PROTO_ENTRY_POINTS'
  291.         print ''
  292.         for func, ents in proto_entry_points:
  293.             for ent in ents:
  294.                 self.printFunction(func, ent)
  295.         print ''
  296.         print '#endif /* _GLAPI_SKIP_PROTO_ENTRY_POINTS */'
  297.         print ''
  298.  
  299.         self.printInitDispatch(api)
  300.         self.printAliasedTable(api)
  301.         return
  302.  
  303.  
  304. def show_usage():
  305.     print "Usage: %s [-f input_file_name] [-c]" % sys.argv[0]
  306.     print "-c          Enable compatibility with OpenGL ES."
  307.     sys.exit(1)
  308.  
  309. if __name__ == '__main__':
  310.     file_name = "gl_API.xml"
  311.  
  312.     try:
  313.         (args, trail) = getopt.getopt(sys.argv[1:], "f:c")
  314.     except Exception,e:
  315.         show_usage()
  316.  
  317.     es = False
  318.     for (arg,val) in args:
  319.         if arg == "-f":
  320.             file_name = val
  321.         elif arg == "-c":
  322.             es = True
  323.  
  324.     api = gl_XML.parse_GL_API(file_name, glX_XML.glx_item_factory())
  325.  
  326.     printer = PrintGlOffsets(es)
  327.     printer.Print(api)
  328.