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