summaryrefslogtreecommitdiff
path: root/libs/rs/rsObjectBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsObjectBase.cpp')
-rw-r--r--libs/rs/rsObjectBase.cpp106
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);
+ }
+ }
+}
+