Home | History | Annotate | Download | only in GLES2_dbg
      1 #!/usr/bin/python
      2 # -*- coding: utf-8 -*-
      3 
      4 #
      5 # Copyright 2011, The Android Open Source Project
      6 #
      7 # Licensed under the Apache License, Version 2.0 (the "License");
      8 # you may not use this file except in compliance with the License.
      9 # You may obtain a copy of the License at
     10 #
     11 #     http://www.apache.org/licenses/LICENSE-2.0
     12 #
     13 # Unless required by applicable law or agreed to in writing, software
     14 # distributed under the License is distributed on an "AS IS" BASIS,
     15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16 # See the License for the specific language governing permissions and
     17 # limitations under the License.
     18 #
     19 
     20 import os
     21 import sys
     22 
     23 externs = []
     24     
     25 def generate_caller(lines):
     26     i = 0
     27     output = ""
     28     skipFunctions = []
     29     
     30     for line in lines:
     31         if line.find("API_ENTRY(") >= 0: # a function prototype
     32             returnType = line[0: line.find(" API_ENTRY(")]
     33             functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name
     34             parameterList = line[line.find(")(") + 2: line.find(") {")]
     35             
     36             #if line.find("*") >= 0:
     37             #    extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList)
     38             #    externs.append(extern)
     39             #    continue
     40             
     41             if functionName in skipFunctions:
     42                 sys.stderr.write("!\n! skipping function '%s'\n!\n" % functionName)
     43                 continue
     44             output += "\
     45     case glesv2debugger::Message_Function_%s:\n" % functionName
     46             parameters = parameterList.split(',')
     47             paramIndex = 0
     48             if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer
     49                 # add function to list of functions that should be hand written, but generate code anyways
     50                 externs.append(functionName)
     51                 output += "\
     52         ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\
     53         break;\n" % (functionName)
     54                 continue
     55             elif line.find(":out") >= 0 or line.find(":inout") >= 0:
     56                 externs.append(functionName)
     57                 output += "\
     58         ret = GenerateCall_%s(dbg, cmd, msg, prevRet);\n\
     59         break; // annotated output pointers\n" % (functionName)
     60                 continue
     61                 
     62             if parameterList == "void":
     63                 parameters = []
     64             arguments = ""
     65             paramNames = []
     66             inout = ""
     67             getData = ""
     68             
     69             callerMembers = ""
     70 
     71             for parameter in parameters:
     72                 const = parameter.find("const")
     73                 parameter = parameter.replace("const", "")
     74                 parameter = parameter.strip()
     75                 paramType = parameter.split(' ')[0]
     76                 paramName = parameter.split(' ')[1]
     77                 annotation = ""
     78                 if parameter.find(":") >= 0: # has annotation
     79                     assert inout == "" # only one parameter should be annotated
     80                     sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType))
     81                     inout = paramType.split(":")[2]
     82                     annotation = paramType.split(":")[1]
     83                     paramType = paramType.split(":")[0]
     84                     count = 1
     85                     countArg = ""
     86                     if annotation.find("*") >= 0: # [1,n] * param
     87                         count = int(annotation.split("*")[0])
     88                         countArg = annotation.split("*")[1]
     89                         assert countArg in paramNames
     90                     elif annotation in paramNames:
     91                         count = 1
     92                         countArg = annotation
     93                     elif annotation == "GLstring":
     94                         annotation = "strlen(%s)" % (paramName)
     95                     else:
     96                         count = int(annotation)
     97             
     98                     paramType += "*"
     99                     arguments += "reinterpret_cast<%s>(const_cast<char *>(cmd.data().data()))" % (paramType)
    100                 elif paramType == "GLboolean":
    101                     arguments += "GLboolean(cmd.arg%d())" % (paramIndex)
    102                 else:
    103                     arguments += "static_cast<%s>(cmd.arg%d())" % (paramType, paramIndex)
    104 
    105                 if paramIndex < len(parameters) - 1:
    106                         arguments += ", "
    107                 if len(arguments) - arguments.rfind("\n") > 60 :
    108                     arguments += "\n\
    109             "
    110                 if const >= 0:
    111                     paramType = "const " + paramType
    112                 paramNames.append(paramName)
    113                 paramIndex += 1
    114                 
    115             if returnType == "void":
    116                 output += "\
    117         dbg->hooks->gl.%s(\n\
    118             %s);\n\
    119         break;\n" % (functionName, arguments)
    120             else:
    121                 output += "\
    122         msg.set_ret(static_cast<int>(dbg->hooks->gl.%s(\n\
    123             %s)));\n\
    124         if (cmd.has_ret())\n\
    125             ret = reinterpret_cast<int *>(msg.ret());\n\
    126         break;\n" % (functionName, arguments)
    127     return output
    128 
    129 if __name__ == "__main__":
    130 
    131     lines = open("gl2_api_annotated.in").readlines()
    132     output = generate_caller(lines)
    133     
    134     out = open("src/caller.cpp", "w")
    135     out.write("""\
    136 /*
    137  ** Copyright 2011, The Android Open Source Project
    138  **
    139  ** Licensed under the Apache License, Version 2.0 (the "License");
    140  ** you may not use this file except in compliance with the License.
    141  ** You may obtain a copy of the License at
    142  **
    143  **     http://www.apache.org/licenses/LICENSE-2.0
    144  **
    145  ** Unless required by applicable law or agreed to in writing, software
    146  ** distributed under the License is distributed on an "AS IS" BASIS,
    147  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    148  ** See the License for the specific language governing permissions and
    149  ** limitations under the License.
    150  */
    151 
    152 // auto generated by generate_caller_cpp.py
    153 // implement declarations in caller.h
    154 
    155 #include "header.h"
    156 
    157 namespace android {
    158 
    159 """)
    160 
    161     for extern in externs:
    162         out.write("\
    163 static const int * GenerateCall_%s(DbgContext * const dbg,\n\
    164     const glesv2debugger::Message & cmd, glesv2debugger::Message & msg, const int * const prevRet);\n" % (extern))
    165         print("\
    166 static const int * GenerateCall_%s(DbgContext * const dbg,\n\
    167                             const glesv2debugger::Message & cmd,\n\
    168                             glesv2debugger::Message & msg, const int * const prevRet)\n\
    169 { assert(0); return prevRet; }\n" % (extern))
    170                      
    171     out.write(
    172 """
    173 #include "caller.h"
    174 
    175 const int * GenerateCall(DbgContext * const dbg, const glesv2debugger::Message & cmd,
    176                   glesv2debugger::Message & msg, const int * const prevRet)
    177 {
    178     LOGD("GenerateCall function=%u", cmd.function());
    179     const int * ret = prevRet; // only some functions have return value
    180     nsecs_t c0 = systemTime(timeMode);
    181     switch (cmd.function()) {""")
    182     
    183     out.write(output)
    184     
    185     out.write("""\
    186     default:
    187         assert(0);
    188     }
    189     msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
    190     msg.set_context_id(reinterpret_cast<int>(dbg));
    191     msg.set_function(cmd.function());
    192     msg.set_type(glesv2debugger::Message_Type_AfterCall);
    193     return ret;
    194 }
    195 
    196 }; // name space android {
    197 """)           
    198     
    199             
    200