/* * GLOMP - transparent multipipe OpenGL * Copyright (C) 2007 the GLOMP team (see AUTHORS) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include int np=-1; int fnum=0; int i; char * type[50]; char * return_type,* buffer; char * nameparam[50]; //int count[50]; char * count[50]; char * variable_param[50]; char * img_width[50]; char * img_height[50]; char * img_depth[50]; char * img_type[50]; char * img_format[50]; int param_attrib[50][8]; // [0]=count [1]=variable_param [2]=img_width //[3]=img_height [4]=img_depth [5]=img_type [6]=output [7]=format typedef struct gl_type{ char* name; int size; char* print; char* cast; } gl_type; gl_type type_table[]= { {"void",0,"",""}, {"GLsizeiptr",sizeof(GLsizeiptr),"%p","(void*)"}, {"GLsizeiptrARB",sizeof(GLsizeiptrARB),"%p","(void*)"}, {"GLintptr",sizeof(GLintptr),"%p","(void*)"}, {"GLintptrARB",sizeof(GLintptrARB),"%p","(void*)"}, {"GLvoid",sizeof(GLvoid),"",""}, {"GLvoid *",sizeof(GLvoid),"%p",""}, {"GLvoid * const *",sizeof(GLvoid),"%p",""}, {"GLvoid **",sizeof(GLvoid),"%p",""}, {"GLboolean",sizeof(GLboolean),"%d",""}, {"GLboolean *",sizeof(GLboolean),"%p",""}, {"GLboolean **",sizeof(GLboolean),"%p",""}, {"GLenum",sizeof(GLenum),"%d",""}, {"GLenum *",sizeof(GLenum),"%p",""}, {"GLhandleARB",sizeof(GLhandleARB),"%d",""}, {"GLhandleARB *",sizeof(GLhandleARB),"%p",""}, {"GLint",sizeof(GLint),"%d",""}, {"GLint *",sizeof(GLint),"%p",""}, {"GLuint",sizeof(GLuint),"%d",""}, {"GLuint *",sizeof(GLuint),"%p",""}, {"GLubyte",sizeof(GLubyte),"%d",""}, {"GLubyte *",sizeof(GLubyte),"%p",""}, {"GLchar",sizeof(GLchar),"%d",""}, {"GLchar *",sizeof(GLchar),"%p",""}, {"GLchar **",sizeof(GLchar),"%p",""}, {"GLcharARB",sizeof(GLcharARB),"%d",""}, {"GLcharARB *",sizeof(GLcharARB),"%p",""}, {"GLcharARB **",sizeof(GLcharARB),"%p",""}, {"GLbyte",sizeof(GLbyte),"%d",""}, {"GLbyte *",sizeof(GLbyte),"%p",""}, {"GLshort",sizeof(GLshort),"%d",""}, {"GLshort *",sizeof(GLshort),"%p",""}, {"GLushort",sizeof(GLushort),"%d",""}, {"GLushort *",sizeof(GLushort),"%p",""}, {"GLfloat",sizeof(GLfloat),"%f",""}, {"GLfloat *",sizeof(GLfloat),"%p",""}, {"GLdouble",sizeof(GLdouble),"%f",""}, {"GLdouble *",sizeof(GLdouble),"%p",""}, {"GLsizei",sizeof(GLsizei),"%d",""}, {"GLsizei ",sizeof(GLsizei),"%d",""}, {"GLsizei *",sizeof(GLsizei),"%p",""}, {"GLclampf",sizeof(GLclampf),"%f",""}, {"GLclampf *",sizeof(GLclampf),"%p",""}, {"GLclampd",sizeof(GLclampd),"%f",""}, {"GLclampd *",sizeof(GLclampd),"%p",""}, {"GLhalfNV",sizeof(GLhalfNV),"%x",""}, {"GLhalfNV *",sizeof(GLhalfNV),"%p",""}, {"GLbitfield", sizeof(GLbitfield),"%x",""}, {"GLint64EXT *",sizeof(int64_t),"%p",""}, {"GLuint64EXT *",sizeof(int64_t),"%p",""}, {NULL,0,"",""}, }; static char * type_remove_const(char * type) { char* r = strstr(type,"const"); if (r) return r+6; else return type; } static int type_match(char* type) { char* t = type_remove_const(type); int i = 0; while(type_table[i].name != NULL) { if (strcmp(t, type_table[i].name) == 0) return i; i++; } printf("unmatched %s\n",t); assert(0); return -1; } static char* type_print(char* type) { int i=0; while(type_table[i].name!=NULL) { if (strcmp(type_remove_const(type),type_table[i].name)==0) return type_table[i].print; i++; } return NULL; } static int type_size(char* type) { int i=0; while(type_table[i].name!=NULL) { if (strcmp(type_remove_const(type),type_table[i].name)==0) return type_table[i].size; i++; } return 0; } static char* type_cast(char* type) { int i=0; while(type_table[i].name!=NULL) { if (strcmp(type_remove_const(type),type_table[i].name)==0) return type_table[i].cast; i++; } return NULL; } int main() { char * docname="gl_API.xml"; xmlDocPtr doc; xmlNodePtr cur; xmlNodePtr retour,retourcategory; xmlChar *attrib; xmlChar *func_name; FILE * file_wrapped = fopen("wrapped.c","wb"); FILE * file_functable = fopen("functable.c","wb"); FILE * file_getprocaddr = fopen("getprocaddr.c","wb"); for(i=0;i<50;i++) { type[i]=malloc(sizeof(char)*50); nameparam[i]=malloc(sizeof(char)*50); img_width[i]=malloc(sizeof(char)*50); img_height[i]=malloc(sizeof(char)*50); img_depth[i]=malloc(sizeof(char)*50); img_type[i]=malloc(sizeof(char)*50); count[i]=malloc(sizeof(char)*50); variable_param[i]=malloc(sizeof(char)*50); img_format[i]=malloc(sizeof(char)*50); } return_type=malloc(sizeof(char)*50); buffer=malloc(sizeof(char)*2048); doc = xmlParseFile(docname); if (doc == NULL ) { fprintf(stderr, "Document not parsed successfully. \n"); return; } cur = xmlDocGetRootElement(doc); if (cur == NULL) { fprintf(stderr, "empty document\n"); xmlFreeDoc(doc); return; } if (xmlStrcmp(cur->name, (const xmlChar *) "OpenGLAPI")) { fprintf(stderr, "document of the wrong type, root node != story"); xmlFreeDoc(doc); return; } fprintf(file_functable, "static void* functable[4096];\n"); fprintf(file_functable, "static void functable_init()\n{\n"); fprintf(file_getprocaddr, "static struct {\n\tchar* name;\n\tint num;\n}\nget_proc_list[] = {\n"); cur = cur->xmlChildrenNode; cur = cur->next; while (cur != NULL) { retourcategory = cur; if( (!xmlStrcmp(cur->name, (const xmlChar *)"category")) ) { cur = cur->xmlChildrenNode; cur = cur->next; while (cur != NULL) { retour=cur; if( (!xmlStrcmp(cur->name, (const xmlChar *)"enum")) ) { attrib=xmlGetProp(cur, "count"); if(attrib!=NULL) { attrib=xmlGetProp(cur, "value"); attrib=xmlGetProp(cur, "count"); } } else if (!xmlStrcmp(cur->name, (const xmlChar *)"function")) { cur = cur->xmlChildrenNode; if(cur->next!=NULL) cur = cur->next; while((!xmlStrcmp(cur->name, (const xmlChar *)"param"))) { if(cur->next->next==NULL) break; cur = cur->next->next; } // function return value if(!xmlStrcmp(cur->name, (const xmlChar *)"return")) { attrib = xmlGetProp(cur, "type"); strcpy(return_type,attrib); fprintf(file_wrapped,"%s ",attrib); } else { fprintf(file_wrapped,"void "); strcpy(return_type,"void"); } cur = retour; func_name = xmlGetProp(cur, "name"); fprintf(file_wrapped,"gl%s(",func_name); fprintf(file_functable,"\tfunctable[%d]=(void*)lib_glXGetProcAddressARB(\"gl%s\");\n",fnum,func_name); cur = cur->xmlChildrenNode; if(cur->next!=NULL) cur = cur->next; attrib = xmlGetProp(cur, "name"); np=-1; if(!xmlStrcmp(cur->name, (const xmlChar *)"return")) cur = cur->next->next; /* function parameters */ while((!xmlStrcmp(cur->name, (const xmlChar *)"param"))) { np++; attrib = xmlGetProp(cur, "name"); strcpy(nameparam[np],attrib); attrib = xmlGetProp(cur, "type"); if (strcmp(nameparam[np],"UNUSED")!=0) fprintf(file_wrapped,"%s %s,",attrib,nameparam[np]); strcpy(type[np],attrib); /*verification de presence de l'attribut count*/ attrib=xmlGetProp(cur, "count"); if( attrib!=NULL) { strcpy(count[np],attrib); param_attrib[np][0]=1; } else param_attrib[np][0]=0; /*verification de presence de l'attribut variable_param*/ attrib=xmlGetProp(cur, "variable_param"); if( attrib!=NULL) { strcpy(variable_param[np],attrib); param_attrib[np][1]=1; } else param_attrib[np][1]=0; /*verification de presence de l'attribut img_width*/ attrib=xmlGetProp(cur, "img_width"); if( attrib!=NULL) { strcpy(img_width[np],attrib); param_attrib[np][2]=1; } else param_attrib[np][2]=0; /*verification de presence de l'attribut img_height*/ attrib=xmlGetProp(cur, "img_height"); if( attrib!=NULL) { strcpy(img_height[np],attrib); param_attrib[np][3]=1; } else param_attrib[np][3]=0; /*verification de presence de l'attribut img_depth*/ attrib=xmlGetProp(cur, "img_depth"); if( attrib!=NULL) { strcpy(img_depth[np],attrib); param_attrib[np][4]=1; } else param_attrib[np][4]=0; /*verification de presence de l'attribut img_type*/ attrib=xmlGetProp(cur, "img_type"); if( attrib!=NULL) { strcpy(img_type[np],attrib); param_attrib[np][5]=1; } else param_attrib[np][5]=0; /*verification de presence de l'attribut output*/ attrib=xmlGetProp(cur, "output"); if( attrib!=NULL) { param_attrib[np][6]=1; } else param_attrib[np][6]=0; /*verification de presence de l'attribut img_format*/ attrib=xmlGetProp(cur, "img_format"); if( attrib!=NULL) { param_attrib[np][7]=1; strcpy(img_format[np],attrib); } else param_attrib[np][7]=0; if(cur->next->next==NULL) break; cur = cur->next->next; } //fin de detection des parametres de la fonction if(np!=-1) { fseek(file_wrapped,-1,SEEK_CUR); } fprintf(file_wrapped,")\n{\n"); // generate the function body fprintf(file_wrapped,"\tuint64_t before, after;\n"); fprintf(file_wrapped,"\tif (trace_perfunc) {\n"); fprintf(file_wrapped,"\t\tprintf(\"gl%s\\n\");\n",func_name); for(i=0;i<=np;i++) { if (strcmp(nameparam[i],"UNUSED")==0) continue; fprintf(file_wrapped,"\t\tprintf(\"%s \",%s %s);\n",type_print(type[i]),type_cast(type[i]),nameparam[i]); } fprintf(file_wrapped, "\t\tprintf(\"\\n\");\n"); fprintf(file_wrapped, "\t}\n"); fprintf(file_wrapped,"\tbefore = gettime64();\n"); // " int ret = ((void*)(int,int,int))functable[123](a,b,c)" fprintf(file_wrapped, "\t"); if (type_match(return_type) != 0) fprintf(file_wrapped, "%s ret = ",return_type); fprintf(file_wrapped,"((%s (*)(",return_type); for(i=0;i<=np;i++) { if (strcmp(nameparam[i],"UNUSED")==0) continue; fprintf(file_wrapped,"%s,",type[i]); } if(np==-1) fprintf(file_wrapped,"void"); else fseek(file_wrapped,-1,SEEK_CUR); fprintf(file_wrapped,"))functable[%d])(",fnum); for(i=0;i<=np;i++) { if (strcmp(nameparam[i],"UNUSED")==0) continue; fprintf(file_wrapped,"%s,",nameparam[i]); } if(np!=-1) fseek(file_wrapped,-1,SEEK_CUR); fprintf(file_wrapped,");\n"); fprintf(file_wrapped,"\tafter = gettime64();\n"); fprintf(file_wrapped,"\tif (trace_perfunc) {\n"); fprintf(file_wrapped,"\t\tprintf(\"%%llu\\n\",(unsigned long long)(after - before));\n"); fprintf(file_wrapped, "\t}\n"); fprintf(file_wrapped,"\tif (trace_summary) {\n"); fprintf(file_wrapped,"\t\ttotal_time[%d] += (after - before);\n", fnum); fprintf(file_wrapped,"\t\ttotal_calls[%d] ++;\n", fnum); fprintf(file_wrapped, "\t}\n"); if (!strcmp(func_name,"DrawArrays")) fprintf(file_wrapped,"\tvertex_array_add(count, after - before);\n"); if (!strcmp(func_name,"DrawElements")) fprintf(file_wrapped,"\tvertex_array_add(count, after - before);\n"); if (!strcmp(func_name,"ArrayElement")) fprintf(file_wrapped,"\tvertex_array_add(1, after - before);\n"); if (type_match(return_type) != 0) fprintf(file_wrapped,"\treturn ret;\n"); fprintf(file_wrapped,"}\n\n"); // " {"glBlahBlah",123}," fprintf(file_getprocaddr, "\t{\"gl%s\",%d},\n",func_name,fnum); fnum++; }//fin if function cur = retour; cur = cur->next; } //fin while function }//fin if category cur = retourcategory; cur = cur->next; }//fin while final fprintf(file_getprocaddr, "};\n\n"); fprintf(file_getprocaddr, "static uint64_t total_time[%d];\n\n", fnum); fprintf(file_getprocaddr, "static uint64_t total_calls[%d];\n\n", fnum); fprintf(file_getprocaddr, "static int num_funcs = %d;\n\n", fnum); fprintf(file_functable,"}\n\n"); fclose(file_wrapped); fclose(file_functable); fclose(file_getprocaddr); free(return_type); free(buffer); for(i=0;i<50;i++) free(type[i]); int r = system("cat prologue.c functable.c getprocaddr.c wrapped.c epilogue.c > main.c"); r = system("rm -f functable.c getprocaddr.c wrapped.c"); return; }