rsObjectBase.cpp revision 605048a9f9af925782f6c90bc1cdc5af59e337d8
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "rsObjectBase.h" 18 19#ifndef ANDROID_RS_BUILD_FOR_HOST 20#include "rsContext.h" 21#else 22#include "rsContextHostStub.h" 23#endif 24 25using namespace android; 26using namespace android::renderscript; 27 28ObjectBase::ObjectBase(Context *rsc) 29{ 30 mUserRefCount = 0; 31 mSysRefCount = 0; 32 mRSC = NULL; 33 mNext = NULL; 34 mPrev = NULL; 35 mAllocFile = __FILE__; 36 mAllocLine = __LINE__; 37 setContext(rsc); 38} 39 40ObjectBase::~ObjectBase() 41{ 42 //LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount); 43 rsAssert(!mUserRefCount); 44 rsAssert(!mSysRefCount); 45 remove(); 46} 47 48void ObjectBase::dumpLOGV(const char *op) const 49{ 50 if (mName.size()) { 51 LOGV("%s RSobj %p, name %s, refs %i,%i from %s,%i links %p,%p,%p", 52 op, this, mName.string(), mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC); 53 } else { 54 LOGV("%s RSobj %p, no-name, refs %i,%i from %s,%i links %p,%p,%p", 55 op, this, mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC); 56 } 57} 58 59void ObjectBase::setContext(Context *rsc) 60{ 61 if (mRSC) { 62 remove(); 63 } 64 rsAssert(rsc); 65 mRSC = rsc; 66 if (rsc) { 67 add(); 68 } 69} 70 71void ObjectBase::incUserRef() const 72{ 73 mUserRefCount ++; 74 //LOGV("ObjectBase %p inc ref %i", this, mRefCount); 75} 76 77void ObjectBase::incSysRef() const 78{ 79 mSysRefCount ++; 80 //LOGV("ObjectBase %p inc ref %i", this, mRefCount); 81} 82 83bool ObjectBase::checkDelete() const 84{ 85 if (!(mSysRefCount | mUserRefCount)) { 86 if (mRSC && mRSC->props.mLogObjects) { 87 dumpLOGV("checkDelete"); 88 } 89 delete this; 90 return true; 91 } 92 return false; 93} 94 95bool ObjectBase::decUserRef() const 96{ 97 rsAssert(mUserRefCount > 0); 98 mUserRefCount --; 99 //dumpObj("decUserRef"); 100 return checkDelete(); 101} 102 103bool ObjectBase::zeroUserRef() const 104{ 105 mUserRefCount = 0; 106 //dumpObj("zeroUserRef"); 107 return checkDelete(); 108} 109 110bool ObjectBase::decSysRef() const 111{ 112 rsAssert(mSysRefCount > 0); 113 mSysRefCount --; 114 //dumpObj("decSysRef"); 115 return checkDelete(); 116} 117 118void ObjectBase::setName(const char *name) 119{ 120 mName.setTo(name); 121} 122 123void ObjectBase::setName(const char *name, uint32_t len) 124{ 125 mName.setTo(name, len); 126} 127 128void ObjectBase::add() const 129{ 130 rsAssert(!mNext); 131 rsAssert(!mPrev); 132 //LOGV("calling add rsc %p", mRSC); 133 mNext = mRSC->mObjHead; 134 if (mRSC->mObjHead) { 135 mRSC->mObjHead->mPrev = this; 136 } 137 mRSC->mObjHead = this; 138} 139 140void ObjectBase::remove() const 141{ 142 //LOGV("calling remove rsc %p", mRSC); 143 if (!mRSC) { 144 rsAssert(!mPrev); 145 rsAssert(!mNext); 146 return; 147 } 148 if (mRSC->mObjHead == this) { 149 mRSC->mObjHead = mNext; 150 } 151 if (mPrev) { 152 mPrev->mNext = mNext; 153 } 154 if (mNext) { 155 mNext->mPrev = mPrev; 156 } 157 mPrev = NULL; 158 mNext = NULL; 159} 160 161void ObjectBase::zeroAllUserRef(Context *rsc) 162{ 163 if (rsc->props.mLogObjects) { 164 LOGV("Forcing release of all outstanding user refs."); 165 } 166 167 // This operation can be slow, only to be called during context cleanup. 168 const ObjectBase * o = rsc->mObjHead; 169 while (o) { 170 //LOGE("o %p", o); 171 if (o->zeroUserRef()) { 172 // deleted the object and possibly others, restart from head. 173 o = rsc->mObjHead; 174 //LOGE("o head %p", o); 175 } else { 176 o = o->mNext; 177 //LOGE("o next %p", o); 178 } 179 } 180 181 if (rsc->props.mLogObjects) { 182 LOGV("Objects remaining."); 183 dumpAll(rsc); 184 } 185} 186 187void ObjectBase::dumpAll(Context *rsc) 188{ 189 LOGV("Dumping all objects"); 190 const ObjectBase * o = rsc->mObjHead; 191 while (o) { 192 LOGV(" Object %p", o); 193 o->dumpLOGV(" "); 194 o = o->mNext; 195 } 196} 197 198bool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj) 199{ 200 const ObjectBase * o = rsc->mObjHead; 201 while (o) { 202 if (o == obj) { 203 return true; 204 } 205 o = o->mNext; 206 } 207 return false; 208} 209 210