diff options
author | 2009-10-06 13:58:47 -0700 | |
---|---|---|
committer | 2009-10-06 13:58:47 -0700 | |
commit | 516c31911578db8ce53529483c3ded918ac7dc6b (patch) | |
tree | eee49f301e720ddfa249375abf611d550a0fba5d | |
parent | f7ae77cd67f1a3993b8e56c1af4720a7adf4e69d (diff) |
Implement data push from scripts. Fixes the problem where apps would have to poll to monitor a scripts state.
Fix bug in StoreState where state could be overridden by the default unless the script used more than one state.
Change only impacts renderscript and renderscript apps.
-rw-r--r-- | graphics/java/android/renderscript/RenderScript.java | 55 | ||||
-rw-r--r-- | graphics/jni/android_renderscript_RenderScript.cpp | 34 | ||||
-rw-r--r-- | libs/rs/RenderScript.h | 4 | ||||
-rw-r--r-- | libs/rs/rsContext.cpp | 77 | ||||
-rw-r--r-- | libs/rs/rsContext.h | 6 | ||||
-rw-r--r-- | libs/rs/rsLocklessFifo.cpp | 6 | ||||
-rw-r--r-- | libs/rs/rsScriptC_Lib.cpp | 8 | ||||
-rw-r--r-- | libs/rs/rsThreadIO.cpp | 1 | ||||
-rw-r--r-- | libs/rs/rsThreadIO.h | 2 |
9 files changed, 192 insertions, 1 deletions
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index 6b0b69610d9b..1f2ea38faf9c 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -75,6 +75,9 @@ public class RenderScript { native void nContextAddDefineF(String name, float value); native void nContextPause(); native void nContextResume(); + native int nContextGetMessage(int[] data, boolean wait); + native void nContextInitToClient(); + native void nContextDeinitToClient(); native void nAssignName(int obj, byte[] name); native void nObjDestroy(int id); @@ -190,6 +193,7 @@ public class RenderScript { private int mContext; @SuppressWarnings({"FieldCanBeLocal"}) private Surface mSurface; + private MessageThread mMessageThread; Element mElement_USER_U8; @@ -214,6 +218,52 @@ public class RenderScript { /////////////////////////////////////////////////////////////////////////////////// // + public static class RSMessage implements Runnable { + protected int[] mData; + protected int mID; + public void run() { + } + } + public RSMessage mMessageCallback = null; + + private static class MessageThread extends Thread { + RenderScript mRS; + boolean mRun = true; + + MessageThread(RenderScript rs) { + super("RSMessageThread"); + mRS = rs; + + } + + public void run() { + // This function is a temporary solution. The final solution will + // used typed allocations where the message id is the type indicator. + int[] rbuf = new int[16]; + mRS.nContextInitToClient(); + while(mRun) { + int msg = mRS.nContextGetMessage(rbuf, true); + if (msg == 0) { + // Should only happen during 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) { + } + } + if(mRS.mMessageCallback != null) { + mRS.mMessageCallback.mData = rbuf; + mRS.mMessageCallback.mID = msg; + mRS.mMessageCallback.run(); + } + //Log.d("rs", "MessageThread msg " + msg + " v1 " + rbuf[0] + " v2 " + rbuf[1] + " v3 " +rbuf[2]); + } + Log.d("rs", "MessageThread exiting."); + } + } + public RenderScript(Surface sur, boolean useDepth, boolean forceSW) { mSurface = sur; mDev = nDeviceCreate(); @@ -222,9 +272,14 @@ public class RenderScript { } mContext = nContextCreate(mDev, mSurface, 0, useDepth); Element.initPredefined(this); + mMessageThread = new MessageThread(this); + mMessageThread.start(); } public void destroy() { + nContextDeinitToClient(); + mMessageThread.mRun = false; + nContextDestroy(mContext); mContext = 0; diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index 9054b6557ef0..fa3baa200fe3 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -194,6 +194,37 @@ nContextResume(JNIEnv *_env, jobject _this) rsContextResume(con); } +static jint +nContextGetMessage(JNIEnv *_env, jobject _this, jintArray data, jboolean wait) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + 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); + if (!id && receiveLen) { + LOGE("message receive buffer too small. %i", receiveLen); + } + _env->ReleaseIntArrayElements(data, ptr, 0); + return id; +} + +static void nContextInitToClient(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextInitToClient, con(%p)", con); + rsContextInitToClient(con); +} + +static void nContextDeinitToClient(JNIEnv *_env, jobject _this) +{ + RsContext con = (RsContext)(_env->GetIntField(_this, gContextId)); + LOG_API("nContextDeinitToClient, con(%p)", con); + rsContextDeinitToClient(con); +} + + static void nElementBegin(JNIEnv *_env, jobject _this) { @@ -1303,6 +1334,9 @@ static JNINativeMethod methods[] = { {"nAssignName", "(I[B)V", (void*)nAssignName }, {"nObjDestroy", "(I)V", (void*)nObjDestroy }, {"nObjDestroyOOB", "(I)V", (void*)nObjDestroyOOB }, +{"nContextGetMessage", "([IZ)I", (void*)nContextGetMessage }, +{"nContextInitToClient", "()V", (void*)nContextInitToClient }, +{"nContextDeinitToClient", "()V", (void*)nContextDeinitToClient }, {"nFileOpen", "([B)I", (void*)nFileOpen }, diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h index 87a2f4a8f6ec..9b043930d520 100644 --- a/libs/rs/RenderScript.h +++ b/libs/rs/RenderScript.h @@ -59,6 +59,10 @@ RsContext rsContextCreate(RsDevice, void *, uint32_t version, bool useDepth); void rsContextDestroy(RsContext); void rsObjDestroyOOB(RsContext, void *); +uint32_t rsContextGetMessage(RsContext, void *data, size_t *receiveLen, size_t bufferLen, bool wait); +void rsContextInitToClient(RsContext); +void rsContextDeinitToClient(RsContext); + #define RS_MAX_TEXTURE 2 enum RsDataType { diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 169d5d40ecaf..a1e9e45335ff 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -142,6 +142,7 @@ bool Context::runRootScript() if (this->props.mLogTimes) { timerSet(RS_TIMER_SCRIPT); } + mStateFragmentStore.mLast.clear(); bool ret = runScript(mRootScript.get(), 0); return ret; } @@ -529,6 +530,64 @@ void Context::objDestroyAdd(ObjectBase *obj) } } +uint32_t Context::getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait) +{ + //LOGE("getMessageToClient %i %i", bufferLen, wait); + if (!wait) { + if (mIO.mToClient.isEmpty()) { + // No message to get and not going to wait for one. + receiveLen = 0; + return 0; + } + } + + //LOGE("getMessageToClient 2 con=%p", this); + uint32_t bytesData = 0; + uint32_t commandID = 0; + const void *d = mIO.mToClient.get(&commandID, &bytesData); + //LOGE("getMessageToClient 3 %i %i", commandID, bytesData); + + *receiveLen = bytesData; + if (bufferLen >= bytesData) { + memcpy(data, d, bytesData); + mIO.mToClient.next(); + return commandID; + } + return 0; +} + +bool Context::sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace) +{ + //LOGE("sendMessageToClient %i %i %i", cmdID, len, waitForSpace); + if (cmdID == 0) { + LOGE("Attempting to send invalid command 0 to client."); + return false; + } + if (!waitForSpace) { + if (mIO.mToClient.getFreeSpace() < len) { + // Not enough room, and not waiting. + return false; + } + } + //LOGE("sendMessageToClient 2"); + void *p = mIO.mToClient.reserve(len); + memcpy(p, data, len); + mIO.mToClient.commit(cmdID, len); + //LOGE("sendMessageToClient 3"); + return true; +} + +void Context::initToClient() +{ + while(!mRunning) { + usleep(100); + } +} + +void Context::deinitToClient() +{ + mIO.mToClient.shutdown(); +} /////////////////////////////////////////////////////////////////////////////////////////// @@ -636,3 +695,21 @@ void rsObjDestroyOOB(RsContext vrsc, void *obj) rsc->objDestroyAdd(static_cast<ObjectBase *>(obj)); } +uint32_t rsContextGetMessage(RsContext vrsc, void *data, size_t *receiveLen, size_t bufferLen, bool wait) +{ + Context * rsc = static_cast<Context *>(vrsc); + return rsc->getMessageToClient(data, receiveLen, bufferLen, wait); +} + +void rsContextInitToClient(RsContext vrsc) +{ + Context * rsc = static_cast<Context *>(vrsc); + rsc->initToClient(); +} + +void rsContextDeinitToClient(RsContext vrsc) +{ + Context * rsc = static_cast<Context *>(vrsc); + rsc->deinitToClient(); +} + diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h index cef421d73b14..b56e7d7f8476 100644 --- a/libs/rs/rsContext.h +++ b/libs/rs/rsContext.h @@ -97,6 +97,12 @@ public: void appendNameDefines(String8 *str) const; void appendVarDefines(String8 *str) const; + uint32_t getMessageToClient(void *data, size_t *receiveLen, size_t bufferLen, bool wait); + bool sendMessageToClient(void *data, uint32_t cmdID, size_t len, bool waitForSpace); + + void initToClient(); + void deinitToClient(); + ProgramFragment * getDefaultProgramFragment() const { return mStateFragment.mDefault.get(); } diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp index b0540a6eac47..085a81e751bb 100644 --- a/libs/rs/rsLocklessFifo.cpp +++ b/libs/rs/rsLocklessFifo.cpp @@ -99,6 +99,9 @@ void * LocklessCommandFifo::reserve(uint32_t sizeInBytes) void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) { + if (mInShutdown) { + return; + } //dumpState("commit 1"); reinterpret_cast<uint16_t *>(mPut)[0] = command; reinterpret_cast<uint16_t *>(mPut)[1] = sizeInBytes; @@ -109,6 +112,9 @@ void LocklessCommandFifo::commit(uint32_t command, uint32_t sizeInBytes) void LocklessCommandFifo::commitSync(uint32_t command, uint32_t sizeInBytes) { + if (mInShutdown) { + return; + } commit(command, sizeInBytes); flush(); } diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp index 17d14f5b7204..9a962907a100 100644 --- a/libs/rs/rsScriptC_Lib.cpp +++ b/libs/rs/rsScriptC_Lib.cpp @@ -1002,6 +1002,12 @@ static uint32_t SC_colorFloatRGBAto565(float r, float g, float b) return rs888to565(ir, ig, ib); } +static uint32_t SC_toClient(void *data, int cmdID, int len, int waitForSpace) +{ + GET_TLS(); + return rsc->sendMessageToClient(data, cmdID, len, waitForSpace != 0); +} + ////////////////////////////////////////////////////////////////////////////// // Class implementation ////////////////////////////////////////////////////////////////////////////// @@ -1270,6 +1276,8 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = { { "getHeight", (void *)&SC_getHeight, "int", "()" }, + { "sendToClient", (void *)&SC_toClient, + "int", "(void *data, int cmdID, int len, int waitForSpace)" }, { "debugF", (void *)&SC_debugF, diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp index 4d3d73a93bf1..527b3d7dbabb 100644 --- a/libs/rs/rsThreadIO.cpp +++ b/libs/rs/rsThreadIO.cpp @@ -24,6 +24,7 @@ using namespace android::renderscript; ThreadIO::ThreadIO() { mToCore.init(16 * 1024); + mToClient.init(1024); } ThreadIO::~ThreadIO() diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h index 1f6a0c28dcc1..95270f594302 100644 --- a/libs/rs/rsThreadIO.h +++ b/libs/rs/rsThreadIO.h @@ -39,7 +39,7 @@ public: LocklessCommandFifo mToCore; - //LocklessCommandFifo mToClient; + LocklessCommandFifo mToClient; intptr_t mToCoreRet; |