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