Merge change 21825 into eclair

* changes:
  Implement OOB destroy method that can be called from the java finalizer removing the need to explicitly destroy objects.
This commit is contained in:
Android (Google) Code Review
2009-08-18 17:15:04 -07:00
7 changed files with 107 additions and 11 deletions

View File

@@ -60,8 +60,13 @@ class BaseObj {
protected void finalize() throws Throwable protected void finalize() throws Throwable
{ {
if (!mDestroyed) { if (!mDestroyed) {
if(mID != 0) {
mRS.nObjDestroyOOB(mID);
}
mID = 0;
mDestroyed = true;
Log.v(RenderScript.LOG_TAG, Log.v(RenderScript.LOG_TAG,
getClass() + " finalized without having released the RS reference."); getClass() + " auto finalizing object without having released the RS reference.");
} }
super.finalize(); super.finalize();
} }

View File

@@ -75,6 +75,7 @@ public class RenderScript {
native void nAssignName(int obj, byte[] name); native void nAssignName(int obj, byte[] name);
native void nObjDestroy(int id); native void nObjDestroy(int id);
native void nObjDestroyOOB(int id);
native int nFileOpen(byte[] name); native int nFileOpen(byte[] name);
native void nElementBegin(); native void nElementBegin();

View File

@@ -86,6 +86,15 @@ nObjDestroy(JNIEnv *_env, jobject _this, jint obj)
rsObjDestroy(con, (void *)obj); rsObjDestroy(con, (void *)obj);
} }
static void
nObjDestroyOOB(JNIEnv *_env, jobject _this, jint obj)
{
// This function only differs from nObjDestroy in that it calls the
// special Out Of Band version of ObjDestroy which is thread safe.
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
LOG_API("nObjDestroyOOB, con(%p) obj(%p)", con, (void *)obj);
rsObjDestroyOOB(con, (void *)obj);
}
static jint static jint
nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str) nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str)
@@ -1217,6 +1226,7 @@ static JNINativeMethod methods[] = {
{"nContextDestroy", "(I)V", (void*)nContextDestroy }, {"nContextDestroy", "(I)V", (void*)nContextDestroy },
{"nAssignName", "(I[B)V", (void*)nAssignName }, {"nAssignName", "(I[B)V", (void*)nAssignName },
{"nObjDestroy", "(I)V", (void*)nObjDestroy }, {"nObjDestroy", "(I)V", (void*)nObjDestroy },
{"nObjDestroyOOB", "(I)V", (void*)nObjDestroyOOB },
{"nFileOpen", "([B)I", (void*)nFileOpen }, {"nFileOpen", "([B)I", (void*)nFileOpen },

View File

@@ -51,6 +51,7 @@ void rsDeviceDestroy(RsDevice);
RsContext rsContextCreate(RsDevice, void *, uint32_t version); RsContext rsContextCreate(RsDevice, void *, uint32_t version);
void rsContextDestroy(RsContext); void rsContextDestroy(RsContext);
void rsObjDestroyOOB(RsContext, void *);
#define RS_MAX_TEXTURE 2 #define RS_MAX_TEXTURE 2

View File

@@ -67,8 +67,6 @@ public class FountainRS {
private RenderScript mRS; private RenderScript mRS;
private Allocation mIntAlloc; private Allocation mIntAlloc;
private Allocation mPartAlloc;
private Script mScript;
private SimpleMesh mSM; private SimpleMesh mSM;
private SomeData mSD; private SomeData mSD;
private Type mSDType; private Type mSDType;
@@ -94,9 +92,9 @@ public class FountainRS {
mSM = smb.create(); mSM = smb.create();
mSM.setName("PartMesh"); mSM.setName("PartMesh");
mPartAlloc = mSM.createVertexAllocation(vtxSlot); Allocation partAlloc = mSM.createVertexAllocation(vtxSlot);
mPartAlloc.setName("PartBuffer"); partAlloc.setName("PartBuffer");
mSM.bindVertexAllocation(mPartAlloc, 0); mSM.bindVertexAllocation(partAlloc, 0);
// All setup of named objects should be done by this point // All setup of named objects should be done by this point
// because we are about to compile the script. // because we are about to compile the script.
@@ -104,12 +102,12 @@ public class FountainRS {
sb.setScript(mRes, R.raw.fountain); sb.setScript(mRes, R.raw.fountain);
sb.setRoot(true); sb.setRoot(true);
sb.setType(mSDType, "Control", 0); sb.setType(mSDType, "Control", 0);
mScript = sb.create(); Script script = sb.create();
mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mScript.bindAllocation(mIntAlloc, 0); script.bindAllocation(mIntAlloc, 0);
mScript.bindAllocation(mPartAlloc, 1); script.bindAllocation(partAlloc, 1);
mRS.contextBindRootScript(mScript); mRS.contextBindRootScript(script);
} }
} }

