Core to client fifo on sockets.

Change-Id: I3b84a7d4c3c5fa0d764ad4db22dfd142d5cfa95b
diff --git a/rs.spec b/rs.spec
index 1da00a5..29de5f0 100644
--- a/rs.spec
+++ b/rs.spec
@@ -45,16 +45,14 @@
     direct
     param void *data
     param size_t *receiveLen
-    param uint32_t *subID
-    param bool wait
+    param uint32_t *usrID
     ret RsMessageToClientType
 }
 
 ContextPeekMessage {
     direct
     param size_t *receiveLen
-    param uint32_t *subID
-    param bool wait
+    param uint32_t *usrID
     ret RsMessageToClientType
 }
 
@@ -106,7 +104,7 @@
 
 
 ContextFinish {
-	handcodeApi
+	sync
 	}
 
 ContextBindRootScript {
diff --git a/rsContext.cpp b/rsContext.cpp
index 98adabc..6027946 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -344,6 +344,8 @@
 bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
     pthread_mutex_lock(&gInitMutex);
 
+    mIO.init();
+
     dev->addContext(this);
     mDev = dev;
     if (sc) {
@@ -393,7 +395,7 @@
 Context::~Context() {
     LOGV("Context::~Context");
 
-    mIO.mToCore.flush();
+    mIO.coreFlush();
     rsAssert(mExit);
     mExit = true;
     mPaused = false;
@@ -505,69 +507,18 @@
     }
 }
 
-RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID, bool wait) {
-    *receiveLen = 0;
-    if (!wait && mIO.mToClient.isEmpty()) {
-        return RS_MESSAGE_TO_CLIENT_NONE;
-    }
-
-    uint32_t bytesData = 0;
-    uint32_t commandID = 0;
-    const uint32_t *d = (const uint32_t *)mIO.mToClient.get(&commandID, &bytesData);
-    *receiveLen = bytesData - sizeof(uint32_t);
-    if (bytesData) {
-        *subID = d[0];
-    }
-    return (RsMessageToClientType)commandID;
+RsMessageToClientType Context::peekMessageToClient(size_t *receiveLen, uint32_t *subID) {
+    return (RsMessageToClientType)mIO.getClientHeader(receiveLen, subID);
 }
 
-RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait) {
-    //LOGE("getMessageToClient %i %i", bufferLen, wait);
-    *receiveLen = 0;
-    if (!wait && mIO.mToClient.isEmpty()) {
-        return RS_MESSAGE_TO_CLIENT_NONE;
-    }
-
-    //LOGE("getMessageToClient 2 con=%p", this);
-    uint32_t bytesData = 0;
-    uint32_t commandID = 0;
-    const uint32_t *d = (const uint32_t *)mIO.mToClient.get(&commandID, &bytesData);
-    //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
-
-    *receiveLen = bytesData - sizeof(uint32_t);
-    *subID = d[0];
-
-    //LOGE("getMessageToClient  %i %i", commandID, *subID);
-    if (bufferLen >= (*receiveLen)) {
-        memcpy(data, d+1, *receiveLen);
-        mIO.mToClient.next();
-        return (RsMessageToClientType)commandID;
-    }
-    return RS_MESSAGE_TO_CLIENT_RESIZE;
+RsMessageToClientType Context::getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen) {
+    return (RsMessageToClientType)mIO.getClientPayload(data, receiveLen, subID, bufferLen);
 }
 
 bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID,
                                   uint32_t subID, size_t len, bool waitForSpace) const {
-    //LOGE("sendMessageToClient %i %i %i %i", cmdID, subID, len, waitForSpace);
-    if (cmdID == 0) {
-        LOGE("Attempting to send invalid command 0 to client.");
-        return false;
-    }
-    if (!waitForSpace) {
-        if (!mIO.mToClient.makeSpaceNonBlocking(len + 12)) {
-            // Not enough room, and not waiting.
-            return false;
-        }
-    }
-    //LOGE("sendMessageToClient 2");
-    uint32_t *p = (uint32_t *)mIO.mToClient.reserve(len + sizeof(subID));
-    p[0] = subID;
-    if (len > 0) {
-        memcpy(p+1, data, len);
-    }
-    mIO.mToClient.commit(cmdID, len + sizeof(subID));
-    //LOGE("sendMessageToClient 3");
-    return true;
+
+    return mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
 }
 
 void Context::initToClient() {
@@ -577,7 +528,7 @@
 }
 
 void Context::deinitToClient() {
-    mIO.mToClient.shutdown();
+    mIO.clientShutdown();
 }
 
 void Context::setError(RsError e, const char *msg) const {
@@ -706,16 +657,16 @@
 
 RsMessageToClientType rsi_ContextPeekMessage(Context *rsc,
                                            size_t * receiveLen, size_t receiveLen_length,
-                                           uint32_t * subID, size_t subID_length, bool wait) {
-    return rsc->peekMessageToClient(receiveLen, subID, wait);
+                                           uint32_t * subID, size_t subID_length) {
+    return rsc->peekMessageToClient(receiveLen, subID);
 }
 
 RsMessageToClientType rsi_ContextGetMessage(Context *rsc, void * data, size_t data_length,
                                           size_t * receiveLen, size_t receiveLen_length,
-                                          uint32_t * subID, size_t subID_length, bool wait) {
+                                          uint32_t * subID, size_t subID_length) {
     rsAssert(subID_length == sizeof(uint32_t));
     rsAssert(receiveLen_length == sizeof(size_t));
-    return rsc->getMessageToClient(data, receiveLen, subID, data_length, wait);
+    return rsc->getMessageToClient(data, receiveLen, subID, data_length);
 }
 
 void rsi_ContextInitToClient(Context *rsc) {
diff --git a/rsContext.h b/rsContext.h
index 1407b7e..6336210 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -143,8 +143,8 @@
     void assignName(ObjectBase *obj, const char *name, uint32_t len);
     void removeName(ObjectBase *obj);
 
-    RsMessageToClientType peekMessageToClient(size_t *receiveLen, uint32_t *subID, bool wait);
-    RsMessageToClientType getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen, bool wait);
+    RsMessageToClientType peekMessageToClient(size_t *receiveLen, uint32_t *subID);
+    RsMessageToClientType getMessageToClient(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen);
     bool sendMessageToClient(const void *data, RsMessageToClientType cmdID, uint32_t subID, size_t len, bool waitForSpace) const;
     uint32_t runScript(Script *s);
 
diff --git a/rsFifoSocket.cpp b/rsFifoSocket.cpp
index 1ce57b9..848bba5 100644
--- a/rsFifoSocket.cpp
+++ b/rsFifoSocket.cpp
@@ -45,23 +45,34 @@
 }
 
 void FifoSocket::writeAsync(const void *data, size_t bytes) {
-    size_t ret = ::write(sv[0], data, bytes);
+    if (bytes == 0) {
+        return;
+    }
+    //LOGE("writeAsync %p %i", data, bytes);
+    size_t ret = ::send(sv[0], data, bytes, 0);
+    //LOGE("writeAsync ret %i", ret);
     rsAssert(ret == bytes);
 }
 
 void FifoSocket::writeWaitReturn(void *retData, size_t retBytes) {
-    size_t ret = ::read(sv[1], retData, retBytes);
+    //LOGE("writeWaitReturn %p %i", retData, retBytes);
+    size_t ret = ::recv(sv[0], retData, retBytes, 0);
+    //LOGE("writeWaitReturn %i", ret);
     rsAssert(ret == retBytes);
 }
 
 size_t FifoSocket::read(void *data, size_t bytes) {
-    size_t ret = ::read(sv[0], data, bytes);
+    //LOGE("read %p %i", data, bytes);
+    size_t ret = ::recv(sv[1], data, bytes, 0);
     rsAssert(ret == bytes);
+    //LOGE("read ret %i", ret);
     return ret;
 }
 
 void FifoSocket::readReturn(const void *data, size_t bytes) {
-    size_t ret = ::write(sv[1], data, bytes);
+    LOGE("readReturn %p %i", data, bytes);
+    size_t ret = ::send(sv[1], data, bytes, 0);
+    LOGE("readReturn %i", ret);
     rsAssert(ret == bytes);
 }
 
