diff options
Diffstat (limited to 'opengl/libs/GLES_trace/tools/genapi.py')
-rwxr-xr-x | opengl/libs/GLES_trace/tools/genapi.py | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/opengl/libs/GLES_trace/tools/genapi.py b/opengl/libs/GLES_trace/tools/genapi.py deleted file mode 100755 index 24034c1..0000000 --- a/opengl/libs/GLES_trace/tools/genapi.py +++ /dev/null @@ -1,408 +0,0 @@ -#!/usr/bin/env python -# -# Copyright (C) 2011 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# ABOUT -# This script is used to generate the trace implementations of all -# OpenGL calls. When executed, it reads the specs for the OpenGL calls -# from the files GLES2/gl2_api.in, GLES2/gl2ext_api.in, GLES_CM/gl_api.in, -# and GLES_CM/glext_api.in, and generates trace versions for all the -# defined functions. -# -# PREREQUISITES -# To generate C++ files, this script uses the 'pyratemp' template -# module. The only reason to use pyratemp is that it is extremly -# simple to install: -# $ wget http://www.simple-is-better.org/template/pyratemp-current/pyratemp.py -# Put the file in the GLES_trace/tools folder, or update PYTHONPATH -# to point to wherever it was downloaded. -# -# USAGE -# $ cd GLES_trace - run the program from GLES2_trace folder -# $ ./tools/genapi.py - generates a .cpp and .h file -# $ mv *.cpp *.h src/ - move the generated files into the src folder - -import sys -import re -import pyratemp - -# Constants corresponding to the protobuf DataType.Type -class DataType: - def __init__(self, name): - self.name = name - - def __str__(self): - if self.name == "pointer": # pointers map to the INT DataType - return "INT" - return self.name.upper() - - def getProtobufCall(self): - if self.name == "void": - raise ValueError("Attempt to set void value") - elif self.name == "char" or self.name == "byte" \ - or self.name == "pointer" or self.name == "enum": - return "add_intvalue((int)" - elif self.name == "int": - return "add_intvalue(" - elif self.name == "float": - return "add_floatvalue(" - elif self.name == "bool": - return "add_boolvalue(" - else: - raise ValueError("Unknown value type %s" % self.name) - -DataType.VOID = DataType("void") -DataType.CHAR = DataType("char") -DataType.BYTE = DataType("byte") -DataType.ENUM = DataType("enum") -DataType.BOOL = DataType("bool") -DataType.INT = DataType("int") -DataType.FLOAT = DataType("float") -DataType.POINTER = DataType("pointer") - -# mapping of GL types to protobuf DataType -GL2PROTOBUF_TYPE_MAP = { - "GLvoid":DataType.VOID, - "void":DataType.VOID, - "GLchar":DataType.CHAR, - "GLenum":DataType.ENUM, - "GLboolean":DataType.BOOL, - "GLbitfield":DataType.INT, - "GLbyte":DataType.BYTE, - "GLshort":DataType.INT, - "GLint":DataType.INT, - "int":DataType.INT, - "GLsizei":DataType.INT, - "GLubyte":DataType.BYTE, - "GLushort":DataType.INT, - "GLuint":DataType.INT, - "GLfloat":DataType.FLOAT, - "GLclampf":DataType.FLOAT, - "GLfixed":DataType.INT, - "GLclampx":DataType.INT, - "GLsizeiptr":DataType.INT, - "GLintptr":DataType.INT, - "GLeglImageOES":DataType.POINTER, -} - -API_SPECS = [ - ('GL2','../GLES2/gl2_api.in'), - ('GL2Ext','../GLES2/gl2ext_api.in'), - ('GL1','../GLES_CM/gl_api.in'), - ('GL1Ext','../GLES_CM/glext_api.in'), -] - -HEADER_LICENSE = """/* - * Copyright 2011, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * THIS FILE WAS GENERATED BY A SCRIPT. DO NOT EDIT. - */ -""" - -HEADER_INCLUDES = """ -#include <cutils/log.h> -#include <utils/Timers.h> -#include <GLES2/gl2.h> - -#include "gltrace.pb.h" -#include "gltrace_context.h" -#include "gltrace_fixup.h" -#include "gltrace_transport.h" -""" - -HEADER_NAMESPACE_START = """ -namespace android { -namespace gltrace { -""" - -FOOTER_TEXT = """ -}; // namespace gltrace -}; // namespace android -""" - -TRACE_CALL_TEMPLATE = pyratemp.Template( -"""$!retType!$ GLTrace_$!func!$($!inputArgList!$) { - GLMessage glmsg; - GLTraceContext *glContext = getGLTraceContext(); - - glmsg.set_function(GLMessage::$!func!$); -<!--(if len(parsedArgs) > 0)--> - <!--(for argname, argtype in parsedArgs)--> - - // copy argument $!argname!$ - GLMessage_DataType *arg_$!argname!$ = glmsg.add_args(); - arg_$!argname!$->set_isarray(false); - arg_$!argname!$->set_type(GLMessage::DataType::$!argtype!$); - arg_$!argname!$->$!argtype.getProtobufCall()!$$!argname!$); - <!--(end)--> -<!--(end)--> - - // call function - nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC); - nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD); -<!--(if retType != "void")--> - $!retType!$ retValue = glContext->hooks->gl.$!callsite!$; -<!--(else)--> - glContext->hooks->gl.$!callsite!$; -<!--(end)--> - nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD); - nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC); -<!--(if retType != "void")--> - - // set return value - GLMessage_DataType *rt = glmsg.mutable_returnvalue(); - rt->set_isarray(false); - rt->set_type(GLMessage::DataType::$!retDataType!$); - rt->$!retDataType.getProtobufCall()!$retValue); -<!--(end)--> - - void *pointerArgs[] = { -<!--(for argname, argtype in parsedArgs)--> - <!--(if argtype == DataType.POINTER)--> - (void *) $!argname!$, - <!--(end)--> -<!--(end)--> -<!--(if retDataType == DataType.POINTER)--> - (void *) retValue, -<!--(end)--> - }; - - fixupGLMessage(glContext, wallStartTime, wallEndTime, - threadStartTime, threadEndTime, - &glmsg, pointerArgs); - glContext->traceGLMessage(&glmsg); -<!--(if retType != "void")--> - - return retValue; -<!--(end)--> -} -""") - -def getDataTypeFromKw(kw): - """ Get the data type given declaration. - All pointer declarations are of type DataType.POINTER - - e.g.: GLvoid -> DataType.VOID""" - - if kw.count('*') > 0: - return DataType.POINTER - return GL2PROTOBUF_TYPE_MAP.get(kw) - -def getNameTypePair(decl): - """ Split declaration of a variable to a tuple of (variable name, DataType). - e.g. "const GLChar* varName" -> (varName, POINTER) """ - elements = decl.strip().split(' ') - name = None - if len(elements) > 1: - name = " ".join(elements[-1:]).strip() # last element is the name - dataType = " ".join(elements[:-1]).strip() # everything else is the data type - - # if name is a pointer (e.g. "*ptr"), then remove the "*" from the name - # and add it to the data type - pointersInName = name.count("*") - if pointersInName > 0: - name = name.replace("*", "") - dataType += "*" * pointersInName - - # if name is an array (e.g. "array[10]"), then remove the "[X]" from the name - # and make the datatype to be a pointer - arraysInName = name.count("[") - if arraysInName > 0: - name = name.split('[')[0] - dataType += "*" - else: - dataType = elements[0] - return (name, getDataTypeFromKw(dataType)) - -def parseArgs(arglist): - """ Parse the argument list into a list of (var name, DataType) tuples """ - args = arglist.split(',') - args = map(lambda x: x.strip(), args) # remove unnecessary whitespaces - argtypelist = map(getNameTypePair, args) # split arg into arg type and arg name - if len(argtypelist) == 1: - (name, argtype) = argtypelist[0] - if argtype == DataType.VOID: - return [] - - return argtypelist - -class ApiCall(object): - """An ApiCall models all information about a single OpenGL API""" - - # Regex to match API_ENTRY specification: - # e.g. void API_ENTRY(glActiveTexture)(GLenum texture) { - # the regex uses a non greedy match (?) to match the first closing paren - API_ENTRY_REGEX = "(.*)API_ENTRY\(.*?\)\((.*?)\)" - - # Regex to match CALL_GL_API specification: - # e.g. CALL_GL_API(glCullFace, mode); - # CALL_GL_API_RETURN(glCreateProgram); - CALL_GL_API_REGEX = "CALL_GL_API(_RETURN)?\((.*)\);" - - def __init__(self, prefix, apientry, callsite): - """Construct an ApiCall from its specification. - - The specification is provided by the two arguments: - prefix: prefix to use for function names - defn: specification line containing API_ENTRY macro - e.g: void API_ENTRY(glActiveTexture)(GLenum texture) { - callsite: specification line containing CALL_GL_API macro - e.g: CALL_GL_API(glActiveTexture, texture); - """ - self.prefix = prefix - self.ret = self.getReturnType(apientry) - self.arglist = self.getArgList(apientry) - - # some functions (e.g. __glEGLImageTargetRenderbufferStorageOES), define their - # names one way in the API_ENTRY and another way in the CALL_GL_API macros. - # so self.func is reassigned based on what is there in the call site - self.func = self.getFunc(callsite) - self.callsite = self.getCallSite(callsite) - - def getReturnType(self, apientry): - '''Extract the return type from the API_ENTRY specification''' - m = re.search(self.API_ENTRY_REGEX, apientry) - if not m: - raise ValueError("%s does not match API_ENTRY specification %s" - % (apientry, self.API_ENTRY_REGEX)) - - return m.group(1).strip() - - def getArgList(self, apientry): - '''Extract the argument list from the API_ENTRY specification''' - m = re.search(self.API_ENTRY_REGEX, apientry) - if not m: - raise ValueError("%s does not match API_ENTRY specification %s" - % (apientry, self.API_ENTRY_REGEX)) - - return m.group(2).strip() - - def parseCallSite(self, callsite): - m = re.search(self.CALL_GL_API_REGEX, callsite) - if not m: - raise ValueError("%s does not match CALL_GL_API specification (%s)" - % (callsite, self.CALL_GL_API_REGEX)) - - arglist = m.group(2) - args = arglist.split(',') - args = map(lambda x: x.strip(), args) - - return args - - def getCallSite(self, callsite): - '''Extract the callsite from the CALL_GL_API specification''' - args = self.parseCallSite(callsite) - return "%s(%s)" % (args[0], ", ".join(args[1:])) - - def getFunc(self, callsite): - '''Extract the function name from the CALL_GL_API specification''' - args = self.parseCallSite(callsite) - return args[0] - - def genDeclaration(self): - return "%s GLTrace_%s(%s);" % (self.ret, self.func, self.arglist) - - def genCode(self): - return TRACE_CALL_TEMPLATE(func = self.func, - retType = self.ret, - retDataType = getDataTypeFromKw(self.ret), - inputArgList = self.arglist, - callsite = self.callsite, - parsedArgs = parseArgs(self.arglist), - DataType=DataType) - -def getApis(apiEntryFile, prefix): - '''Get a list of all ApiCalls in provided specification file''' - lines = open(apiEntryFile).readlines() - - apis = [] - for i in range(0, len(lines)/3): - apis.append(ApiCall(prefix, lines[i*3], lines[i*3+1])) - - return apis - -def parseAllSpecs(specs): - apis = [] - for name, specfile in specs: - a = getApis(specfile, name) - print 'Parsed %s APIs from %s, # of entries = %d' % (name, specfile, len(a)) - apis.extend(a) - return apis - -def removeDuplicates(apis): - '''Remove all duplicate function entries. - - The input list contains functions declared in GL1 and GL2 APIs. - This will return a list that contains only the first function if there are - multiple functions with the same name.''' - uniqs = [] - funcs = set() - for api in apis: - if api.func not in funcs: - uniqs.append(api) - funcs.add(api.func) - - return uniqs - -def genHeaders(apis, fname): - lines = [] - lines.append(HEADER_LICENSE) - lines.append(HEADER_NAMESPACE_START) - prefix = "" - for api in apis: - if prefix != api.prefix: - lines.append("\n// Declarations for %s APIs\n\n" % api.prefix) - prefix = api.prefix - lines.append(api.genDeclaration()) - lines.append("\n") - lines.append(FOOTER_TEXT) - - with open(fname, "w") as f: - f.writelines(lines) - -def genSrcs(apis, fname): - lines = [] - lines.append(HEADER_LICENSE) - lines.append(HEADER_INCLUDES) - lines.append(HEADER_NAMESPACE_START) - prefix = "" - for api in apis: - if prefix != api.prefix: - lines.append("\n// Definitions for %s APIs\n\n" % api.prefix) - prefix = api.prefix - lines.append(api.genCode()) - lines.append("\n") - lines.append(FOOTER_TEXT) - - with open(fname, "w") as f: - f.writelines(lines) - -if __name__ == '__main__': - apis = parseAllSpecs(API_SPECS) # read in all the specfiles - apis = removeDuplicates(apis) # remove duplication of functions common to GL1 and GL2 - genHeaders(apis, 'gltrace_api.h') # generate header file - genSrcs(apis, 'gltrace_api.cpp') # generate source file |