summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--graphics/java/android/renderscript/RenderScript.java55
-rw-r--r--graphics/jni/android_renderscript_RenderScript.cpp34
-rw-r--r--libs/rs/RenderScript.h4
-rw-r--r--libs/rs/rsContext.cpp77
-rw-r--r--libs/rs/rsContext.h6
-rw-r--r--libs/rs/rsLocklessFifo.cpp6
-rw-r--r--libs/rs/rsScriptC_Lib.cpp8
-rw-r--r--libs/rs/rsThreadIO.cpp1
-rw-r--r--libs/rs/rsThreadIO.h2
9 files changed, 192 insertions, 1 deletions
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 6b0b696..1f2ea38 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 9054b65..fa3baa2 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 87a2f4a..9b04393 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 169d5d4..a1e9e45 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 cef421d..b56e7d7 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 b0540a6..085a81e 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 17d14f5..9a96290 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 4d3d73a..527b3d7 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 1f6a0c2..95270f5 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;