diff --git a/rsHandcode.h b/rsHandcode.h
deleted file mode 100644
index e6b722c..0000000
--- a/rsHandcode.h
+++ /dev/null
@@ -1,9 +0,0 @@
-
-#define DATA_SYNC_SIZE 1024
-
-static inline void rsHCAPI_ContextFinish (RsContext rsc) {
-    ThreadIO *io = &((Context *)rsc)->mIO;
-    uint32_t size = sizeof(RS_CMD_ContextFinish);
-    io->mToCore.commitSync(RS_CMD_ID_ContextFinish, size);
-}
-
diff --git a/rsThreadIO.cpp b/rsThreadIO.cpp
index 6e959a7..4429556 100644
--- a/rsThreadIO.cpp
+++ b/rsThreadIO.cpp
@@ -23,16 +23,96 @@
 
 ThreadIO::ThreadIO() {
     mToCore.init(16 * 1024);
-    mToClient.init(1024);
 }
 
 ThreadIO::~ThreadIO() {
 }
 
-void ThreadIO::shutdown() {
-    mToCore.shutdown();
+void ThreadIO::init(bool useSocket) {
+    mUsingSocket = useSocket;
+
+    if (mUsingSocket) {
+        mToClientSocket.init();
+        mToCoreSocket.init();
+    } else {
+        mToClient.init(1024);
+    }
 }
 
+void ThreadIO::shutdown() {
+    //LOGE("shutdown 1");
+    mToCore.shutdown();
+    //LOGE("shutdown 2");
+}
+
+void ThreadIO::coreFlush() {
+    //LOGE("coreFlush 1");
+    if (mUsingSocket) {
+    } else {
+        mToCore.flush();
+    }
+    //LOGE("coreFlush 2");
+}
+
+void * ThreadIO::coreHeader(uint32_t cmdID, size_t dataLen) {
+    //LOGE("coreHeader %i %i", cmdID, dataLen);
+    if (mUsingSocket) {
+        CoreCmdHeader hdr;
+        hdr.bytes = dataLen;
+        hdr.cmdID = cmdID;
+        mToCoreSocket.writeAsync(&hdr, sizeof(hdr));
+    } else {
+        mCoreCommandSize = dataLen;
+        mCoreCommandID = cmdID;
+        mCoreDataPtr = (uint8_t *)mToCore.reserve(dataLen);
+        mCoreDataBasePtr = mCoreDataPtr;
+    }
+    //LOGE("coreHeader ret %p", mCoreDataPtr);
+    return mCoreDataPtr;
+}
+
+void ThreadIO::coreData(const void *data, size_t dataLen) {
+    //LOGE("coreData %p %i", data, dataLen);
+    mToCoreSocket.writeAsync(data, dataLen);
+    //LOGE("coreData ret %p", mCoreDataPtr);
+}
+
+void ThreadIO::coreCommit() {
+    //LOGE("coreCommit %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
+    if (mUsingSocket) {
+    } else {
+        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
+        mToCore.commit(mCoreCommandID, mCoreCommandSize);
+    }
+    //LOGE("coreCommit ret");
+}
+
+void ThreadIO::coreCommitSync() {
+    //LOGE("coreCommitSync %p %p %i", mCoreDataPtr, mCoreDataBasePtr, mCoreCommandSize);
+    if (mUsingSocket) {
+    } else {
+        rsAssert((size_t)(mCoreDataPtr - mCoreDataBasePtr) <= mCoreCommandSize);
+        mToCore.commitSync(mCoreCommandID, mCoreCommandSize);
+    }
+    //LOGE("coreCommitSync ret");
+}
+
+void ThreadIO::clientShutdown() {
+    //LOGE("coreShutdown 1");
+    mToClient.shutdown();
+    //LOGE("coreShutdown 2");
+}
+
+void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
+    rsAssert(dataLen <= sizeof(mToCoreRet));
+    memcpy(&mToCoreRet, data, dataLen);
+}
+
+void ThreadIO::coreGetReturn(void *data, size_t dataLen) {
+    memcpy(data, &mToCoreRet, dataLen);
+}
+
+
 bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand) {
     bool ret = false;
     while (!mToCore.isEmpty() || waitForCommand) {
@@ -64,4 +144,82 @@
     return ret;
 }
 
+RsMessageToClientType ThreadIO::getClientHeader(size_t *receiveLen, uint32_t *usrID) {
+    if (mUsingSocket) {
+        mToClientSocket.read(&mLastClientHeader, sizeof(mLastClientHeader));
+    } else {
+        size_t bytesData = 0;
+        const uint32_t *d = (const uint32_t *)mToClient.get(&mLastClientHeader.cmdID, &bytesData);
+        if (bytesData >= sizeof(uint32_t)) {
+            mLastClientHeader.userID = d[0];
+            mLastClientHeader.bytes = bytesData - sizeof(uint32_t);
+        } else {
+            mLastClientHeader.userID = 0;
+            mLastClientHeader.bytes = 0;
+        }
+    }
+    receiveLen[0] = mLastClientHeader.bytes;
+    usrID[0] = mLastClientHeader.userID;
+    return (RsMessageToClientType)mLastClientHeader.cmdID;
+}
+
+RsMessageToClientType ThreadIO::getClientPayload(void *data, size_t *receiveLen,
+                                uint32_t *usrID, size_t bufferLen) {
+    receiveLen[0] = mLastClientHeader.bytes;
+    usrID[0] = mLastClientHeader.userID;
+    if (bufferLen < mLastClientHeader.bytes) {
+        return RS_MESSAGE_TO_CLIENT_RESIZE;
+    }
+    if (mUsingSocket) {
+        if (receiveLen[0]) {
+            mToClientSocket.read(data, receiveLen[0]);
+        }
+        return (RsMessageToClientType)mLastClientHeader.cmdID;
+    } else {
+        uint32_t bytesData = 0;
+        uint32_t commandID = 0;
+        const uint32_t *d = (const uint32_t *)mToClient.get(&commandID, &bytesData);
+        //LOGE("getMessageToClient 3    %i  %i", commandID, bytesData);
+        //LOGE("getMessageToClient  %i %i", commandID, *subID);
+        if (bufferLen >= receiveLen[0]) {
+            memcpy(data, d+1, receiveLen[0]);
+            mToClient.next();
+            return (RsMessageToClientType)commandID;
+        }
+    }
+    return RS_MESSAGE_TO_CLIENT_RESIZE;
+}
+
+bool ThreadIO::sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data,
+                            size_t dataLen, bool waitForSpace) {
+    ClientCmdHeader hdr;
+    hdr.bytes = dataLen;
+    hdr.cmdID = cmdID;
+    hdr.userID = usrID;
+    if (mUsingSocket) {
+        mToClientSocket.writeAsync(&hdr, sizeof(hdr));
+        if (dataLen) {
+            mToClientSocket.writeAsync(data, dataLen);
+        }
+        return true;
+    } else {
+        if (!waitForSpace) {
+            if (!mToClient.makeSpaceNonBlocking(dataLen + sizeof(hdr))) {
+                // Not enough room, and not waiting.
+                return false;
+            }
+        }
+
+        //LOGE("sendMessageToClient 2");
+        uint32_t *p = (uint32_t *)mToClient.reserve(dataLen + sizeof(usrID));
+        p[0] = usrID;
+        if (dataLen > 0) {
+            memcpy(p+1, data, dataLen);
+        }
+        mToClient.commit(cmdID, dataLen + sizeof(usrID));
+        //LOGE("sendMessageToClient 3");
+        return true;
+    }
+    return false;
+}
 
