summaryrefslogtreecommitdiffstats
path: root/opengl/libs/GLES_trace/tools/genapi.py
diff options
context:
space:
mode:
Diffstat (limited to 'opengl/libs/GLES_trace/tools/genapi.py')
-rwxr-xr-xopengl/libs/GLES_trace/tools/genapi.py408
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