diff options
Diffstat (limited to 'libs/rs/rsObjectBase.cpp')
-rw-r--r-- | libs/rs/rsObjectBase.cpp | 106 |
1 files changed, 91 insertions, 15 deletions
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp index 7e7afabe0550..acfc5ceede67 100644 --- a/libs/rs/rsObjectBase.cpp +++ b/libs/rs/rsObjectBase.cpp @@ -15,22 +15,39 @@ */ #include "rsObjectBase.h" +#include "rsContext.h" using namespace android; using namespace android::renderscript; -ObjectBase::ObjectBase() +ObjectBase::ObjectBase(Context *rsc) { mUserRefCount = 0; mSysRefCount = 0; mName = NULL; + mRSC = NULL; + mNext = NULL; + mPrev = NULL; + setContext(rsc); } ObjectBase::~ObjectBase() { - //LOGV("~ObjectBase %p ref %i", this, mRefCount); + //LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount); rsAssert(!mUserRefCount); rsAssert(!mSysRefCount); + remove(); +} + +void ObjectBase::setContext(Context *rsc) +{ + if (mRSC) { + remove(); + } + mRSC = rsc; + if (rsc) { + add(); + } } void ObjectBase::incUserRef() const @@ -45,11 +62,8 @@ void ObjectBase::incSysRef() const //LOGV("ObjectBase %p inc ref %i", this, mRefCount); } -void ObjectBase::decUserRef() const +bool ObjectBase::checkDelete() const { - rsAssert(mUserRefCount > 0); - mUserRefCount --; - //LOGV("ObjectBase %p dec ref %i", this, mRefCount); if (!(mSysRefCount | mUserRefCount)) { if (mName) { LOGV("Deleting RS object %p, name %s", this, mName); @@ -57,22 +71,32 @@ void ObjectBase::decUserRef() const LOGV("Deleting RS object %p, no name", this); } delete this; + return true; } + return false; } -void ObjectBase::decSysRef() const +bool ObjectBase::decUserRef() const +{ + rsAssert(mUserRefCount > 0); + mUserRefCount --; + //LOGV("ObjectBase %p dec ref %i", this, mRefCount); + return checkDelete(); +} + +bool ObjectBase::zeroUserRef() const +{ + mUserRefCount = 0; + //LOGV("ObjectBase %p dec ref %i", this, mRefCount); + return checkDelete(); +} + +bool ObjectBase::decSysRef() const { rsAssert(mSysRefCount > 0); mSysRefCount --; //LOGV("ObjectBase %p dec ref %i", this, mRefCount); - if (!(mSysRefCount | mUserRefCount)) { - if (mName) { - LOGV("Deleting RS object %p, name %s", this, mName); - } else { - LOGV("Deleting RS object %p, no name", this); - } - delete this; - } + return checkDelete(); } void ObjectBase::setName(const char *name) @@ -96,3 +120,55 @@ void ObjectBase::setName(const char *name, uint32_t len) } } +void ObjectBase::add() const +{ + rsAssert(!mNext); + rsAssert(!mPrev); + //LOGV("calling add rsc %p", mRSC); + mNext = mRSC->mObjHead; + if (mRSC->mObjHead) { + mRSC->mObjHead->mPrev = this; + } + mRSC->mObjHead = this; +} + +void ObjectBase::remove() const +{ + //LOGV("calling remove rsc %p", mRSC); + if (!mRSC) { + rsAssert(!mPrev); + rsAssert(!mNext); + return; + } + if (mRSC->mObjHead == this) { + mRSC->mObjHead = mNext; + } + if (mPrev) { + mPrev->mNext = mNext; + } + if (mNext) { + mNext->mPrev = mPrev; + } + mPrev = NULL; + mNext = NULL; +} + +void ObjectBase::zeroAllUserRef(Context *rsc) +{ + LOGV("Forcing release of all outstanding user refs."); + + // This operation can be slow, only to be called during context cleanup. + const ObjectBase * o = rsc->mObjHead; + while (o) { + //LOGE("o %p", o); + if (o->zeroUserRef()) { + // deleted the object and possibly others, restart from head. + o = rsc->mObjHead; + //LOGE("o head %p", o); + } else { + o = o->mNext; + //LOGE("o next %p", o); + } + } +} + |