diff --git a/rsThreadIO.h b/rsThreadIO.h
index f9d0de7..cad7318 100644
--- a/rsThreadIO.h
+++ b/rsThreadIO.h
@@ -19,6 +19,7 @@
 
 #include "rsUtils.h"
 #include "rsLocklessFifo.h"
+#include "rsFifoSocket.h"
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -31,17 +32,58 @@
     ThreadIO();
     ~ThreadIO();
 
+    void init(bool useSocket = false);
     void shutdown();
 
     // Plays back commands from the client.
     // Returns true if any commands were processed.
     bool playCoreCommands(Context *con, bool waitForCommand);
 
+    //LocklessCommandFifo mToCore;
 
-    LocklessCommandFifo mToCore;
+
+
+    void coreFlush();
+    void * coreHeader(uint32_t, size_t dataLen);
+    void coreData(const void *data, size_t dataLen);
+    void coreCommit();
+    void coreCommitSync();
+    void coreSetReturn(const void *data, size_t dataLen);
+    void coreGetReturn(void *data, size_t dataLen);
+
+
+    RsMessageToClientType getClientHeader(size_t *receiveLen, uint32_t *usrID);
+    RsMessageToClientType getClientPayload(void *data, size_t *receiveLen, uint32_t *subID, size_t bufferLen);
+    bool sendToClient(RsMessageToClientType cmdID, uint32_t usrID, const void *data, size_t dataLen, bool waitForSpace);
+    void clientShutdown();
+
+
+protected:
+    typedef struct CoreCmdHeaderRec {
+        uint32_t cmdID;
+        uint32_t bytes;
+    } CoreCmdHeader;
+    typedef struct ClientCmdHeaderRec {
+        uint32_t cmdID;
+        uint32_t bytes;
+        uint32_t userID;
+    } ClientCmdHeader;
+    ClientCmdHeader mLastClientHeader;
+
+    size_t mCoreCommandSize;
+    uint32_t mCoreCommandID;
+    uint8_t * mCoreDataPtr;
+    uint8_t * mCoreDataBasePtr;
+
+    bool mUsingSocket;
     LocklessCommandFifo mToClient;
