am decc139b: Merge change I7a824efc into eclair

Merge commit 'decc139b232721ea1b0521d144521c8082636f0c' into eclair-mr2

* commit 'decc139b232721ea1b0521d144521c8082636f0c':
  Support applications changing the surface attached to the RS.
diff --git a/graphics/java/android/renderscript/RSSurfaceView.java b/graphics/java/android/renderscript/RSSurfaceView.java
index 53466cc..1bc03ac 100644
--- a/graphics/java/android/renderscript/RSSurfaceView.java
+++ b/graphics/java/android/renderscript/RSSurfaceView.java
@@ -80,6 +80,9 @@
      */
     public void surfaceDestroyed(SurfaceHolder holder) {
         // Surface will be destroyed when we return
+        if (mRS != null) {
+            mRS.contextSetSurface(null);
+        }
         //Log.v(RenderScript.LOG_TAG, "surfaceDestroyed");
     }
 
@@ -88,6 +91,9 @@
      * not normally called or subclassed by clients of RSSurfaceView.
      */
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        if (mRS != null) {
+            mRS.contextSetSurface(holder.getSurface());
+        }
         //Log.v(RenderScript.LOG_TAG, "surfaceChanged");
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 1f2ea38..f1e5af1 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -64,6 +64,7 @@
     native void nDeviceSetConfig(int dev, int param, int value);
     native int  nContextCreate(int dev, Surface sur, int ver, boolean useDepth);
     native void nContextDestroy(int con);
+    native void nContextSetSurface(Surface sur);
 
     native void nContextBindRootScript(int script);
     native void nContextBindSampler(int sampler, int slot);
@@ -276,6 +277,11 @@
         mMessageThread.start();
     }
 
+    public void contextSetSurface(Surface sur) {
+        mSurface = sur;
+        nContextSetSurface(mSurface);
+    }
+
     public void destroy() {
         nContextDeinitToClient();
         mMessageThread.mRun = false;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index fa3baa2..f3dda41 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -171,6 +171,24 @@
 }
 
 static void
+nContextSetSurface(JNIEnv *_env, jobject _this, jobject wnd)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    LOG_API("nContextSetSurface, con(%p), surface(%p)", con, (Surface *)wnd);
+
+    Surface * window = NULL;
+    if (wnd == NULL) {
+
+    } else {
+        jclass surface_class = _env->FindClass("android/view/Surface");
+        jfieldID surfaceFieldID = _env->GetFieldID(surface_class, "mSurface", "I");
+        window = (Surface*)_env->GetIntField(wnd, surfaceFieldID);
+    }
+
+    rsContextSetSurface(con, window);
+}
+
+static void
 nContextDestroy(JNIEnv *_env, jobject _this, jint con)
 {
     LOG_API("nContextDestroy, con(%p)", (RsContext)con);
@@ -1328,6 +1346,7 @@
 {"nDeviceDestroy",                 "(I)V",                                 (void*)nDeviceDestroy },
 {"nDeviceSetConfig",               "(III)V",                               (void*)nDeviceSetConfig },
 {"nContextCreate",                 "(ILandroid/view/Surface;IZ)I",         (void*)nContextCreate },
+{"nContextSetSurface",             "(Landroid/view/Surface;)V",            (void*)nContextSetSurface },
 {"nContextDestroy",                "(I)V",                                 (void*)nContextDestroy },
 {"nContextPause",                  "()V",                                  (void*)nContextPause },
 {"nContextResume",                 "()V",                                  (void*)nContextResume },
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index a393e2f..865e435 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -36,6 +36,10 @@
 ContextResume {
 	}
 
+ContextSetSurface {
+	param void *sur
+	}
+
 AssignName {
 	param void *obj
 	param const char *name
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2e6d7b0..3e4cc36 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -85,17 +85,6 @@
     }
     //eglChooseConfig(mEGL.mDisplay, configAttribs, &mEGL.mConfig, 1, &mEGL.mNumConfigs);
 
-    if (mWndSurface) {
-        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
-    } else {
-        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig,
-             android_createDisplaySurface(),
-             NULL);
-    }
-    checkEglError("eglCreateWindowSurface");
-    if (mEGL.mSurface == EGL_NO_SURFACE) {
-        LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
-    }
 
     mEGL.mContext = eglCreateContext(mEGL.mDisplay, mEGL.mConfig, EGL_NO_CONTEXT, NULL);
     checkEglError("eglCreateContext");
@@ -104,10 +93,10 @@
     }
     gGLContextCount++;
 
-    EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
-    checkEglError("eglCreateContext", ret);
-    if (mEGL.mContext == EGL_NO_CONTEXT) {
-        LOGE("eglCreateContext returned EGL_NO_CONTEXT");
+    if (mWndSurface) {
+        setSurface(mWndSurface);
+    } else {
+        setSurface((Surface *)android_createDisplaySurface());
     }
 
     eglQuerySurface(mEGL.mDisplay, mEGL.mSurface, EGL_WIDTH, &mEGL.mWidth);
@@ -134,12 +123,7 @@
 
 void Context::deinitEGL()
 {
-    EGLBoolean ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    checkEglError("eglCreateContext", ret);
-    if (mEGL.mContext == EGL_NO_CONTEXT) {
-        LOGE("eglCreateContext returned EGL_NO_CONTEXT");
-    }
-
+    setSurface(NULL);
     eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
     checkEglError("eglDestroyContext");
 
@@ -311,6 +295,7 @@
      while (!rsc->mExit) {
          mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
          mDraw &= (rsc->mRootScript.get() != NULL);
+         mDraw &= (rsc->mWndSurface != NULL);
 
          if (mDraw) {
              mDraw = rsc->runRootScript() && !rsc->mPaused;
@@ -441,6 +426,32 @@
     objDestroyOOBDestroy();
 }
 
+void Context::setSurface(Surface *sur)
+{
+    EGLBoolean ret;
+    if (mEGL.mSurface != NULL) {
+        ret = eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        checkEglError("eglMakeCurrent", ret);
+
+        ret = eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+        checkEglError("eglDestroySurface", ret);
+
+        mEGL.mSurface = NULL;
+    }
+
+    mWndSurface = sur;
+    if (mWndSurface != NULL) {
+        mEGL.mSurface = eglCreateWindowSurface(mEGL.mDisplay, mEGL.mConfig, mWndSurface, NULL);
+        checkEglError("eglCreateWindowSurface");
+        if (mEGL.mSurface == EGL_NO_SURFACE) {
+            LOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
+        }
+
+        ret = eglMakeCurrent(mEGL.mDisplay, mEGL.mSurface, mEGL.mSurface, mEGL.mContext);
+        checkEglError("eglMakeCurrent", ret);
+    }
+}
+
 void Context::pause()
 {
     mPaused = true;
@@ -756,6 +767,11 @@
     rsc->resume();
 }
 
+void rsi_ContextSetSurface(Context *rsc, void *sur)
+{
+    rsc->setSurface((Surface *)sur);
+}
+
 }
 }
 
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index c80fd5a..bffc55b 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -94,6 +94,7 @@
 
     void pause();
     void resume();
+    void setSurface(Surface *sur);
 
     void assignName(ObjectBase *obj, const char *name, uint32_t len);
     void removeName(ObjectBase *obj);