Start using bcinfo components within librs.

BUG=4942491

Change-Id: I3a46783511c4954bac9eadbbbefe5abf85498c16
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 535f713..3ba0123 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -52,8 +52,8 @@
 RsDevice rsDeviceCreate();
 void rsDeviceDestroy(RsDevice dev);
 void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
-RsContext rsContextCreate(RsDevice dev, uint32_t version);
-RsContext rsContextCreateGL(RsDevice dev, uint32_t version, RsSurfaceConfig sc, uint32_t dpi);
+RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion);
+RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, RsSurfaceConfig sc, uint32_t dpi);
 
 #include "rsgApiFuncDecl.h"
 
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 0c0aa10..807ed24 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -19,7 +19,7 @@
 #include "rsdBcc.h"
 #include "rsdRuntime.h"
 
-#include <bcinfo/bcinfo.h>
+#include <bcinfo/MetadataExtractor.h>
 
 #include "rsContext.h"
 #include "rsScriptC.h"
@@ -40,7 +40,7 @@
 
     BCCScriptRef mBccScript;
 
-    struct BCScriptMetadata *mScriptMetadata;
+    bcinfo::MetadataExtractor *ME;
 
     InvokeFunc_t *mInvokeFunctions;
     void ** mFieldAddress;
@@ -71,7 +71,9 @@
 
     pthread_mutex_lock(&rsdgInitMutex);
     char *cachePath = NULL;
