• 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 __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 
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,int externC)126 void 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 
printFuncPointers(FILE * f,int addContext)138 void 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 
printPlaybackFuncs(FILE * f,const char * prefix)150 void 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 
hasInlineDataPointers(const ApiEntry * api)161 static 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 
printApiCpp(FILE * f)187 void 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 
printPlaybackCpp(FILE * f)448 void 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 
643 void yylex();
644 
main(int argc,char ** argv)645 int 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