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:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 },
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user