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