1
2#include "spec.h"
3#include <stdio.h>
4#include <string.h>
5
6void 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
24void 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
59void 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
67void 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
77void 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 __attribute__((packed)) 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
101void 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
126void printFuncDecls(FILE *f, const char *prefix, int addContext, int externC) {
127    int ct;
128    for (ct=0; ct < apiCount; ct++) {
129        if (externC) {
130            fprintf(f, "extern \"C\" ");
131        }
132        printFuncDecl(f, &apis[ct], prefix, addContext, 0);
133        fprintf(f, ";\n");
134    }
135    fprintf(f, "\n\n");
136}
137
138void printFuncPointers(FILE *f, int addContext) {
139    fprintf(f, "\n");
140    fprintf(f, "typedef struct RsApiEntrypoints {\n");
141    int ct;
142    for (ct=0; ct < apiCount; ct++) {
143        fprintf(f, "    ");
144        printFuncDecl(f, &apis[ct], "", addContext, 1);
145        fprintf(f, ";\n");
146    }
147    fprintf(f, "} RsApiEntrypoints_t;\n\n");
148}
149
150void printPlaybackFuncs(FILE *f, const char *prefix) {
151    int ct;
152    for (ct=0; ct < apiCount; ct++) {
153        if (apis[ct].direct) {
154            continue;
155        }
156
157        fprintf(f, "void %s%s (Context *, const void *);\n", prefix, apis[ct].name);
158    }
159}
160
161static int hasInlineDataPointers(const ApiEntry * api) {
162    int ret = 0;
163    int ct;
164    if (api->sync || api->ret.typeName[0]) {
165        return 0;
166    }
167    for (ct=0; ct < api->paramCount; ct++) {
168        const VarType *vt = &api->params[ct];
169
170        if (!vt->isConst && vt->ptrLevel) {
171            // Non-const pointers cannot be inlined.
172            return 0;
173        }
174        if (vt->ptrLevel > 1) {
175            // not handled yet.
176            return 0;
177        }
178
179        if (vt->isConst && vt->ptrLevel) {
180            // Non-const pointers cannot be inlined.
181            ret = 1;
182        }
183    }
184    return ret;
185}
186
187void printApiCpp(FILE *f) {
188    int ct;
189    int ct2;
190
191    fprintf(f, "#include \"rsDevice.h\"\n");
192    fprintf(f, "#include \"rsContext.h\"\n");
193    fprintf(f, "#include \"rsThreadIO.h\"\n");
194    fprintf(f, "#include \"rsgApiStructs.h\"\n");
195    fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
196    fprintf(f, "#include \"rsFifo.h\"\n");
197    fprintf(f, "\n");
198    fprintf(f, "using namespace android;\n");
199    fprintf(f, "using namespace android::renderscript;\n");
200    fprintf(f, "\n");
201
202    printFuncPointers(f, 0);
203
204    // Generate RS funcs for local fifo
205    for (ct=0; ct < apiCount; ct++) {
206        int needFlush = 0;
207        const ApiEntry * api = &apis[ct];
208
209        fprintf(f, "static ");
210        printFuncDecl(f, api, "LF_", 0, 0);
211        fprintf(f, "\n{\n");
212        if (api->direct) {
213            fprintf(f, "    ");
214            if (api->ret.typeName[0]) {
215                fprintf(f, "return ");
216            }
217            fprintf(f, "rsi_%s(", api->name);
218            if (!api->nocontext) {
219                fprintf(f, "(Context *)rsc");
220            }
221            for (ct2=0; ct2 < api->paramCount; ct2++) {
222                const VarType *vt = &api->params[ct2];
223                if (ct2 > 0 || !api->nocontext) {
224                    fprintf(f, ", ");
225                }
226                fprintf(f, "%s", vt->name);
227            }
228            fprintf(f, ");\n");
229        } else if (api->handcodeApi) {
230            // handle handcode path
231            fprintf(f, "    LF_%s_handcode(", api->name);
232            if (!api->nocontext) {
233                fprintf(f, "(Context *)rsc");
234            }
235            for (ct2=0; ct2 < api->paramCount; ct2++) {
236                const VarType *vt = &api->params[ct2];
237                if (ct2 > 0 || !api->nocontext) {
238                    fprintf(f, ", ");
239                }
240                fprintf(f, "%s", vt->name);
241            }
242            fprintf(f, ");\n");
243
244        } else {
245            // handle synchronous path
246            fprintf(f, "    if (((Context *)rsc)->isSynchronous()) {\n");
247            fprintf(f, "        ");
248            if (api->ret.typeName[0]) {
249                fprintf(f, "return ");
250            }
251            fprintf(f, "rsi_%s(", api->name);
252            if (!api->nocontext) {
253                fprintf(f, "(Context *)rsc");
254            }
255            for (ct2=0; ct2 < api->paramCount; ct2++) {
256                const VarType *vt = &api->params[ct2];
257                if (ct2 > 0 || !api->nocontext) {
258                    fprintf(f, ", ");
259                }
260                fprintf(f, "%s", vt->name);
261            }
262            fprintf(f, ");\n");
263            if (!api->ret.typeName[0]) {
264                fprintf(f, "    return;");
265            }
266            fprintf(f, "    }\n\n");
267
268            fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
269            fprintf(f, "    const size_t size = sizeof(RS_CMD_%s);\n", api->name);
270            if (hasInlineDataPointers(api)) {
271                fprintf(f, "    size_t dataSize = 0;\n");
272                for (ct2=0; ct2 < api->paramCount; ct2++) {
273                    const VarType *vt = &api->params[ct2];
274                    if (vt->isConst && vt->ptrLevel) {
275                        fprintf(f, "    dataSize += %s_length;\n", vt->name);
276                    }
277                }
278            }
279
280            //fprintf(f, "    ALOGE(\"add command %s\\n\");\n", api->name);
281            if (hasInlineDataPointers(api)) {
282                fprintf(f, "    RS_CMD_%s *cmd = NULL;\n", api->name);
283                fprintf(f, "    if (dataSize < io->getMaxInlineSize()) {;\n");
284                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name);
285                fprintf(f, "    } else {\n");
286                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name);
287                fprintf(f, "    }\n");
288                fprintf(f, "    uint8_t *payload = (uint8_t *)&cmd[1];\n");
289            } else {
290                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);
291            }
292
293            for (ct2=0; ct2 < api->paramCount; ct2++) {
294                const VarType *vt = &api->params[ct2];
295                needFlush += vt->ptrLevel;
296                if (vt->ptrLevel && hasInlineDataPointers(api)) {
297                    fprintf(f, "    if (dataSize < io->getMaxInlineSize()) {\n");
298                    fprintf(f, "        memcpy(payload, %s, %s_length);\n", vt->name, vt->name);
299                    fprintf(f, "        cmd->%s = (", vt->name);
300                    printVarType(f, vt);
301                    fprintf(f, ")(payload - ((uint8_t *)&cmd[1]));\n");
302                    fprintf(f, "        payload += %s_length;\n", vt->name);
303                    fprintf(f, "    } else {\n");
304                    fprintf(f, "        cmd->%s = %s;\n", vt->name, vt->name);
305                    fprintf(f, "    }\n");
306
307                } else {
308                    fprintf(f, "    cmd->%s = %s;\n", vt->name, vt->name);
309                }
310            }
311            if (api->ret.typeName[0] || api->sync) {
312                needFlush = 1;
313            }
314
315            fprintf(f, "    io->coreCommit();\n");
316            if (hasInlineDataPointers(api)) {
317                fprintf(f, "    if (dataSize >= io->getMaxInlineSize()) {\n");
318                fprintf(f, "        io->coreGetReturn(NULL, 0);\n");
319                fprintf(f, "    }\n");
320            } else if (api->ret.typeName[0]) {
321                fprintf(f, "\n    ");
322                printVarType(f, &api->ret);
323                fprintf(f, " ret;\n");
324                fprintf(f, "    io->coreGetReturn(&ret, sizeof(ret));\n");
325                fprintf(f, "    return ret;\n");
326            } else if (needFlush) {
327                fprintf(f, "    io->coreGetReturn(NULL, 0);\n");
328            }
329        }
330        fprintf(f, "};\n\n");
331
332
333        // Generate a remote sender function
334        const char * str = "core";
335        if (api->direct) {
336            str = "async";
337        }
338
339        fprintf(f, "static ");
340        printFuncDecl(f, api, "RF_", 0, 0);
341        fprintf(f, "\n{\n");
342        fprintf(f, "    ThreadIO *io = &((Context *)rsc)->mIO;\n");
343        fprintf(f, "    const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
344        fprintf(f, "    io->%sWrite(&cmdID, sizeof(cmdID));\n\n", str);
345
346        for (ct2=0; ct2 < api->paramCount; ct2++) {
347            const VarType *vt = &api->params[ct2];
348            if (vt->ptrLevel == 0) {
349                fprintf(f, "    io->%sWrite(& %s, sizeof(%s));\n", str, vt->name, vt->name);
350            }
351        }
352        fprintf(f, "\n");
353
354        for (ct2=0; ct2 < api->paramCount; ct2++) {
355            const VarType *vt = &api->params[ct2];
356            if ((vt->ptrLevel == 1) && (vt->isConst)) {
357                fprintf(f, "    io->%sWrite(%s, %s_length);\n", str, vt->name, vt->name);
358            }
359        }
360        fprintf(f, "\n");
361
362        for (ct2=0; ct2 < api->paramCount; ct2++) {
363            const VarType *vt = &api->params[ct2];
364            if ((vt->ptrLevel == 2) && (vt->isConst)) {
365                fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
366                fprintf(f, "        io->%sWrite(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
367                fprintf(f, "    }\n");
368            }
369        }
370        fprintf(f, "\n");
371
372        for (ct2=0; ct2 < api->paramCount; ct2++) {
373            const VarType *vt = &api->params[ct2];
374            if ((vt->ptrLevel == 1) && (!vt->isConst)) {
375                fprintf(f, "    io->%sGetReturn(%s, %s_length);\n", str, vt->name, vt->name);
376            }
377        }
378        fprintf(f, "\n");
379
380        for (ct2=0; ct2 < api->paramCount; ct2++) {
381            const VarType *vt = &api->params[ct2];
382            if ((vt->ptrLevel == 2) && (!vt->isConst)) {
383                fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
384                fprintf(f, "        io->%sGetReturn(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
385                fprintf(f, "    }\n");
386            }
387        }
388        fprintf(f, "\n");
389
390        if (api->ret.typeName[0]) {
391            fprintf(f, "    ");
392            printVarType(f, &api->ret);
393            fprintf(f, " retValue;\n");
394            fprintf(f, "    io->%sGetReturn(&retValue, sizeof(retValue));\n", str);
395            fprintf(f, "    return retValue;\n");
396        } else /*if (api->sync)*/ {
397            fprintf(f, "    io->%sGetReturn(NULL, 0);\n", str);
398        }
399        fprintf(f, "}\n\n");
400    }
401
402    fprintf(f, "\n");
403    fprintf(f, "static RsApiEntrypoints_t s_LocalTable = {\n");
404    for (ct=0; ct < apiCount; ct++) {
405        fprintf(f, "    LF_%s,\n", apis[ct].name);
406    }
407    fprintf(f, "};\n");
408
409    fprintf(f, "\n");
410    fprintf(f, "static RsApiEntrypoints_t s_RemoteTable = {\n");
411    for (ct=0; ct < apiCount; ct++) {
412        fprintf(f, "    RF_%s,\n", apis[ct].name);
413    }
414    fprintf(f, "};\n");
415
416    fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
417    for (ct=0; ct < apiCount; ct++) {
418        int needFlush = 0;
419        const ApiEntry * api = &apis[ct];
420
421        fprintf(f, "extern \"C\" ");
422
423        printFuncDecl(f, api, "rs", 0, 0);
424        fprintf(f, "\n{\n");
425        fprintf(f, "    ");
426        if (api->ret.typeName[0]) {
427            fprintf(f, "return ");
428        }
429        fprintf(f, "s_CurrentTable->%s(", api->name);
430
431        if (!api->nocontext) {
432            fprintf(f, "(Context *)rsc");
433        }
434
435        for (ct2=0; ct2 < api->paramCount; ct2++) {
436            const VarType *vt = &api->params[ct2];
437            if (ct2 > 0 || !api->nocontext) {
438                fprintf(f, ", ");
439            }
440            fprintf(f, "%s", vt->name);
441        }
442        fprintf(f, ");\n");
443        fprintf(f, "}\n\n");
444    }
445
446}
447
448void printPlaybackCpp(FILE *f) {
449    int ct;
450    int ct2;
451
452    fprintf(f, "#include \"rsDevice.h\"\n");
453    fprintf(f, "#include \"rsContext.h\"\n");
454    fprintf(f, "#include \"rsThreadIO.h\"\n");
455    fprintf(f, "#include \"rsgApiStructs.h\"\n");
456    fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
457    fprintf(f, "\n");
458    fprintf(f, "namespace android {\n");
459    fprintf(f, "namespace renderscript {\n");
460    fprintf(f, "\n");
461
462    for (ct=0; ct < apiCount; ct++) {
463        const ApiEntry * api = &apis[ct];
464        int needFlush = 0;
465
466        if (api->direct) {
467            continue;
468        }
469
470        fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
471        fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
472
473        if (hasInlineDataPointers(api)) {
474            fprintf(f, "    const uint8_t *baseData = 0;\n");
475            fprintf(f, "    if (cmdSizeBytes != sizeof(RS_CMD_%s)) {\n", api->name);
476            fprintf(f, "        baseData = &((const uint8_t *)vp)[sizeof(*cmd)];\n");
477            fprintf(f, "    }\n");
478        }
479
480        fprintf(f, "    ");
481        if (api->ret.typeName[0]) {
482            fprintf(f, "\n    ");
483            printVarType(f, &api->ret);
484            fprintf(f, " ret = ");
485        }
486        fprintf(f, "rsi_%s(con", api->name);
487        for (ct2=0; ct2 < api->paramCount; ct2++) {
488            const VarType *vt = &api->params[ct2];
489            needFlush += vt->ptrLevel;
490
491            if (hasInlineDataPointers(api) && vt->ptrLevel) {
492                fprintf(f, ",\n           (const %s *)&baseData[(intptr_t)cmd->%s]", vt->typeName, vt->name);
493            } else {
494                fprintf(f, ",\n           cmd->%s", vt->name);
495            }
496        }
497        fprintf(f, ");\n");
498
499        if (hasInlineDataPointers(api)) {
500            fprintf(f, "    size_t totalSize = 0;\n");
501            for (ct2=0; ct2 < api->paramCount; ct2++) {
502                if (api->params[ct2].ptrLevel) {
503                    fprintf(f, "    totalSize += cmd->%s_length;\n", api->params[ct2].name);
504                }
505            }
506
507            fprintf(f, "    if ((totalSize != 0) && (cmdSizeBytes == sizeof(RS_CMD_%s))) {\n", api->name);
508            fprintf(f, "        con->mIO.coreSetReturn(NULL, 0);\n");
509            fprintf(f, "    }\n");
510        } else if (api->ret.typeName[0]) {
511            fprintf(f, "    con->mIO.coreSetReturn(&ret, sizeof(ret));\n");
512        } else if (api->sync || needFlush) {
513            fprintf(f, "    con->mIO.coreSetReturn(NULL, 0);\n");
514        }
515
516        fprintf(f, "};\n\n");
517    }
518
519    for (ct=0; ct < apiCount; ct++) {
520        const ApiEntry * api = &apis[ct];
521        int needFlush = 0;
522
523        fprintf(f, "void rspr_%s(Context *con, ThreadIO *io) {\n", api->name);
524        fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
525
526        for (ct2=0; ct2 < api->paramCount; ct2++) {
527            const VarType *vt = &api->params[ct2];
528            if (vt->ptrLevel == 0) {
529                fprintf(f, "    io->coreRead(&cmd.%s, sizeof(cmd.%s));\n", vt->name, vt->name);
530            }
531        }
532        fprintf(f, "\n");
533
534        for (ct2=0; ct2 < api->paramCount; ct2++) {
535            const VarType *vt = &api->params[ct2];
536            if (vt->ptrLevel == 1) {
537                fprintf(f, "    cmd.%s = (", vt->name);
538                printVarType(f, vt);
539                fprintf(f, ")malloc(cmd.%s_length);\n", vt->name);
540
541                if (vt->isConst) {
542                    fprintf(f, "    if (cmd.%s_length) io->coreRead((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name, vt->name);
543                }
544            }
545        }
546        fprintf(f, "\n");
547
548        for (ct2=0; ct2 < api->paramCount; ct2++) {
549            const VarType *vt = &api->params[ct2];
550            if (vt->ptrLevel == 2) {
551                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
552                fprintf(f, "        cmd.%s = (", vt->name);
553                printVarType(f, vt);
554                fprintf(f, ")malloc(cmd.%s_length[ct]);\n", vt->name);
555                fprintf(f, "        io->coreRead(& cmd.%s, cmd.%s_length[ct]);\n", vt->name, vt->name);
556                fprintf(f, "    }\n");
557            }
558        }
559        fprintf(f, "\n");
560
561        if (api->ret.typeName[0]) {
562            fprintf(f, "    ");
563            printVarType(f, &api->ret);
564            fprintf(f, " ret =\n");
565        }
566
567        fprintf(f, "    rsi_%s(", api->name);
568        if (!api->nocontext) {
569            fprintf(f, "con");
570        }
571        for (ct2=0; ct2 < api->paramCount; ct2++) {
572            const VarType *vt = &api->params[ct2];
573            if (ct2 > 0 || !api->nocontext) {
574                fprintf(f, ",\n");
575            }
576            fprintf(f, "           cmd.%s", vt->name);
577        }
578        fprintf(f, ");\n");
579
580        for (ct2=0; ct2 < api->paramCount; ct2++) {
581            const VarType *vt = &api->params[ct2];
582            if ((vt->ptrLevel == 1) && (!vt->isConst)) {
583                fprintf(f, "    io->coreSetReturn((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name);
584            }
585        }
586
587        for (ct2=0; ct2 < api->paramCount; ct2++) {
588            const VarType *vt = &api->params[ct2];
589            if ((vt->ptrLevel == 2) && (!vt->isConst)) {
590                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
591                fprintf(f, "        io->coreSetReturn((void *)cmd.%s[ct], cmd.%s_length[ct]);\n", vt->name, vt->name);
592                fprintf(f, "    }\n");
593            }
594        }
595        fprintf(f, "\n");
596
597        if (api->ret.typeName[0]) {
598            fprintf(f, "    io->coreSetReturn(&ret, sizeof(ret));\n");
599        } else /*if (needFlush)*/ {
600            fprintf(f, "    io->coreSetReturn(NULL, 0);\n");
601        }
602
603        for (ct2=0; ct2 < api->paramCount; ct2++) {
604            const VarType *vt = &api->params[ct2];
605            if (vt->ptrLevel == 1) {
606                fprintf(f, "    free((void *)cmd.%s);\n", vt->name);
607            }
608        }
609        for (ct2=0; ct2 < api->paramCount; ct2++) {
610            const VarType *vt = &api->params[ct2];
611            if (vt->ptrLevel == 2) {
612                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
613                fprintf(f, "        free((void *)cmd.%s);\n", vt->name);
614                fprintf(f, "    }\n");
615            }
616        }
617
618        fprintf(f, "};\n\n");
619    }
620
621    fprintf(f, "RsPlaybackLocalFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
622    fprintf(f, "    NULL,\n");
623    for (ct=0; ct < apiCount; ct++) {
624        if (apis[ct].direct) {
625            fprintf(f, "    NULL,\n");
626        } else {
627            fprintf(f, "    %s%s,\n", "rsp_", apis[ct].name);
628        }
629    }
630    fprintf(f, "};\n");
631
632    fprintf(f, "RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i] = {\n", apiCount + 1);
633    fprintf(f, "    NULL,\n");
634    for (ct=0; ct < apiCount; ct++) {
635        fprintf(f, "    %s%s,\n", "rspr_", apis[ct].name);
636    }
637    fprintf(f, "};\n");
638
639    fprintf(f, "};\n");
640    fprintf(f, "};\n");
641}
642
643void yylex();
644
645int main(int argc, char **argv) {
646    if (argc != 3) {
647        fprintf(stderr, "usage: %s commandFile outFile\n", argv[0]);
648        return 1;
649    }
650    const char* rsgFile = argv[1];
651    const char* outFile = argv[2];
652    FILE* input = fopen(rsgFile, "r");
653
654    char choice = fgetc(input);
655    fclose(input);
656
657    if (choice < '0' || choice > '3') {
658        fprintf(stderr, "Uknown command: \'%c\'\n", choice);
659        return -2;
660    }
661
662    yylex();
663    // printf("# of lines = %d\n", num_lines);
664
665    FILE *f = fopen(outFile, "w");
666
667    printFileHeader(f);
668    switch (choice) {
669        case '0': // rsgApiStructs.h
670        {
671            fprintf(f, "\n");
672            fprintf(f, "#include \"rsContext.h\"\n");
673            fprintf(f, "#include \"rsFifo.h\"\n");
674            fprintf(f, "\n");
675            fprintf(f, "namespace android {\n");
676            fprintf(f, "namespace renderscript {\n");
677            printStructures(f);
678            printFuncDecls(f, "rsi_", 1, 0);
679            printPlaybackFuncs(f, "rsp_");
680            fprintf(f, "\n\ntypedef struct RsPlaybackRemoteHeaderRec {\n");
681            fprintf(f, "    uint32_t command;\n");
682            fprintf(f, "    size_t size;\n");
683            fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
684            fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
685            fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, ThreadIO *);\n");
686            fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
687            fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
688
689            fprintf(f, "}\n");
690            fprintf(f, "}\n");
691        }
692        break;
693
694        case '1': // rsgApiFuncDecl.h
695        {
696            printFuncDecls(f, "rs", 0, 1);
697        }
698        break;
699
700        case '2': // rsgApi.cpp
701        {
702            printApiCpp(f);
703        }
704        break;
705
706        case '3': // rsgApiReplay.cpp
707        {
708            printFileHeader(f);
709            printPlaybackCpp(f);
710        }
711        break;
712    }
713    fclose(f);
714    return 0;
715}
716