Merge change I7a824efc into eclair
* changes: Support applications changing the surface attached to the RS.
This commit is contained in:
@@ -80,6 +80,9 @@ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
*/
|
||||
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 @@ public class RSSurfaceView extends SurfaceView implements SurfaceHolder.Callback
|
||||
* 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");
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ public class RenderScript {
|
||||
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 @@ public class RenderScript {
|
||||
mMessageThread.start();
|
||||
}
|
||||
|
||||
public void contextSetSurface(Surface sur) {
|
||||
mSurface = sur;
|
||||
nContextSetSurface(mSurface);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
nContextDeinitToClient();
|
||||
mMessageThread.mRun = false;
|
||||
|
||||
@@ -170,6 +170,24 @@ nContextCreate(JNIEnv *_env, jobject _this, jint dev, jobject wnd, jint ver, jbo
|
||||
return (jint)rsContextCreate((RsDevice)dev, window, ver, useDepth);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -1328,6 +1346,7 @@ static JNINativeMethod methods[] = {
|
||||
{"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 },
|
||||
|
||||
@@ -36,6 +36,10 @@ ContextPause {
|
||||
ContextResume {
|
||||
}
|
||||
|
||||
ContextSetSurface {
|
||||
param void *sur
|
||||
}
|
||||
|
||||
AssignName {
|
||||
param void *obj
|
||||
param const char *name
|
||||
|
||||
@@ -85,17 +85,6 @@ void Context::initEGL()
|
||||
}
|
||||
//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 @@ void Context::initEGL()
|
||||
}
|
||||
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::initEGL()
|
||||
|
||||
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 @@ void * Context::threadProc(void *vrsc)
|
||||
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 @@ Context::~Context()
|
||||
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 @@ void rsi_ContextResume(Context *rsc)
|
||||
rsc->resume();
|
||||
}
|
||||
|
||||
void rsi_ContextSetSurface(Context *rsc, void *sur)
|
||||
{
|
||||
rsc->setSurface((Surface *)sur);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ public:
|
||||
|
||||
void pause();
|
||||
void resume();
|
||||
void setSurface(Surface *sur);
|
||||
|
||||
void assignName(ObjectBase *obj, const char *name, uint32_t len);
|
||||
void removeName(ObjectBase *obj);
|
||||
|
||||
Reference in New Issue
Block a user