+    LocklessCommandFifo mToCore;
+
+    FifoSocket mToClientSocket;
+    FifoSocket mToCoreSocket;
 
     intptr_t mToCoreRet;
+
 };
 
 
diff --git a/rsg_generator.c b/rsg_generator.c
index d550712..b3f6c55 100644
--- a/rsg_generator.c
+++ b/rsg_generator.c
@@ -193,7 +193,6 @@
     fprintf(f, "\n");
     fprintf(f, "using namespace android;\n");
     fprintf(f, "using namespace android::renderscript;\n");
-    fprintf(f, "#include \"rsHandcode.h\"\n");
     fprintf(f, "\n");
 
     printFuncPointers(f, 0);
@@ -206,18 +205,14 @@
         fprintf(f, "static ");
         printFuncDecl(f, api, "LF_", 0, 0);
         fprintf(f, "\n{\n");
-        if (api->handcodeApi || api->direct) {
-            if (api->handcodeApi) {
-                fprintf(f, "    rsHCAPI_%s(rsc", api->name);
-            } else {
-                fprintf(f, "    ");
-                if (api->ret.typeName[0]) {
-                    fprintf(f, "return ");
-                }
-                fprintf(f, "rsi_%s(", api->name);
-                if (!api->nocontext) {
-                    fprintf(f, "(Context *)rsc");
-                }
+        if (api->direct) {
+            fprintf(f, "    ");
+            if (api->ret.typeName[0]) {
+                fprintf(f, "return ");
+            }
+            fprintf(f, "rsi_%s(", api->name);
+            if (!api->nocontext) {
+                fprintf(f, "(Context *)rsc");
             }
             for (ct2=0; ct2 < api->paramCount; ct2++) {
                 const VarType *vt = &api->params[ct2];
@@ -244,13 +239,13 @@
             if (hasInlineDataPointers(api)) {
                 fprintf(f, "    RS_CMD_%s *cmd = NULL;\n", api->name);
                 fprintf(f, "    if (dataSize < 1024) {;\n");
-                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(dataSize + size));\n", api->name);
+                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name);
                 fprintf(f, "    } else {\n");
-                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(size));\n", api->name);
+                fprintf(f, "        cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name);
                 fprintf(f, "    }\n");
                 fprintf(f, "    uint8_t *payload = (uint8_t *)&cmd[1];\n");
             } else {
-                fprintf(f, "    RS_CMD_%s *cmd = static_cast<RS_CMD_%s *>(io->mToCore.reserve(size));\n", api->name, api->name);
+                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);
             }
 
             for (ct2=0; ct2 < api->paramCount; ct2++) {
@@ -271,28 +266,30 @@
                     fprintf(f, "    cmd->%s = %s;\n", vt->name, vt->name);
                 }
             }
