• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include "spec.h"
3 #include <stdio.h>
4 
printFileHeader(FILE * f)5 void printFileHeader(FILE *f) {
6     fprintf(f, "/*\n");
7     fprintf(f, " * Copyright (C) 2011 The Android Open Source Project\n");
8     fprintf(f, " *\n");
9     fprintf(f, " * Licensed under the Apache License, Version 2.0 (the \"License\");\n");
10     fprintf(f, " * you may not use this file except in compliance with the License.\n");
11     fprintf(f, " * You may obtain a copy of the License at\n");
12     fprintf(f, " *\n");
13     fprintf(f, " *      http://www.apache.org/licenses/LICENSE-2.0\n");
14     fprintf(f, " *\n");
15     fprintf(f, " * Unless required by applicable law or agreed to in writing, software\n");
16     fprintf(f, " * distributed under the License is distributed on an \"AS IS\" BASIS,\n");
17     fprintf(f, " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n");
18     fprintf(f, " * See the License for the specific language governing permissions and\n");
19     fprintf(f, " * limitations under the License.\n");
20     fprintf(f, " */\n\n");
21 }
22 
printVarType(FILE * f,const VarType * vt)23 void printVarType(FILE *f, const VarType *vt) {
24     int ct;
25     if (vt->isConst) {
26         fprintf(f, "const ");
27     }
28 
29     switch (vt->type) {
30     case 0:
31         fprintf(f, "void");
32         break;
33     case 1:
34         fprintf(f, "int%i_t", vt->bits);
35         break;
36     case 2:
37         fprintf(f, "uint%i_t", vt->bits);
38         break;
39     case 3:
40         if (vt->bits == 32)
41             fprintf(f, "float");
42         else
43             fprintf(f, "double");
44         break;
45     case 4:
46         fprintf(f, "%s", vt->typeName);
47         break;
48     }
49 
50     if (vt->ptrLevel) {
51         fprintf(f, " ");
52         for (ct=0; ct < vt->ptrLevel; ct++) {
53             fprintf(f, "*");
54         }
55     }
56 }
57 
printVarTypeAndName(FILE * f,const VarType * vt)58 void printVarTypeAndName(FILE *f, const VarType *vt) {
59     printVarType(f, vt);
60 
61     if (vt->name[0]) {
62         fprintf(f, " %s", vt->name);
63     }
64 }
65 
printArgList(FILE * f,const ApiEntry * api,int assumePrevious)66 void printArgList(FILE *f, const ApiEntry * api, int assumePrevious) {
67     int ct;
68     for (ct=0; ct < api->paramCount; ct++) {
69         if (ct || assumePrevious) {
70             fprintf(f, ", ");
71         }
72         printVarTypeAndName(f, &api->params[ct]);
73     }
74 }
75 
printStructures(FILE * f)76 void printStructures(FILE *f) {
77     int ct;
78     int ct2;
79 
80     for (ct=0; ct < apiCount; ct++) {
81         fprintf(f, "typedef struct RS_CMD_%s_rec RS_CMD_%s;\n", apis[ct].name, apis[ct].name);
82     }
83     fprintf(f, "\n");
84 
85     for (ct=0; ct < apiCount; ct++) {
86         const ApiEntry * api = &apis[ct];
87         fprintf(f, "#define RS_CMD_ID_%s %i\n", api->name, ct+1);
88         fprintf(f, "struct RS_CMD_%s_rec {\n", api->name);
89         //fprintf(f, "    RsCommandHeader _hdr;\n");
90 
91         for (ct2=0; ct2 < api->paramCount; ct2++) {
92             fprintf(f, "    ");
93             printVarTypeAndName(f, &api->params[ct2]);
94             fprintf(f, ";\n");
95         }
96         fprintf(f, "};\n\n");
97     }
98 }
99 
printFuncDecl(FILE * f,const ApiEntry * api,const char * prefix,int addContext,int isFnPtr)100 void printFuncDecl(FILE *f, const ApiEntry *api, const char *prefix, int addContext, int isFnPtr) {
101     printVarTypeAndName(f, &api->ret);
102     if (isFnPtr) {
103         char t[1024];
104         strcpy(t, api->name);
105         if (strlen(prefix) == 0) {
106             if (t[0] > 'A' && t[0] < 'Z') {
107                 t[0] -= 'A' - 'a';
108             }
109         }
110         fprintf(f, " (* %s%s) (", prefix, api->name);
111     } else {
112         fprintf(f, " %s%s (", prefix, api->name);
113     }
114     if (!api->nocontext) {
115         if (addContext) {
116             fprintf(f, "Context *");
117         } else {
118             fprintf(f, "RsContext rsc");
119         }
120     }
121     printArgList(f, api, !api->nocontext);
122     fprintf(f, ")");
123 }
124 
printFuncDecls(FILE * f,const char * prefix,int addContext)125 void printFuncDecls(FILE *f, const char *prefix, int addContext) {
126     int ct;
127     for (ct=0; ct < apiCount; ct++) {
128         printFuncDecl(f, &apis[ct], prefix, addContext, 0);
129         fprintf(f, ";\n");
130     }
131     fprintf(f, "\n\n");
132 }
133 
printFuncPointers(FILE * f,int addContext)134 void printFuncPointers(FILE *f, int addContext) {
135     fprintf(f, "\n");
136     fprintf(f, "typedef struct RsApiEntrypoints {\n");
137     int ct;
138     for (ct=0; ct < apiCount; ct++) {
139         fprintf(f, "    ");
140         printFuncDecl(f, &apis[ct], "", addContext, 1);
141         fprintf(f, ";\n");
142     }
143     fprintf(f, "} RsApiEntrypoints_t;\n\n");
144 }
145 
printPlaybackFuncs(FILE * f,const char * prefix)146 void printPlaybackFuncs(FILE *f, const char *prefix) {
147     int ct;
148     for (ct=0; ct < apiCount; ct++) {
149         if (apis[ct].direct) {
150             continue;
151         }
152 
153         fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name);
154     }
155 }
156 
hasInlineDataPointers(const ApiEntry * api)157 static int hasInlineDataPointers(const ApiEntry * api) {
158     int ret = 0;
159     int ct;
160     if (api->sync || api->ret.typeName[0]) {
161         return 0;
162     }
163     for (ct=0; ct < api->paramCount; ct++) {
164         const VarType *vt = &api->params[ct];
165 
166         if (!vt->isConst && vt->ptrLevel) {
167             // Non-const pointers cannot be inlined.
168             return 0;
169         }
170         if (vt->ptrLevel > 1) {
171             // not handled yet.
172             return 0;
173         }
174 
175         if (vt->isConst && vt->ptrLevel) {
176             // Non-const pointers cannot be inlined.
177             ret = 1;
178         }
179     }
180     return ret;
181 }
182 
printApiCpp(FILE * f)183 void printApiCpp(FILE *f) {
184     int ct;
185     int ct2;
186 
187     fprintf(f, "#include \"rsDevice.h\"\n");
188     fprintf(f, "#include \"rsContext.h\"\n");
189     fprintf(f, "#include \"rsThreadIO.h\"\n");
190     fprintf(f, "#include \"rsgApiStructs.h\"\n");
191     fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
192     fprintf(f, "#include \"rsFifo.h\"\n");
193     fprintf(f, "\n");
194     fprintf(f, "using namespace android;\n");
195     fprintf(f, "using namespace android::renderscript;\n");
196     fprintf(f, "\n");
197 
198     printFuncPointers(f, 0);
199 
200     // Generate RS funcs for local fifo
201     for (ct=0; ct < apiCount; ct++) {
202         int needFlush = 0;
203         const ApiEntry * api = &apis[ct];
204 
205         fprintf(f, "static ");
206         printFuncDecl(f, api, "LF_", 0, 0);
207         fprintf(f, "\n{\n");
208         if (api->direct) {
209             fprintf(f, "    ");
210             if (api->ret.typeName[0]) {
211                 fprintf(f, "return ");
212             }
213             fprintf(f, "rsi_%s(", api->name);
214             if (!api->nocontext) {
215                 fprintf(f, "(Context *)rsc");
216             }
217             for (ct2=0; ct2 < api->paramCount; ct2++) {
218                 const VarType *vt = &api->params[ct2];
219                 if (ct2 > 0 || !api->nocontext) {
220                     fprintf(f, ", ");
221                 }
222                 fprintf(f, "%s", vt->name);
223             }
224             fprintf(f, ");\n");
225         } else {
226             fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
227             fprintf(f, "    const uint32_t size = sizeof(RS_CMD_%s);\n", api->name);
228             if (hasInlineDataPointers(api)) {
229                 fprintf(f, "    uint32_t dataSize = 0;\n");
230                 for (ct2=0; ct2 < api->paramCount; ct2++) {
231                     const VarType *vt = &api->params[ct2];
232                     if (vt->isConst && vt->ptrLevel) {
233                         fprintf(f, "    dataSize += %s_length;\n", vt->name);
234                     }
235                 }
236             }
237 
238             //fprintf(f, "    ALOGE(\"add command %s\\n\");\n", api->name);
239             if (hasInlineDataPointers(api)) {
240                 fprintf(f, "    RS_CMD_%s *cmd = NULL;\n", api->name);
241                 fprintf(f, "    if (dataSize < io->getMaxInlineSize()) {;\n");
242                 fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name);
243                 fprintf(f, "    } else {\n");
244                 fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name);
245                 fprintf(f, "    }\n");
246                 fprintf(f, "    uint8_t *payload = (uint8_t *)&cmd[1];\n");
247             } else {
248                 fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name, api->name);
249             }
250 
251             for (ct2=0; ct2 < api->paramCount; ct2++) {
252                 const VarType *vt = &api->params[ct2];
253                 needFlush += vt->ptrLevel;
254                 if (vt->ptrLevel && hasInlineDataPointers(api)) {
255                     fprintf(f, "    if (dataSize < io->getMaxInlineSize()) {\n");
256                     fprintf(f, "        memcpy(payload, %s, %s_length);\n", vt->name, vt->name);
257                     fprintf(f, "        cmd->%s = (", vt->name);
258                     printVarType(f, vt);
259                     fprintf(f, ")(payload - ((uint8_t *)&cmd[1]));\n");
260                     fprintf(f, "        payload += %s_length;\n", vt->name);
261                     fprintf(f, "    } else {\n");
262                     fprintf(f, "        cmd->%s = %s;\n", vt->name, vt->name);
263                     fprintf(f, "    }\n");
264 
265                 } else {
266                     fprintf(f, "    cmd->%s = %s;\n", vt->name, vt->name);
267                 }
268             }
269             if (api->ret.typeName[0] || api->sync) {
270                 needFlush = 1;
271             }
272 
273             fprintf(f, "    io->coreCommit();\n");
274             if (hasInlineDataPointers(api)) {
275                 fprintf(f, "    if (dataSize >= io->getMaxInlineSize()) {\n");
276                 fprintf(f, "        io->coreGetReturn(NULL, 0);\n");
277                 fprintf(f, "    }\n");
278             } else if (api->ret.typeName[0]) {
279                 fprintf(f, "\n    ");
280                 printVarType(f, &api->ret);
281                 fprintf(f, " ret;\n");
282                 fprintf(f, "    io->coreGetReturn(&ret, sizeof(ret));\n");
283                 fprintf(f, "    return ret;\n");
284             } else if (needFlush) {
285                 fprintf(f, "    io->coreGetReturn(NULL, 0);\n");
286             }
287         }
288         fprintf(f, "};\n\n");
289 
290 
291         // Generate a remote sender function
292         const char * str = "core";
293         if (api->direct) {
294             str = "async";
295         }
296 
297         fprintf(f, "static ");
298         printFuncDecl(f, api, "RF_", 0, 0);
299         fprintf(f, "\n{\n");
300         fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
301         fprintf(f, "    const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
302         fprintf(f, "    io->%sWrite(&cmdID, sizeof(cmdID));\n\n", str);
303 
304         for (ct2=0; ct2 < api->paramCount; ct2++) {
305             const VarType *vt = &api->params[ct2];
306             if (vt->ptrLevel == 0) {
307                 fprintf(f, "    io->%sWrite(& %s, sizeof(%s));\n", str, vt->name, vt->name);
308             }
309         }
310         fprintf(f, "\n");
311 
312         for (ct2=0; ct2 < api->paramCount; ct2++) {
313             const VarType *vt = &api->params[ct2];
314             if ((vt->ptrLevel == 1) && (vt->isConst)) {
315                 fprintf(f, "    io->%sWrite(%s, %s_length);\n", str, vt->name, vt->name);
316             }
317         }
318         fprintf(f, "\n");
319 
320         for (ct2=0; ct2 < api->paramCount; ct2++) {
321             const VarType *vt = &api->params[ct2];
322             if ((vt->ptrLevel == 2) && (vt->isConst)) {
323                 fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
324                 fprintf(f, "        io->%sWrite(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
325                 fprintf(f, "    }\n");
326             }
327         }
328         fprintf(f, "\n");
329 
330         for (ct2=0; ct2 < api->paramCount; ct2++) {
331             const VarType *vt = &api->params[ct2];
332             if ((vt->ptrLevel == 1) && (!vt->isConst)) {
333                 fprintf(f, "    io->%sGetReturn(%s, %s_length);\n", str, vt->name, vt->name);
334             }
335         }
336         fprintf(f, "\n");
337 
338         for (ct2=0; ct2 < api->paramCount; ct2++) {
339             const VarType *vt = &api->params[ct2];
340             if ((vt->ptrLevel == 2) && (!vt->isConst)) {
341                 fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
342                 fprintf(f, "        io->%sGetReturn(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
343                 fprintf(f, "    }\n");
344             }
345         }
346         fprintf(f, "\n");
347 
348         if (api->ret.typeName[0]) {
349             fprintf(f, "    ");
350             printVarType(f, &api->ret);
351             fprintf(f, " retValue;\n");
352             fprintf(f, "    io->%sGetReturn(&retValue, sizeof(retValue));\n", str);
353             fprintf(f, "    return retValue;\n");
354         } else /*if (api->sync)*/ {
355             fprintf(f, "    io->%sGetReturn(NULL, 0);\n", str);
356         }
357         fprintf(f, "}\n\n");
358     }
359 
360     fprintf(f, "\n");
361     fprintf(f, "static RsApiEntrypoints_t s_LocalTable = {\n");
362     for (ct=0; ct < apiCount; ct++) {
363         fprintf(f, "    LF_%s,\n", apis[ct].name);
364     }
365     fprintf(f, "};\n");
366 
367     fprintf(f, "\n");
368     fprintf(f, "static RsApiEntrypoints_t s_RemoteTable = {\n");
369     for (ct=0; ct < apiCount; ct++) {
370         fprintf(f, "    RF_%s,\n", apis[ct].name);
371     }
372     fprintf(f, "};\n");
373 
374     fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
375     for (ct=0; ct < apiCount; ct++) {
376         int needFlush = 0;
377         const ApiEntry * api = &apis[ct];
378 
379         printFuncDecl(f, api, "rs", 0, 0);
380         fprintf(f, "\n{\n");
381         fprintf(f, "    ");
382         if (api->ret.typeName[0]) {
383             fprintf(f, "return ");
384         }
385         fprintf(f, "s_CurrentTable->%s(", api->name);
386 
387         if (!api->nocontext) {
388             fprintf(f, "(Context *)rsc");
389         }
390 
391         for (ct2=0; ct2 < api->paramCount; ct2++) {
392             const VarType *vt = &api->params[ct2];
393             if (ct2 > 0 || !api->nocontext) {
394                 fprintf(f, ", ");
395             }
396             fprintf(f, "%s", vt->name);
397         }
398         fprintf(f, ");\n");
399         fprintf(f, "}\n\n");
400     }
401 
402 }
403 
printPlaybackCpp(FILE * f)404 void printPlaybackCpp(FILE *f) {
405     int ct;
406     int ct2;
407 
408     fprintf(f, "#include \"rsDevice.h\"\n");
409     fprintf(f, "#include \"rsContext.h\"\n");
410     fprintf(f, "#include \"rsThreadIO.h\"\n");
411     fprintf(f, "#include \"rsgApiStructs.h\"\n");
412     fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
413     fprintf(f, "\n");
414     fprintf(f, "namespace android {\n");
415     fprintf(f, "namespace renderscript {\n");
416     fprintf(f, "\n");
417 
418     for (ct=0; ct < apiCount; ct++) {
419         const ApiEntry * api = &apis[ct];
420         int needFlush = 0;
421 
422         if (api->direct) {
423             continue;
424         }
425 
426         fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
427         fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
428 
429         if (hasInlineDataPointers(api)) {
430             fprintf(f, "    const uint8_t *baseData = 0;\n");
431             fprintf(f, "    if (cmdSizeBytes != sizeof(RS_CMD_%s)) {\n", api->name);
432             fprintf(f, "        baseData = &((const uint8_t *)vp)[sizeof(*cmd)];\n");
433             fprintf(f, "    }\n");
434         }
435 
436         fprintf(f, "    ");
437         if (api->ret.typeName[0]) {
438             fprintf(f, "\n    ");
439             printVarType(f, &api->ret);
440             fprintf(f, " ret = ");
441         }
442         fprintf(f, "rsi_%s(con", api->name);
443         for (ct2=0; ct2 < api->paramCount; ct2++) {
444             const VarType *vt = &api->params[ct2];
445             needFlush += vt->ptrLevel;
446 
447             if (hasInlineDataPointers(api) && vt->ptrLevel) {
448                 fprintf(f, ",\n           (const %s *)&baseData[(intptr_t)cmd->%s]", vt->typeName, vt->name);
449             } else {
450                 fprintf(f, ",\n           cmd->%s", vt->name);
451             }
452         }
453         fprintf(f, ");\n");
454 
455         if (hasInlineDataPointers(api)) {
456             fprintf(f, "    size_t totalSize = 0;\n");
457             for (ct2=0; ct2 < api->paramCount; ct2++) {
458                 if (api->params[ct2].ptrLevel) {
459                     fprintf(f, "    totalSize += cmd->%s_length;\n", api->params[ct2].name);
460                 }
461             }
462 
463             fprintf(f, "    if ((totalSize != 0) && (cmdSizeBytes == sizeof(RS_CMD_%s))) {\n", api->name);
464             fprintf(f, "        con->mIO.coreSetReturn(NULL, 0);\n");
465             fprintf(f, "    }\n");
466         } else if (api->ret.typeName[0]) {
467             fprintf(f, "    con->mIO.coreSetReturn(&ret, sizeof(ret));\n");
468         } else if (api->sync || needFlush) {
469             fprintf(f, "    con->mIO.coreSetReturn(NULL, 0);\n");
470         }
471 
472         fprintf(f, "};\n\n");
473     }
474 
475     for (ct=0; ct < apiCount; ct++) {
476         const ApiEntry * api = &apis[ct];
477         int needFlush = 0;
478 
479         fprintf(f, "void rspr_%s(Context *con, ThreadIO *io) {\n", api->name);
480         fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
481 
482         for (ct2=0; ct2 < api->paramCount; ct2++) {
483             const VarType *vt = &api->params[ct2];
484             if (vt->ptrLevel == 0) {
485                 fprintf(f, "    io->coreRead(&cmd.%s, sizeof(cmd.%s));\n", vt->name, vt->name);
486             }
487         }
488         fprintf(f, "\n");
489 
490         for (ct2=0; ct2 < api->paramCount; ct2++) {
491             const VarType *vt = &api->params[ct2];
492             if (vt->ptrLevel == 1) {
493                 fprintf(f, "    cmd.%s = (", vt->name);
494                 printVarType(f, vt);
495                 fprintf(f, ")malloc(cmd.%s_length);\n", vt->name);
496 
497                 if (vt->isConst) {
498                     fprintf(f, "    if (cmd.%s_length) io->coreRead((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name, vt->name);
499                 }
500             }
501         }
502         fprintf(f, "\n");
503 
504         for (ct2=0; ct2 < api->paramCount; ct2++) {
505             const VarType *vt = &api->params[ct2];
506             if (vt->ptrLevel == 2) {
507                 fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
508                 fprintf(f, "        cmd.%s = (", vt->name);
509                 printVarType(f, vt);
510                 fprintf(f, ")malloc(cmd.%s_length[ct]);\n", vt->name);
511                 fprintf(f, "        io->coreRead(& cmd.%s, cmd.%s_length[ct]);\n", vt->name, vt->name);
512                 fprintf(f, "    }\n");
513             }
514         }
515         fprintf(f, "\n");
516 
517         if (api->ret.typeName[0]) {
518             fprintf(f, "    ");
519             printVarType(f, &api->ret);
520             fprintf(f, " ret =\n");
521         }
522 
523         fprintf(f, "    rsi_%s(", api->name);
524         if (!api->nocontext) {
525             fprintf(f, "con");
526         }
527         for (ct2=0; ct2 < api->paramCount; ct2++) {
528             const VarType *vt = &api->params[ct2];
529             if (ct2 > 0 || !api->nocontext) {
530                 fprintf(f, ",\n");
531             }
532             fprintf(f, "           cmd.%s", vt->name);
533         }
534         fprintf(f, ");\n");
535 
536         for (ct2=0; ct2 < api->paramCount; ct2++) {
537             const VarType *vt = &api->params[ct2];
538             if ((vt->ptrLevel == 1) && (!vt->isConst)) {
539                 fprintf(f, "    io->coreSetReturn((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name);
540             }
541         }
542 
543         for (ct2=0; ct2 < api->paramCount; ct2++) {
544             const VarType *vt = &api->params[ct2];
545             if ((vt->ptrLevel == 2) && (!vt->isConst)) {
546                 fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
547                 fprintf(f, "        io->coreSetReturn((void *)cmd.%s[ct], cmd.%s_length[ct]);\n", vt->name, vt->name);
548                 fprintf(f, "    }\n");
549             }
550         }
551         fprintf(f, "\n");
552 
553         if (api->ret.typeName[0]) {
554             fprintf(f, "    io->coreSetReturn(&ret, sizeof(ret));\n");
555         } else /*if (needFlush)*/ {
556             fprintf(f, "    io->coreSetReturn(NULL, 0);\n");
557         }
558 
559         for (ct2=0; ct2 < api->paramCount; ct2++) {
560             const VarType *vt = &api->params[ct2];
561             if (vt->ptrLevel == 1) {
562                 fprintf(f, "    free((void *)cmd.%s);\n", vt->name);
563             }
564         }
565         for (ct2=0; ct2 < api->paramCount; ct2++) {
566             const VarType *vt = &api->params[ct2];
567             if (vt->ptrLevel == 2) {
568                 fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
569                 fprintf(f, "        free((void *)cmd.%s);\n", vt->name);
570                 fprintf(f, "    }\n");
571             }
572         }
573 
574         fprintf(f, "};\n\n");
575     }
576 
577     fprintf(f, "RsPlaybackLocalFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
578     fprintf(f, "    NULL,\n");
579     for (ct=0; ct < apiCount; ct++) {
580         if (apis[ct].direct) {
581             fprintf(f, "    NULL,\n");
582         } else {
583             fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
584         }
585     }
586     fprintf(f, "};\n");
587 
588     fprintf(f, "RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i] = {\n", apiCount + 1);
589     fprintf(f, "    NULL,\n");
590     for (ct=0; ct < apiCount; ct++) {
591         fprintf(f, "    %s%s,\n", "rspr_", apis[ct].name);
592     }
593     fprintf(f, "};\n");
594 
595     fprintf(f, "};\n");
596     fprintf(f, "};\n");
597 }
598 
599 void yylex();
600 
main(int argc,char ** argv)601 int main(int argc, char **argv) {
602     if (argc != 3) {
603         fprintf(stderr, "usage: %s commandFile outFile\n", argv[0]);
604         return 1;
605     }
606     const char* rsgFile = argv[1];
607     const char* outFile = argv[2];
608     FILE* input = fopen(rsgFile, "r");
609 
610     char choice = fgetc(input);
611     fclose(input);
612 
613     if (choice < '0' || choice > '3') {
614         fprintf(stderr, "Uknown command: \'%c\'\n", choice);
615         return -2;
616     }
617 
618     yylex();
619     // printf("# of lines = %d\n", num_lines);
620 
621     FILE *f = fopen(outFile, "w");
622 
623     printFileHeader(f);
624     switch (choice) {
625         case '0': // rsgApiStructs.h
626         {
627             fprintf(f, "\n");
628             fprintf(f, "#include \"rsContext.h\"\n");
629             fprintf(f, "#include \"rsFifo.h\"\n");
630             fprintf(f, "\n");
631             fprintf(f, "namespace android {\n");
632             fprintf(f, "namespace renderscript {\n");
633             printStructures(f);
634             printFuncDecls(f, "rsi_", 1);
635             printPlaybackFuncs(f, "rsp_");
636             fprintf(f, "\n\ntypedef struct RsPlaybackRemoteHeaderRec {\n");
637             fprintf(f, "    uint32_t command;\n");
638             fprintf(f, "    uint32_t size;\n");
639             fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
640             fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
641             fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, ThreadIO *);\n");
642             fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
643             fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
644 
645             fprintf(f, "}\n");
646             fprintf(f, "}\n");
647         }
648         break;
649 
650         case '1': // rsgApiFuncDecl.h
651         {
652             printFuncDecls(f, "rs", 0);
653         }
654         break;
655 
656         case '2': // rsgApi.cpp
657         {
658             printApiCpp(f);
659         }
660         break;
661 
662         case '3': // rsgApiReplay.cpp
663         {
664             printFileHeader(f);
665             printPlaybackCpp(f);
666         }
667         break;
668 
669         case '4': // rsgApiStream.cpp
670         {
671             printFileHeader(f);
672             printPlaybackCpp(f);
673         }
674 
675         case '5': // rsgApiStreamReplay.cpp
676         {
677             printFileHeader(f);
678             printPlaybackCpp(f);
679         }
680         break;
681     }
682     fclose(f);
683     return 0;
684 }
685