diff options
| author | 2009-11-12 18:45:53 -0800 | |
|---|---|---|
| committer | 2009-11-13 13:53:39 -0800 | |
| commit | 9db3d07b9620b4269ab33f78604a36327e536ce1 (patch) | |
| tree | 41e294f34b9695187af098cd42167489fb0c8fb0 /libs/rs/rsObjectBase.cpp | |
| parent | 6c63ee4fc4acae4bbbbd2a49e0a68206221f0de0 (diff) | |
eclair snapshot
Diffstat (limited to 'libs/rs/rsObjectBase.cpp')
| -rw-r--r-- | libs/rs/rsObjectBase.cpp | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp new file mode 100644 index 000000000000..b7d67cca4b3c --- /dev/null +++ b/libs/rs/rsObjectBase.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rsObjectBase.h" +#include "rsContext.h" + +using namespace android; +using namespace android::renderscript; + +ObjectBase::ObjectBase(Context *rsc) +{ + mUserRefCount = 0; + mSysRefCount = 0; + mName = NULL; + mRSC = NULL; + mNext = NULL; + mPrev = NULL; + mAllocFile = __FILE__; + mAllocLine = __LINE__; + setContext(rsc); +} + +ObjectBase::~ObjectBase() +{ + //LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount); + rsAssert(!mUserRefCount); + rsAssert(!mSysRefCount); + remove(); + delete[] mName; +} + +void ObjectBase::dumpLOGV(const char *op) const +{ + if (mName) { + LOGV("%s RSobj %p, name %s, refs %i,%i from %s,%i links %p,%p,%p", + op, this, mName, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC); + } else { + LOGV("%s RSobj %p, no-name, refs %i,%i from %s,%i links %p,%p,%p", + op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC); + } +} + +void ObjectBase::setContext(Context *rsc) +{ + if (mRSC) { + remove(); + } + mRSC = rsc; + if (rsc) { + add(); + } +} + +void ObjectBase::incUserRef() const +{ + mUserRefCount ++; + //LOGV("ObjectBase %p inc ref %i", this, mRefCount); +} + +void ObjectBase::incSysRef() const +{ + mSysRefCount ++; + //LOGV("ObjectBase %p inc ref %i", this, mRefCount); +} + +bool ObjectBase::checkDelete() const +{ + if (!(mSysRefCount | mUserRefCount)) { + if (mRSC && mRSC->props.mLogObjects) { + dumpLOGV("checkDelete"); + } + delete this; + return true; + } + return false; +} + +bool ObjectBase::decUserRef() const +{ + rsAssert(mUserRefCount > 0); + mUserRefCount --; + //dumpObj("decUserRef"); + return checkDelete(); +} + +bool ObjectBase::zeroUserRef() const +{ + mUserRefCount = 0; + //dumpObj("zeroUserRef"); + return checkDelete(); +} + +bool ObjectBase::decSysRef() const +{ + rsAssert(mSysRefCount > 0); + mSysRefCount --; + //dumpObj("decSysRef"); + return checkDelete(); +} + +void ObjectBase::setName(const char *name) +{ + setName(name, strlen(name)); +} + +void ObjectBase::setName(const char *name, uint32_t len) +{ + delete mName; + mName = NULL; + if (name) { + mName = new char[len + 1]; + memcpy(mName, name, len); + mName[len] = 0; + } +} + +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) +{ + if (rsc->props.mLogObjects) { + 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); + } + } + + if (rsc->props.mLogObjects) { + LOGV("Objects remaining."); + o = rsc->mObjHead; + while (o) { + o->dumpLOGV(" "); + o = o->mNext; + } + } +} + |