rsObjectBase.cpp revision fb6b614bcea88a587a7ea4530be45ff0ffa0210e
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 mRSC = rsc; 65 if (rsc) { 66 add(); 67 } 68} 69 70void ObjectBase::incUserRef() const 71{ 72 mUserRefCount ++; 73 //LOGV("ObjectBase %p inc ref %i", this, mRefCount); 74} 75 76void ObjectBase::incSysRef() const 77{ 78 mSysRefCount ++; 79 //LOGV("ObjectBase %p inc ref %i", this, mRefCount); 80} 81 82bool ObjectBase::checkDelete() const 83{ 84 if (!(mSysRefCount | mUserRefCount)) { 85 if (mRSC && mRSC->props.mLogObjects) { 86 dumpLOGV("checkDelete"); 87 } 88 delete this; 89 return true; 90 } 91 return false; 92} 93 94bool ObjectBase::decUserRef() const 95{ 96 rsAssert(mUserRefCount > 0); 97 mUserRefCount --; 98 //dumpObj("decUserRef"); 99 return checkDelete(); 100} 101 102bool ObjectBase::zeroUserRef() const 103{ 104 mUserRefCount = 0; 105 //dumpObj("zeroUserRef"); 106 return checkDelete(); 107} 108 109bool ObjectBase::decSysRef() const 110{ 111 rsAssert(mSysRefCount > 0); 112 mSysRefCount --; 113 //dumpObj("decSysRef"); 114 return checkDelete(); 115} 116 117void ObjectBase::setName(const char *name) 118{ 119 mName.setTo(name); 120} 121 122void ObjectBase::setName(const char *name, uint32_t len) 123{ 124 mName.setTo(name, len); 125} 126 127void ObjectBase::add() const 128{ 129 rsAssert(!mNext); 130 rsAssert(!mPrev); 131 //LOGV("calling add rsc %p", mRSC); 132 mNext = mRSC->mObjHead; 133 if (mRSC->mObjHead) { 134 mRSC->mObjHead->mPrev = this; 135 } 136 mRSC->mObjHead = this; 137} 138 139void ObjectBase::remove() const 140{ 141 //LOGV("calling remove rsc %p", mRSC); 142 if (!mRSC) { 143 rsAssert(!mPrev); 144 rsAssert(!mNext); 145 return; 146 } 147 if (mRSC->mObjHead == this) { 148 mRSC->mObjHead = mNext; 149 } 150 if (mPrev) { 151 mPrev->mNext = mNext; 152 } 153 if (mNext) { 154 mNext->mPrev = mPrev; 155 } 156 mPrev = NULL; 157 mNext = NULL; 158} 159 160void ObjectBase::zeroAllUserRef(Context *rsc) 161{ 162 if (rsc->props.mLogObjects) { 163 LOGV("Forcing release of all outstanding user refs."); 164 } 165 166 // This operation can be slow, only to be called during context cleanup. 167 const ObjectBase * o = rsc->mObjHead; 168 while (o) { 169 //LOGE("o %p", o); 170 if (o->zeroUserRef()) { 171 // deleted the object and possibly others, restart from head. 172 o = rsc->mObjHead; 173 //LOGE("o head %p", o); 174 } else { 175 o = o->mNext; 176 //LOGE("o next %p", o); 177 } 178 } 179 180 if (rsc->props.mLogObjects) { 181 LOGV("Objects remaining."); 182 dumpAll(rsc); 183 } 184} 185 186void ObjectBase::dumpAll(Context *rsc) 187{ 188 LOGV("Dumping all objects"); 189 const ObjectBase * o = rsc->mObjHead; 190 while (o) { 191 LOGV(" Object %p", o); 192 o->dumpLOGV(" "); 193 o = o->mNext; 194 } 195} 196 197