-    struct BCScriptMetadata *md = NULL;
+    size_t exportFuncCount = 0;
+    size_t exportVarCount = 0;
+    size_t objectSlotCount = 0;
 
     DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
     if (drv == NULL) {
@@ -84,13 +86,13 @@
     drv->mScriptText = bitcode;
     drv->mScriptTextLength = bitcodeSize;
 
-    md = bcinfoGetScriptMetadata((const char*)drv->mScriptText,
-                                 drv->mScriptTextLength, 0);
-    if (!md) {
+
+    drv->ME = new bcinfo::MetadataExtractor((const char*)drv->mScriptText,
+                                            drv->mScriptTextLength);
+    if (!drv->ME->extract()) {
       LOGE("bcinfo: failed to read script metadata");
       goto error;
     }
-    drv->mScriptMetadata = md;
 
     //LOGE("mBccScript %p", script->mBccScript);
 
@@ -122,40 +124,41 @@
     drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
     drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
 
-    if (md->exportFuncCount > 0) {
-        drv->mInvokeFunctions = (InvokeFunc_t*) calloc(md->exportFuncCount,
+    exportFuncCount = drv->ME->getExportFuncCount();
+    if (exportFuncCount > 0) {
+        drv->mInvokeFunctions = (InvokeFunc_t*) calloc(exportFuncCount,
                                                        sizeof(InvokeFunc_t));
-        bccGetExportFuncList(drv->mBccScript,
-                             md->exportFuncCount,
+        bccGetExportFuncList(drv->mBccScript, exportFuncCount,
                              (void **) drv->mInvokeFunctions);
     } else {
         drv->mInvokeFunctions = NULL;
     }
 
-    if (md->exportVarCount > 0) {
-        drv->mFieldAddress = (void **) calloc(md->exportVarCount,
-                                              sizeof(void*));
-        drv->mFieldIsObject = (bool *) calloc(md->exportVarCount, sizeof(bool));
-        bccGetExportVarList(drv->mBccScript,
-                            md->exportVarCount,
+    exportVarCount = drv->ME->getExportVarCount();
+    if (exportVarCount > 0) {
+        drv->mFieldAddress = (void **) calloc(exportVarCount, sizeof(void*));
+        drv->mFieldIsObject = (bool *) calloc(exportVarCount, sizeof(bool));
+        bccGetExportVarList(drv->mBccScript, exportVarCount,
                             (void **) drv->mFieldAddress);
     } else {
         drv->mFieldAddress = NULL;
         drv->mFieldIsObject = NULL;
     }
 
-    if (md->objectSlotCount) {
-        for (uint32_t ct=0; ct < md->objectSlotCount; ct++) {
-            drv->mFieldIsObject[md->objectSlotList[ct]] = true;
+    objectSlotCount = drv->ME->getObjectSlotCount();
+    if (objectSlotCount > 0) {
+        const uint32_t *objectSlotList = drv->ME->getObjectSlotList();
+        for (uint32_t ct=0; ct < objectSlotCount; ct++) {
+            drv->mFieldIsObject[objectSlotList[ct]] = true;
         }
     }
 
     // Copy info over to runtime
-    script->mHal.info.exportedFunctionCount = md->exportFuncCount;
-    script->mHal.info.exportedVariableCount = md->exportVarCount;
-    script->mHal.info.exportedPragmaCount = md->pragmaCount;
-    script->mHal.info.exportedPragmaKeyList = md->pragmaKeyList;
-    script->mHal.info.exportedPragmaValueList = md->pragmaValueList;
+    script->mHal.info.exportedFunctionCount = drv->ME->getExportFuncCount();
+    script->mHal.info.exportedVariableCount = drv->ME->getExportVarCount();
+    script->mHal.info.exportedPragmaCount = drv->ME->getPragmaCount();
+    script->mHal.info.exportedPragmaKeyList = drv->ME->getPragmaKeyList();
+    script->mHal.info.exportedPragmaValueList = drv->ME->getPragmaValueList();
     script->mHal.info.root = drv->mRoot;
 
     pthread_mutex_unlock(&rsdgInitMutex);
@@ -164,6 +167,10 @@
 error:
 
     pthread_mutex_unlock(&rsdgInitMutex);
+    if (drv->ME) {
+        delete drv->ME;
+        drv->ME = NULL;
+    }
     free(drv);
     return false;
 
@@ -445,10 +452,10 @@
 
 void rsdScriptDestroy(const Context *dc, Script *script) {
     DrvScript *drv = (DrvScript *)script->mHal.drv;
-    struct BCScriptMetadata *md = drv->mScriptMetadata;
 
     if (drv->mFieldAddress) {
-        for (size_t ct = 0; ct < md->exportVarCount; ct++) {
+        size_t exportVarCount = drv->ME->getExportVarCount();
+        for (size_t ct = 0; ct < exportVarCount; ct++) {
             if (drv->mFieldIsObject[ct]) {
                 // The field address can be NULL if the script-side has
                 // optimized the corresponding global variable away.
@@ -467,7 +474,8 @@
         drv->mInvokeFunctions = NULL;
     }
 
-    bcinfoReleaseScriptMetadata(&drv->mScriptMetadata);
+    delete drv->ME;
+    drv->ME = NULL;
 
     free(drv);
     script->mHal.drv = NULL;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index decd9f1..6a30b17 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -333,6 +333,7 @@
     mPaused = false;
     mObjHead = NULL;
     mError = RS_ERROR_NONE;
+    mTargetSdkVersion = 14;
     mDPI = 96;
     mIsContextLite = false;
 }
@@ -678,19 +679,25 @@
 }
 }
 
-RsContext rsContextCreate(RsDevice vdev, uint32_t version) {
+RsContext rsContextCreate(RsDevice vdev, uint32_t version,
+                          uint32_t sdkVersion) {
     LOGV("rsContextCreate %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, NULL);
+    if (rsc) {
+        rsc->setTargetSdkVersion(sdkVersion);
+    }
     return rsc;
 }
 
 RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
-                            RsSurfaceConfig sc, uint32_t dpi) {
+                            uint32_t sdkVersion, RsSurfaceConfig sc,
+                            uint32_t dpi) {
     LOGV("rsContextCreateGL %p", vdev);
     Device * dev = static_cast<Device *>(vdev);
     Context *rsc = Context::createContext(dev, &sc);
     if (rsc) {
+        rsc->setTargetSdkVersion(sdkVersion);
         rsc->setDPI(dpi);
     }
     LOGV("rsContextCreateGL ret %p ", rsc);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 309fe95..3c7a3d2 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -199,9 +199,13 @@
     uint32_t getDPI() const {return mDPI;}
     void setDPI(uint32_t dpi) {mDPI = dpi;}
 
+    uint32_t getTargetSdkVersion() const {return mTargetSdkVersion;}
+    void setTargetSdkVersion(uint32_t sdkVer) {mTargetSdkVersion = sdkVer;}
+
     Device *mDev;
 protected:
 
+    uint32_t mTargetSdkVersion;
     uint32_t mDPI;
     uint32_t mWidth;
     uint32_t mHeight;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index e8b1014..dccf71f 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -19,6 +19,10 @@
 #include "utils/Timers.h"
 #include "utils/StopWatch.h"
 
+#ifndef ANDROID_RS_SERIALIZE
+#include <bcinfo/BitcodeTranslator.h>
+#endif
+
 using namespace android;
 using namespace android::renderscript;
 
@@ -28,9 +32,18 @@
     ScriptC * sc = (ScriptC *) tls->mScript
 
 ScriptC::ScriptC(Context *rsc) : Script(rsc) {
+#ifndef ANDROID_RS_SERIALIZE
+    BT = NULL;
+#endif
 }
 
 ScriptC::~ScriptC() {
+#ifndef ANDROID_RS_SERIALIZE
+    if (BT) {
+        delete BT;
+        BT = NULL;
+    }
+#endif
     mRSC->mHal.funcs.script.destroy(mRSC, this);
 }
 
@@ -181,6 +194,22 @@
                           size_t bitcodeLen) {
 
     //LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
+#ifndef ANDROID_RS_SERIALIZE
+    uint32_t sdkVersion = rsc->getTargetSdkVersion();
+    if (BT) {
+        delete BT;
+    }
+    BT = new bcinfo::BitcodeTranslator((const char *)bitcode, bitcodeLen,
+                                       sdkVersion);
+    if (!BT->translate()) {
+        LOGE("Failed to translate bitcode from version: %u", sdkVersion);
+        delete BT;
+        BT = NULL;
+        return false;
+    }
+    bitcode = (const uint8_t *) BT->getTranslatedBitcode();
+    bitcodeLen = BT->getTranslatedBitcodeSize();
+#endif
 
     rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0);
 
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 5c191d9..c65a5bf 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -21,6 +21,9 @@
 
 #include "RenderScriptEnv.h"
 
+#ifndef ANDROID_RS_SERIALIZE
+#include "bcinfo/BitcodeTranslator.h"
+#endif
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -61,6 +64,10 @@
     void setupScript(Context *);
     void setupGLState(Context *);
     Script * setTLS(Script *);
+  private:
+#ifndef ANDROID_RS_SERIALIZE
+    bcinfo::BitcodeTranslator *BT;
+#endif
 };
 
 class ScriptCState {