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