Home | History | Annotate | Download | only in rs
      1 
      2 #include "spec.h"
      3 #include <stdio.h>
      4 #include <string.h>
      5 
      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 
     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 
     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 
     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 
     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 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 
    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 
    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 
    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 
    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 
    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 
    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 {
    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 
    433 void 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 
    628 void yylex();
    629 
    630 int 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