View File

@@ -170,12 +170,14 @@ void * Context::threadProc(void *vrsc)
mDraw = rsc->runRootScript(); mDraw = rsc->runRootScript();
eglSwapBuffers(rsc->mDisplay, rsc->mSurface); eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
} }
rsc->objDestroyOOBRun();
} }
glClearColor(0,0,0,0); glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(rsc->mDisplay, rsc->mSurface); eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
eglTerminate(rsc->mDisplay); eglTerminate(rsc->mDisplay);
rsc->objDestroyOOBRun();
return NULL; return NULL;
} }
@@ -210,6 +212,8 @@ Context::Context(Device *dev, Surface *sur)
mWndSurface = sur; mWndSurface = sur;
objDestroyOOBInit();
LOGV("RS Launching thread"); LOGV("RS Launching thread");
status = pthread_create(&mThreadId, &threadAttr, threadProc, this); status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
if (status) { if (status) {
@@ -229,11 +233,14 @@ Context::~Context()
void *res; void *res;
int status = pthread_join(mThreadId, &res); int status = pthread_join(mThreadId, &res);
objDestroyOOBRun();
if (mDev) { if (mDev) {
mDev->removeContext(this); mDev->removeContext(this);
pthread_key_delete(gThreadTLSKey); pthread_key_delete(gThreadTLSKey);
} }
objDestroyOOBDestroy();
} }
void Context::swapBuffers() void Context::swapBuffers()
@@ -345,6 +352,62 @@ void Context::appendVarDefines(String8 *str) const
} }
} }
bool Context::objDestroyOOBInit()
{
int status = pthread_mutex_init(&mObjDestroy.mMutex, NULL);
if (status) {
LOGE("Context::ObjDestroyOOBInit mutex init failure");
return false;
}
return true;
}
void Context::objDestroyOOBRun()
{
if (mObjDestroy.mNeedToEmpty) {
int status = pthread_mutex_lock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
return;
}
for (size_t ct = 0; ct < mObjDestroy.mDestroyList.size(); ct++) {
mObjDestroy.mDestroyList[ct]->decRef();
}
mObjDestroy.mDestroyList.clear();
mObjDestroy.mNeedToEmpty = false;
status = pthread_mutex_unlock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
}
}
}
void Context::objDestroyOOBDestroy()
{
rsAssert(!mObjDestroy.mNeedToEmpty);
pthread_mutex_destroy(&mObjDestroy.mMutex);
}
void Context::objDestroyAdd(ObjectBase *obj)
{
int status = pthread_mutex_lock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i locking for OOBRun.", status);
return;
}
mObjDestroy.mNeedToEmpty = true;
mObjDestroy.mDestroyList.add(obj);
status = pthread_mutex_unlock(&mObjDestroy.mMutex);
if (status) {
LOGE("Context::ObjDestroyOOBRun: error %i unlocking for set condition.", status);
}
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// //
@@ -429,3 +492,9 @@ void rsContextDestroy(RsContext vrsc)
delete rsc; delete rsc;
} }
void rsObjDestroyOOB(RsContext vrsc, void *obj)
{
Context * rsc = static_cast<Context *>(vrsc);
rsc->objDestroyAdd(static_cast<ObjectBase *>(obj));
}

View File

@@ -118,6 +118,7 @@ public:
ThreadIO mIO; ThreadIO mIO;
void objDestroyAdd(ObjectBase *);
protected: protected:
Device *mDev; Device *mDev;
@@ -142,6 +143,17 @@ protected:
ObjectBaseRef<ProgramVertex> mVertex; ObjectBaseRef<ProgramVertex> mVertex;
ObjectBaseRef<ProgramFragmentStore> mFragmentStore; ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
struct ObjDestroyOOB {
pthread_mutex_t mMutex;
Vector<ObjectBase *> mDestroyList;
bool mNeedToEmpty;
};
ObjDestroyOOB mObjDestroy;
bool objDestroyOOBInit();
void objDestroyOOBRun();
void objDestroyOOBDestroy();
private: private:
Context(); Context();