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