-            if (api->ret.typeName[0]) {
+            if (api->ret.typeName[0] || api->sync) {
                 needFlush = 1;
             }
 
             if (hasInlineDataPointers(api)) {
                 fprintf(f, "    if (dataSize < 1024) {\n");
-                fprintf(f, "        io->mToCore.commit(RS_CMD_ID_%s, size + dataSize);\n", api->name);
+                fprintf(f, "        io->coreCommit();\n");
                 fprintf(f, "    } else {\n");
-                fprintf(f, "        io->mToCore.commitSync(RS_CMD_ID_%s, size);\n", api->name);
+                fprintf(f, "        io->coreCommitSync();\n");
                 fprintf(f, "    }\n");
             } else {
-                fprintf(f, "    io->mToCore.commit");
+                fprintf(f, "    io->coreCommit");
                 if (needFlush) {
                     fprintf(f, "Sync");
                 }
-                fprintf(f, "(RS_CMD_ID_%s, size);\n", api->name);
+                fprintf(f, "();\n");
             }
 
             if (api->ret.typeName[0]) {
-                fprintf(f, "    return reinterpret_cast<");
+                fprintf(f, "\n    ");
                 printVarType(f, &api->ret);
-                fprintf(f, ">(io->mToCoreRet);\n");
+                fprintf(f, " ret;\n");
+                fprintf(f, "    io->coreGetReturn(&ret, sizeof(ret));\n");
+                fprintf(f, "    return ret;\n");
             }
         }
         fprintf(f, "};\n\n");
