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
{
if (!mDestroyed) {
if(mID != 0) {
mRS.nObjDestroyOOB(mID);
}
mID = 0;
mDestroyed = true;
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();
}

View File

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

View File

@@ -86,6 +86,15 @@ nObjDestroy(JNIEnv *_env, jobject _this, jint 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
nFileOpen(JNIEnv *_env, jobject _this, jbyteArray str)
@@ -1217,6 +1226,7 @@ static JNINativeMethod methods[] = {
{"nContextDestroy", "(I)V", (void*)nContextDestroy },
{"nAssignName", "(I[B)V", (void*)nAssignName },
{"nObjDestroy", "(I)V", (void*)nObjDestroy },
{"nObjDestroyOOB", "(I)V", (void*)nObjDestroyOOB },
{"nFileOpen", "([B)I", (void*)nFileOpen },

View File

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

View File

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

View File

@@ -170,12 +170,14 @@ void * Context::threadProc(void *vrsc)
mDraw = rsc->runRootScript();
eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
}
rsc->objDestroyOOBRun();
}
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(rsc->mDisplay, rsc->mSurface);
eglTerminate(rsc->mDisplay);
rsc->objDestroyOOBRun();
return NULL;
}
@@ -210,6 +212,8 @@ Context::Context(Device *dev, Surface *sur)
mWndSurface = sur;
objDestroyOOBInit();
LOGV("RS Launching thread");
status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
if (status) {
@@ -229,11 +233,14 @@ Context::~Context()
void *res;
int status = pthread_join(mThreadId, &res);
objDestroyOOBRun();
if (mDev) {
mDev->removeContext(this);
pthread_key_delete(gThreadTLSKey);
}
objDestroyOOBDestroy();
}
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;
}
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;
void objDestroyAdd(ObjectBase *);
protected:
Device *mDev;
@@ -142,6 +143,17 @@ protected:
ObjectBaseRef<ProgramVertex> mVertex;
ObjectBaseRef<ProgramFragmentStore> mFragmentStore;
struct ObjDestroyOOB {
pthread_mutex_t mMutex;
Vector<ObjectBase *> mDestroyList;
bool mNeedToEmpty;
};
ObjDestroyOOB mObjDestroy;
bool objDestroyOOBInit();
void objDestroyOOBRun();
void objDestroyOOBDestroy();
private:
Context();