diff options
author | Jason Sams <rjsams@android.com> | 2010-11-08 17:06:46 -0800 |
---|---|---|
committer | Jason Sams <rjsams@android.com> | 2010-11-08 17:19:31 -0800 |
commit | 1c41517124a90fcfdb95dc069fc492c6fcf1ff25 (patch) | |
tree | 43a463cfe40b0cf7e96ca9045075e31390d1e60e /graphics | |
parent | 553a53ef9ff789dff8b5a74dfea4d6f37feeb263 (diff) | |
download | frameworks_base-1c41517124a90fcfdb95dc069fc492c6fcf1ff25.zip frameworks_base-1c41517124a90fcfdb95dc069fc492c6fcf1ff25.tar.gz frameworks_base-1c41517124a90fcfdb95dc069fc492c6fcf1ff25.tar.bz2 |
Handle user message ID 0
Pass RS runtime errors back to java.
throw exceptions for runtime errors.
Change-Id: Ifcf16cbbf9b98137971dced5076f8a5563eb016c
Diffstat (limited to 'graphics')
-rw-r--r-- | graphics/java/android/renderscript/RenderScript.java | 75 | ||||
-rw-r--r-- | graphics/jni/android_renderscript_RenderScript.cpp | 58 |
2 files changed, 101 insertions, 32 deletions
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index 0c9a4ed..b3774d4 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -62,7 +62,9 @@ public class RenderScript { native int nDeviceCreate(); native void nDeviceDestroy(int dev); native void nDeviceSetConfig(int dev, int param, int value); - native int nContextGetMessage(int con, int[] data, boolean wait); + native void nContextGetUserMessage(int con, int[] data); + native String nContextGetErrorMessage(int con); + native int nContextPeekMessage(int con, int[] subID, boolean wait); native void nContextInitToClient(int con); native void nContextDeinitToClient(int con); @@ -582,11 +584,20 @@ public class RenderScript { public static class RSMessage implements Runnable { protected int[] mData; protected int mID; + protected int mLength; public void run() { } } public RSMessage mMessageCallback = null; + public static class RSAsyncError implements Runnable { + protected String mErrorMessage; + protected int mErrorNum; + public void run() { + } + } + public RSAsyncError mErrorCallback = null; + public enum Priority { LOW (5), //ANDROID_PRIORITY_BACKGROUND + 5 NORMAL (-4); //ANDROID_PRIORITY_DISPLAY @@ -611,6 +622,13 @@ public class RenderScript { protected static class MessageThread extends Thread { RenderScript mRS; boolean mRun = true; + int[] auxData = new int[2]; + + public static final int RS_MESSAGE_TO_CLIENT_NONE = 0; + public static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1; + public static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2; + public static final int RS_MESSAGE_TO_CLIENT_ERROR = 3; + public static final int RS_MESSAGE_TO_CLIENT_USER = 4; MessageThread(RenderScript rs) { super("RSMessageThread"); @@ -625,28 +643,47 @@ public class RenderScript { mRS.nContextInitToClient(mRS.mContext); while(mRun) { rbuf[0] = 0; - int msg = mRS.nContextGetMessage(mRS.mContext, rbuf, true); - if ((msg == 0)) { - // Can happen for two reasons - if (rbuf[0] > 0 && mRun) { - // 1: Buffer needs to be enlarged. - rbuf = new int[rbuf[0] + 2]; + int msg = mRS.nContextPeekMessage(mRS.mContext, auxData, true); + int size = auxData[1]; + int subID = auxData[0]; + + if (msg == RS_MESSAGE_TO_CLIENT_USER) { + if ((size>>2) >= rbuf.length) { + rbuf = new int[(size + 3) >> 2]; + } + mRS.nContextGetUserMessage(mRS.mContext, rbuf); + + if(mRS.mMessageCallback != null) { + mRS.mMessageCallback.mData = rbuf; + mRS.mMessageCallback.mID = subID; + mRS.mMessageCallback.mLength = size; + mRS.mMessageCallback.run(); } else { - // 2: teardown. - // But we want to avoid starving other threads during - // teardown by yielding until the next line in the destructor - // can execute to set mRun = false - try { - sleep(1, 0); - } catch(InterruptedException e) { - } + throw new RSInvalidStateException("Received a message from the script with no message handler installed."); } continue; } - if(mRS.mMessageCallback != null) { - mRS.mMessageCallback.mData = rbuf; - mRS.mMessageCallback.mID = msg; - mRS.mMessageCallback.run(); + + if (msg == RS_MESSAGE_TO_CLIENT_ERROR) { + String e = mRS.nContextGetErrorMessage(mRS.mContext); + + if(mRS.mErrorCallback != null) { + mRS.mErrorCallback.mErrorMessage = e; + mRS.mErrorCallback.mErrorNum = subID; + mRS.mErrorCallback.run(); + } else { + //throw new RSRuntimeException("Received error num " + subID + ", details: " + e); + } + continue; + } + + // 2: teardown. + // But we want to avoid starving other threads during + // teardown by yielding until the next line in the destructor + // can execute to set mRun = false + try { + sleep(1, 0); + } catch(InterruptedException e) { } } Log.d(LOG_TAG, "MessageThread exiting."); diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index 77cbc10..dd84848 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -223,19 +223,48 @@ nContextResume(JNIEnv *_env, jobject _this, RsContext con) rsContextResume(con); } -static jint -nContextGetMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data, jboolean wait) + +static jstring +nContextGetErrorMessage(JNIEnv *_env, jobject _this, RsContext con) +{ + LOG_API("nContextGetErrorMessage, con(%p)", con); + char buf[1024]; + + size_t receiveLen; + uint32_t subID; + int id = rsContextGetMessage(con, buf, &receiveLen, &subID, sizeof(buf), true); + if (!id && receiveLen) { + LOGV("message receive buffer too small. %i", receiveLen); + } + return _env->NewStringUTF(buf); +} + +static void +nContextGetUserMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray data) { jint len = _env->GetArrayLength(data); LOG_API("nContextGetMessage, con(%p), len(%i)", con, len); jint *ptr = _env->GetIntArrayElements(data, NULL); size_t receiveLen; - int id = rsContextGetMessage(con, ptr, &receiveLen, len * 4, wait); + uint32_t subID; + int id = rsContextGetMessage(con, ptr, &receiveLen, &subID, len * 4, true); if (!id && receiveLen) { LOGV("message receive buffer too small. %i", receiveLen); - *ptr = (jint)receiveLen; } _env->ReleaseIntArrayElements(data, ptr, 0); +} + +static jint +nContextPeekMessage(JNIEnv *_env, jobject _this, RsContext con, jintArray auxData, jboolean wait) +{ + LOG_API("nContextPeekMessage, con(%p)", con); + jint *auxDataPtr = _env->GetIntArrayElements(auxData, NULL); + size_t receiveLen; + uint32_t subID; + int id = rsContextPeekMessage(con, &receiveLen, &subID, wait); + auxDataPtr[0] = (jint)subID; + auxDataPtr[1] = (jint)receiveLen; + _env->ReleaseIntArrayElements(auxData, auxDataPtr, 0); return id; } @@ -1218,15 +1247,18 @@ nMeshGetIndices(JNIEnv *_env, jobject _this, RsContext con, jint mesh, jintArray static const char *classPathName = "android/renderscript/RenderScript"; static JNINativeMethod methods[] = { -{"_nInit", "()V", (void*)_nInit }, -{"nInitElements", "(IIII)V", (void*)nInitElements }, - -{"nDeviceCreate", "()I", (void*)nDeviceCreate }, -{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy }, -{"nDeviceSetConfig", "(III)V", (void*)nDeviceSetConfig }, -{"nContextGetMessage", "(I[IZ)I", (void*)nContextGetMessage }, -{"nContextInitToClient", "(I)V", (void*)nContextInitToClient }, -{"nContextDeinitToClient", "(I)V", (void*)nContextDeinitToClient }, +{"_nInit", "()V", (void*)_nInit }, +{"nInitElements", "(IIII)V", (void*)nInitElements }, + +{"nDeviceCreate", "()I", (void*)nDeviceCreate }, +{"nDeviceDestroy", "(I)V", (void*)nDeviceDestroy }, +{"nDeviceSetConfig", "(III)V", (void*)nDeviceSetConfig }, +{"nContextGetUserMessage", "(I[I)V", (void*)nContextGetUserMessage }, +{"nContextGetErrorMessage", "(I)Ljava/lang/String;", (void*)nContextGetErrorMessage }, +{"nContextPeekMessage", "(I[IZ)I", (void*)nContextPeekMessage }, + +{"nContextInitToClient", "(I)V", (void*)nContextInitToClient }, +{"nContextDeinitToClient", "(I)V", (void*)nContextDeinitToClient }, // All methods below are thread protected in java. |