Add caching support of BCC binaries.

Change-Id: I1e75bb84d88319cb6f1bbe6d907cf6e8ed546142
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 20949a4..dcf86e3 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -402,9 +402,9 @@
     synchronized void nScriptCSetScript(byte[] script, int offset, int length) {
         rsnScriptCSetScript(mContext, script, offset, length);
     }
-    native int  rsnScriptCCreate(int con);
-    synchronized int nScriptCCreate() {
-        return rsnScriptCCreate(mContext);
+    native int  rsnScriptCCreate(int con, String val);
+    synchronized int nScriptCCreate(String val) {
+        return rsnScriptCCreate(mContext, val);
     }
 
     native void rsnSamplerBegin(int con);
@@ -814,6 +814,3 @@
         return 0;
     }
 }
-
-
-
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 44fc5fd..64ed75b 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -75,7 +75,7 @@
 
         rs.nScriptCBegin();
         rs.nScriptCSetScript(pgm, 0, pgmLength);
-        return rs.nScriptCCreate();
+        Log.v(TAG, "Create script for resource = " + resources.getResourceName(resourceID));
+        return rs.nScriptCCreate(resources.getResourceName(resourceID));
     }
 }
-
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 8888459..1cc4386 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -954,10 +954,11 @@
 }
 
 static jint
-nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con)
+nScriptCCreate(JNIEnv *_env, jobject _this, RsContext con, jstring resName)
 {
     LOG_API("nScriptCCreate, con(%p)", con);
-    return (jint)rsScriptCCreate(con);
+    const char* resNameUTF = _env->GetStringUTFChars(resName, NULL);
+    return (jint)rsScriptCCreate(con, resNameUTF);
 }
 
 // ---------------------------------------------------------------------------
@@ -1346,7 +1347,7 @@
 
 {"rsnScriptCBegin",                  "(I)V",                                  (void*)nScriptCBegin },
 {"rsnScriptCSetScript",              "(I[BII)V",                              (void*)nScriptCSetScript },
-{"rsnScriptCCreate",                 "(I)I",                                  (void*)nScriptCCreate },
+{"rsnScriptCCreate",                 "(ILjava/lang/String;)I",                (void*)nScriptCCreate },
 
 {"rsnProgramStoreBegin",             "(III)V",                                (void*)nProgramStoreBegin },
 {"rsnProgramStoreDepthFunc",         "(II)V",                                 (void*)nProgramStoreDepthFunc },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 76db14f..1b584c8 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -320,6 +320,7 @@
 	}
 
 ScriptCCreate {
+        param const char * resName
 	ret RsScript
 	}
 
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index ec7780e..6587b51 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -396,15 +396,25 @@
 extern const char rs_runtime_lib_bc[];
 extern unsigned rs_runtime_lib_bc_size;
 
-void ScriptCState::runCompiler(Context *rsc, ScriptC *s) {
+void ScriptCState::runCompiler(Context *rsc, ScriptC *s, const char *resName) {
     {
-        StopWatch compileTimer("RenderScript compile time");
         s->mBccScript = bccCreateScript();
         s->mEnviroment.mIsThreadable = true;
-        bccScriptBitcode(s->mBccScript, s->mEnviroment.mScriptText, s->mEnviroment.mScriptTextLength);
-        //bccLinkBitcode(s->mBccScript, rs_runtime_lib_bc, rs_runtime_lib_bc_size);
         bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s);
-        bccCompileScript(s->mBccScript);
+        // bccReadBC() reads in the BitCode, if no cache file corresponding to
+        // the resName is found. Otherwise, bccReadBC() returns a negative value
+        // and the "else" branch will be taken.
+        if (bccReadBC(s->mBccScript,
+                      s->mEnviroment.mScriptText,
+                      s->mEnviroment.mScriptTextLength,
+                      resName) >= 0) {
+          //bccLinkBC(s->mBccScript, rs_runtime_lib_bc, rs_runtime_lib_bc_size);
+          bccCompileBC(s->mBccScript);
+        } else {
+          // bccReadBC returns a neagative value: Didn't read any script,
+          // So, use cached binary instead
+          bccLoadBinary(s->mBccScript);
+        }
         bccGetScriptLabel(s->mBccScript, "root", (BCCvoid**) &s->mProgram.mRoot);
         bccGetScriptLabel(s->mBccScript, "init", (BCCvoid**) &s->mProgram.mInit);
     }
@@ -518,14 +528,15 @@
     ss->mScript->mEnviroment.mScriptTextLength = len;
 }
 
-RsScript rsi_ScriptCCreate(Context * rsc) {
+RsScript rsi_ScriptCCreate(Context * rsc, const char *resName)
+{
     ScriptCState *ss = &rsc->mScriptC;
 
     ObjectBaseRef<ScriptC> s(ss->mScript);
     ss->mScript.clear();
     s->incUserRef();
 
-    ss->runCompiler(rsc, s.get());
+    ss->runCompiler(rsc, s.get(), resName);
     ss->clear(rsc);
     return s.get();
 }
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 7ca33ac..4f0dff3 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -81,7 +81,7 @@
     void init(Context *rsc);
 
     void clear(Context *rsc);
-    void runCompiler(Context *rsc, ScriptC *s);
+    void runCompiler(Context *rsc, ScriptC *s, const char *resName);
 
     struct SymbolTable_t {
         const char * mName;
@@ -98,6 +98,3 @@
 }
 }
 #endif
-
-
-