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