Loading graphics/java/android/renderscript/RenderScript.java +55 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -190,6 +193,7 @@ public class RenderScript { private int mContext; @SuppressWarnings({"FieldCanBeLocal"}) private Surface mSurface; private MessageThread mMessageThread; Element mElement_USER_U8; Loading @@ -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(); Loading @@ -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; Loading graphics/jni/android_renderscript_RenderScript.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 }, Loading libs/rs/RenderScript.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading libs/rs/rsContext.cpp +77 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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(); } /////////////////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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(); } libs/rs/rsContext.h +6 −0 Original line number Diff line number Diff line Loading @@ -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(); } Loading Loading
graphics/java/android/renderscript/RenderScript.java +55 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading @@ -190,6 +193,7 @@ public class RenderScript { private int mContext; @SuppressWarnings({"FieldCanBeLocal"}) private Surface mSurface; private MessageThread mMessageThread; Element mElement_USER_U8; Loading @@ -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(); Loading @@ -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; Loading
graphics/jni/android_renderscript_RenderScript.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 }, Loading
libs/rs/RenderScript.h +4 −0 Original line number Diff line number Diff line Loading @@ -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 { Loading
libs/rs/rsContext.cpp +77 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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(); } /////////////////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -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(); }
libs/rs/rsContext.h +6 −0 Original line number Diff line number Diff line Loading @@ -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(); } Loading