@@ -306,86 +303,73 @@
         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];
+        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 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);
+                    fprintf(f, "    dataSize += %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, "        dataSize += %s_length[ct];\n", vt->name);
                     fprintf(f, "    }\n");
                     break;
                 default:
                     printf("pointer level not handled!!");
                 }
             }
-            fprintf(f, "\n");
+        }
+        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");
-                }
+        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:
+                fprintf(stderr, "pointer level not handled!!");
             }
+        }
+        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, "    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");
     }
@@ -446,7 +430,6 @@
     fprintf(f, "\n");
     fprintf(f, "namespace android {\n");
     fprintf(f, "namespace renderscript {\n");
-    fprintf(f, "#include \"rsHandcode.h\"\n");
     fprintf(f, "\n");
 
     for (ct=0; ct < apiCount; ct++) {
@@ -463,7 +446,9 @@
 
         fprintf(f, "    ");
         if (api->ret.typeName[0]) {
-            fprintf(f, "con->mIO.mToCoreRet = (intptr_t)");
+            fprintf(f, "\n    ");
+            printVarType(f, &api->ret);
+            fprintf(f, " ret = ");
         }
         fprintf(f, "rsi_%s(con", api->name);
         for (ct2=0; ct2 < api->paramCount; ct2++) {
@@ -472,6 +457,10 @@
         }
         fprintf(f, ");\n");
 
+        if (api->ret.typeName[0]) {
+            fprintf(f, "    con->mIO.coreSetReturn(&ret, sizeof(ret));\n");
+        }
+
         fprintf(f, "};\n\n");
     }