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 20import os 21import sys 22 23def RemoveAnnotation(line): 24 if line.find(":") >= 0: 25 annotation = line[line.find(":"): line.find(" ", line.find(":"))] 26 return line.replace(annotation, "*") 27 else: 28 return line 29 30def generate_api(lines): 31 externs = [] 32 i = 0 33 # these have been hand written 34 skipFunctions = ["glDrawArrays", "glDrawElements"] 35 36 # these have an EXTEND_Debug_* macro for getting data 37 extendFunctions = ["glCopyTexImage2D", "glCopyTexSubImage2D", "glReadPixels", 38"glShaderSource", "glTexImage2D", "glTexSubImage2D"] 39 40 # these also needs to be forwarded to DbgContext 41 contextFunctions = ["glUseProgram", "glEnableVertexAttribArray", "glDisableVertexAttribArray", 42"glVertexAttribPointer", "glBindBuffer", "glBufferData", "glBufferSubData", "glDeleteBuffers",] 43 44 for line in lines: 45 if line.find("API_ENTRY(") >= 0: # a function prototype 46 returnType = line[0: line.find(" API_ENTRY(")] 47 functionName = line[line.find("(") + 1: line.find(")")] #extract GL function name 48 parameterList = line[line.find(")(") + 2: line.find(") {")] 49 50 #if line.find("*") >= 0: 51 # extern = "%s Debug_%s(%s);" % (returnType, functionName, parameterList) 52 # externs.append(extern) 53 # continue 54 55 if functionName in skipFunctions: 56 sys.stderr.write("!\n! skipping function '%s'\n!\n" % (functionName)) 57 continue 58 59 parameters = parameterList.split(',') 60 paramIndex = 0 61 if line.find("*") >= 0 and (line.find("*") < line.find(":") or line.find("*") > line.rfind(":")): # unannotated pointer 62 if not functionName in extendFunctions: 63 # add function to list of functions that should be hand written, but generate code anyways 64 extern = "%s Debug_%s(%s);" % (returnType, functionName, RemoveAnnotation(parameterList)) 65 sys.stderr.write("%s should be hand written\n" % (extern)) 66 print "// FIXME: this function has pointers, it should be hand written" 67 externs.append(extern) 68 69 print "%s Debug_%s(%s)\n{" % (returnType, functionName, RemoveAnnotation(parameterList)) 70 print " glesv2debugger::Message msg;" 71 72 if parameterList == "void": 73 parameters = [] 74 arguments = "" 75 paramNames = [] 76 inout = "" 77 getData = "" 78 79 callerMembers = "" 80 setCallerMembers = "" 81 setMsgParameters = "" 82 83 for parameter in parameters: 84 const = parameter.find("const") 85 parameter = parameter.replace("const", "") 86 parameter = parameter.strip() 87 paramType = parameter.split(' ')[0] 88 paramName = parameter.split(' ')[1] 89 annotation = "" 90 arguments += paramName 91 if parameter.find(":") >= 0: # has annotation 92 assert inout == "" # only one parameter should be annotated 93 sys.stderr.write("%s is annotated: %s \n" % (functionName, paramType)) 94 inout = paramType.split(":")[2] 95 annotation = paramType.split(":")[1] 96 paramType = paramType.split(":")[0] 97 count = 1 98 countArg = "" 99 if annotation.find("*") >= 0: # [1,n] * param 100 count = int(annotation.split("*")[0]) 101 countArg = annotation.split("*")[1] 102 assert countArg in paramNames 103 elif annotation in paramNames: 104 count = 1 105 countArg = annotation 106 elif annotation == "GLstring": 107 annotation = "strlen(%s)" % (paramName) 108 else: 109 count = int(annotation) 110 111 setMsgParameters += " msg.set_arg%d(ToInt(%s));\n" % (paramIndex, paramName) 112 if paramType.find("void") >= 0: 113 getData += " msg.mutable_data()->assign(reinterpret_cast<const char *>(%s), %s * sizeof(char));" % (paramName, annotation) 114 else: 115 getData += " msg.mutable_data()->assign(reinterpret_cast<const char *>(%s), %s * sizeof(%s));" % (paramName, annotation, paramType) 116 paramType += "*" 117 else: 118 if paramType == "GLfloat" or paramType == "GLclampf" or paramType.find("*") >= 0: 119 setMsgParameters += " msg.set_arg%d(ToInt(%s));\n" % (paramIndex, paramName) 120 else: 121 setMsgParameters += " msg.set_arg%d(%s);\n" % (paramIndex, paramName) 122 if paramIndex < len(parameters) - 1: 123 arguments += ', ' 124 if const >= 0: 125 paramType = "const " + paramType 126 paramNames.append(paramName) 127 paramIndex += 1 128 callerMembers += " %s %s;\n" % (paramType, paramName) 129 setCallerMembers += " caller.%s = %s;\n" % (paramName, paramName) 130 131 print " struct : public FunctionCall {" 132 print callerMembers 133 print " const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {" 134 if inout in ["out", "inout"]: # get timing excluding output data copy 135 print " nsecs_t c0 = systemTime(timeMode);" 136 if returnType == "void": 137 print " _c->%s(%s);" % (functionName, arguments) 138 else: 139 print " const int * ret = reinterpret_cast<const int *>(_c->%s(%s));" % (functionName, arguments) 140 print " msg.set_ret(ToInt(ret));" 141 if inout in ["out", "inout"]: 142 print " msg.set_time((systemTime(timeMode) - c0) * 1e-6f);" 143 print " " + getData 144 if functionName in extendFunctions: 145 print "\ 146#ifdef EXTEND_AFTER_CALL_Debug_%s\n\ 147 EXTEND_AFTER_CALL_Debug_%s;\n\ 148#endif" % (functionName, functionName) 149 if functionName in contextFunctions: 150 print " getDbgContextThreadSpecific()->%s(%s);" % (functionName, arguments) 151 if returnType == "void": 152 print " return 0;" 153 else: 154 print " return ret;" 155 print """ } 156 } caller;""" 157 print setCallerMembers 158 print setMsgParameters 159 160 if line.find("*") >= 0 or line.find(":") >= 0: 161 print " // FIXME: check for pointer usage" 162 if inout in ["in", "inout"]: 163 print getData 164 if functionName in extendFunctions: 165 print "\ 166#ifdef EXTEND_Debug_%s\n\ 167 EXTEND_Debug_%s;\n\ 168#endif" % (functionName, functionName) 169 print " int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_%s);"\ 170 % (functionName) 171 if returnType != "void": 172 if returnType == "GLboolean": 173 print " return static_cast<GLboolean>(reinterpret_cast<int>(ret));" 174 else: 175 print " return reinterpret_cast<%s>(ret);" % (returnType) 176 print "}\n" 177 178 179 print "// FIXME: the following functions should be written by hand" 180 for extern in externs: 181 print extern 182 183if __name__ == "__main__": 184 print """\ 185/* 186 ** Copyright 2011, The Android Open Source Project 187 ** 188 ** Licensed under the Apache License, Version 2.0 (the "License"); 189 ** you may not use this file except in compliance with the License. 190 ** You may obtain a copy of the License at 191 ** 192 ** http://www.apache.org/licenses/LICENSE-2.0 193 ** 194 ** Unless required by applicable law or agreed to in writing, software 195 ** distributed under the License is distributed on an "AS IS" BASIS, 196 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 197 ** See the License for the specific language governing permissions and 198 ** limitations under the License. 199 */ 200 201// auto generated by generate_api_cpp.py 202 203#include <utils/Debug.h> 204 205#include "src/header.h" 206#include "src/api.h" 207 208template<typename T> static int ToInt(const T & t) 209{ 210 COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(T) == sizeof(int)); 211 return (int &)t; 212} 213""" 214 lines = open("gl2_api_annotated.in").readlines() 215 generate_api(lines) 216 #lines = open("gl2ext_api.in").readlines() 217 #generate_api(lines) 218 219 220