Add code for generating fifo command packing.

Change-Id: I2d2ef095344b200b10457de96ae1d85821edc91e
diff --git a/rsg_generator.c b/rsg_generator.c
index 1d8b9b5..d550712 100644
--- a/rsg_generator.c
+++ b/rsg_generator.c
@@ -189,6 +189,7 @@
     fprintf(f, "#include \"rsThreadIO.h\"\n");
     //fprintf(f, "#include \"rsgApiStructs.h\"\n");
     fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
+    fprintf(f, "#include \"rsFifo.h\"\n");
     fprintf(f, "\n");
     fprintf(f, "using namespace android;\n");
     fprintf(f, "using namespace android::renderscript;\n");
@@ -290,11 +291,103 @@
 
             if (api->ret.typeName[0]) {
                 fprintf(f, "    return reinterpret_cast<");
-                printVarTypeAndName(f, &api->ret);
+                printVarType(f, &api->ret);
                 fprintf(f, ">(io->mToCoreRet);\n");
             }
         }
         fprintf(f, "};\n\n");
+
+
+        fprintf(f, "static ");
+        printFuncDecl(f, api, "RF_", 0, 0);
+        fprintf(f, "\n{\n");
+        fprintf(f, "    Fifo *f = NULL;\n");
+        fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
+        fprintf(f, "    const uint32_t cmdSize = sizeof(cmd);\n");
+        fprintf(f, "    const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
+        fprintf(f, "    f->writeAsync(&cmdID, sizeof(cmdID));\n");
+
+        if (api->handcodeApi) {
+            fprintf(f, "    rsHCAPI_%s(rsc", api->name);
+            for (ct2=0; ct2 < api->paramCount; ct2++) {
+                const VarType *vt = &api->params[ct2];
+                if (ct2 > 0 || !api->nocontext) {
+                    fprintf(f, ", ");
+                }
+                fprintf(f, "%s", vt->name);
+            }
+            fprintf(f, ");\n");
+        } else {
+            fprintf(f, "    intptr_t offset = cmdSize;\n");
+            fprintf(f, "    uint32_t dataSize = 0;\n");
+            for (ct2=0; ct2 < api->paramCount; ct2++) {
+                const VarType *vt = &api->params[ct2];
+                if (vt->isConst && vt->ptrLevel) {
+                    switch(vt->ptrLevel) {
+                    case 1:
+                        fprintf(f, "    dataSize += %s_length;\n", vt->name);
+                        break;
+                    case 2:
+                        fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+                        fprintf(f, "        dataSize += %s_length[ct];\n", vt->name);
+                        fprintf(f, "    }\n");
+                        break;
+                    default:
+                        printf("pointer level not handled!!");
+                    }
+                }
+            }
+            fprintf(f, "\n");
+
+            for (ct2=0; ct2 < api->paramCount; ct2++) {
+                const VarType *vt = &api->params[ct2];
+                switch(vt->ptrLevel) {
+                case 0:
+                    fprintf(f, "    cmd.%s = %s;\n", vt->name, vt->name);
+                    break;
+                case 1:
+                    fprintf(f, "    cmd.%s = (", vt->name);
+                    printVarType(f, vt);
+                    fprintf(f, ")offset;\n");
+                    fprintf(f, "    offset += %s_length;\n", vt->name);
+                    break;
+                case 2:
+                    fprintf(f, "    cmd.%s = (", vt->name);
+                    printVarType(f, vt);
+                    fprintf(f, ")offset;\n");
+                    fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+                    fprintf(f, "        offset += %s_length[ct];\n", vt->name);
+                    fprintf(f, "    }\n");
+                    break;
+                default:
+                    printf("pointer level not handled!!");
+                }
+            }
+            fprintf(f, "\n");
+
+            fprintf(f, "    f->writeAsync(&cmd, cmdSize);\n");
+            for (ct2=0; ct2 < api->paramCount; ct2++) {
+                const VarType *vt = &api->params[ct2];
+                if (vt->ptrLevel == 1) {
+                    fprintf(f, "    f->writeAsync(%s, %s_length);\n", vt->name, vt->name);
+                }
+                if (vt->ptrLevel == 2) {
+                    fprintf(f, "    for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+                    fprintf(f, "        f->writeAsync(%s, %s_length[ct]);\n", vt->name, vt->name);
+                    fprintf(f, "        offset += %s_length[ct];\n", vt->name);
+                    fprintf(f, "    }\n");
+                }
+            }
+
+            if (api->ret.typeName[0]) {
+                fprintf(f, "    ");
+                printVarType(f, &api->ret);
+                fprintf(f, " retValue;\n");
+                fprintf(f, "    f->writeWaitReturn(&retValue, sizeof(retValue));\n");
+                fprintf(f, "    return retValue;\n");
+            }
+        }
+        fprintf(f, "}\n\n");
     }
 
     fprintf(f, "\n");
@@ -304,8 +397,14 @@
     }
     fprintf(f, "};\n");
 
-    fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
+    fprintf(f, "\n");
+    fprintf(f, "static RsApiEntrypoints_t s_RemoteTable = {\n");
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    RF_%s,\n", apis[ct].name);
+    }
+    fprintf(f, "};\n");
 
+    fprintf(f, "static RsApiEntrypoints_t *s_CurrentTable = &s_LocalTable;\n\n");
     for (ct=0; ct < apiCount; ct++) {
         int needFlush = 0;
         const ApiEntry * api = &apis[ct];
@@ -357,8 +456,7 @@
             continue;
         }
 
-        fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes)\n", api->name);
-        fprintf(f, "{\n");
+        fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
 
         //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
         fprintf(f, "    const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
@@ -377,7 +475,63 @@
         fprintf(f, "};\n\n");
     }
 
-    fprintf(f, "RsPlaybackFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
+    for (ct=0; ct < apiCount; ct++) {
+        const ApiEntry * api = &apis[ct];
+
+        fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name);
+
+        //fprintf(f, "    LOGE(\"play command %s\\n\");\n", api->name);
+        fprintf(f, "    RS_CMD_%s cmd;\n", api->name);
+        fprintf(f, "    f->read(&cmd, sizeof(cmd));\n");
+
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (vt->ptrLevel == 1) {
+                fprintf(f, "    cmd.%s = (", vt->name);
+                printVarType(f, vt);
+                fprintf(f, ")scratch;\n");
+                fprintf(f, "    f->read(scratch, cmd.%s_length);\n", vt->name);
+                fprintf(f, "    scratch += cmd.%s_length;\n", vt->name);
+            }
+            if (vt->ptrLevel == 2) {
+                fprintf(f, "    size_t sum_%s = 0;\n", vt->name);
+                fprintf(f, "    for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
+                fprintf(f, "        ((size_t *)scratch)[ct] = cmd.%s_length[ct];\n", vt->name);
+                fprintf(f, "        sum_%s += cmd.%s_length[ct];\n", vt->name, vt->name);
+                fprintf(f, "    }\n");
+                fprintf(f, "    f->read(scratch, sum_%s);\n", vt->name);
+                fprintf(f, "    scratch += sum_%s;\n", vt->name);
+            }
+        }
+        fprintf(f, "\n");
+
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    ");
+            printVarType(f, &api->ret);
+            fprintf(f, " ret =\n");
+        }
+
+        fprintf(f, "    rsi_%s(", api->name);
+        if (!api->nocontext) {
+            fprintf(f, "con");
+        }
+        for (ct2=0; ct2 < api->paramCount; ct2++) {
+            const VarType *vt = &api->params[ct2];
+            if (ct2 > 0 || !api->nocontext) {
+                fprintf(f, ",\n");
+            }
+            fprintf(f, "           cmd.%s", vt->name);
+        }
+        fprintf(f, ");\n");
+
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    f->readReturn(&ret, sizeof(ret));\n");
+        }
+
+        fprintf(f, "};\n\n");
+    }
+
+    fprintf(f, "RsPlaybackLocalFunc gPlaybackFuncs[%i] = {\n", apiCount + 1);
     fprintf(f, "    NULL,\n");
     for (ct=0; ct < apiCount; ct++) {
         if (apis[ct].direct) {
@@ -388,6 +542,13 @@
     }
     fprintf(f, "};\n");
 
+    fprintf(f, "RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i] = {\n", apiCount + 1);
+    fprintf(f, "    NULL,\n");
+    for (ct=0; ct < apiCount; ct++) {
+        fprintf(f, "    %s%s,\n", "rspr_", apis[ct].name);
+    }
+    fprintf(f, "};\n");
+
     fprintf(f, "};\n");
     fprintf(f, "};\n");
 }
@@ -422,14 +583,21 @@
         {
             fprintf(f, "\n");
             fprintf(f, "#include \"rsContext.h\"\n");
+            fprintf(f, "#include \"rsFifo.h\"\n");
             fprintf(f, "\n");
             fprintf(f, "namespace android {\n");
             fprintf(f, "namespace renderscript {\n");
             printStructures(f);
             printFuncDecls(f, "rsi_", 1);
             printPlaybackFuncs(f, "rsp_");
-            fprintf(f, "\n\ntypedef void (*RsPlaybackFunc)(Context *, const void *, size_t sizeBytes);\n");
-            fprintf(f, "extern RsPlaybackFunc gPlaybackFuncs[%i];\n", apiCount + 1);
+            fprintf(f, "\n\ntypedef struct RsPlaybackRemoteHeaderRec {\n");
+            fprintf(f, "    uint32_t command;\n");
+            fprintf(f, "    uint32_t size;\n");
+            fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
+            fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
+            fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, Fifo *, uint8_t *scratch, size_t scratchSize);\n");
+            fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
+            fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
 
             fprintf(f, "}\n");
             fprintf(f, "}\n");