summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorJason Sams <rjsams@android.com>2010-10-21 14:06:55 -0700
committerJason Sams <rjsams@android.com>2010-10-21 21:17:30 -0700
commitb38d534873ca514f5a5230596c838aa37eca1568 (patch)
tree4473cccf239e0a97597db92052508b2149309ad1 /libs
parent4924aee9cb1c5988359f3162b6e89689c5b101e1 (diff)
downloadframeworks_base-b38d534873ca514f5a5230596c838aa37eca1568.zip
frameworks_base-b38d534873ca514f5a5230596c838aa37eca1568.tar.gz
frameworks_base-b38d534873ca514f5a5230596c838aa37eca1568.tar.bz2
Fix refcounting bugs where the sys refcount
could be corrupted during async type creation. Change-Id: If42828e92990598b0cb5da81c82ea513f94725f2 Fix stack object deletion bug. Change-Id: I2c723aa5ad15e0c99dc9cd0cfbc7db80bace172a
Diffstat (limited to 'libs')
-rw-r--r--libs/rs/RenderScript.h2
-rw-r--r--libs/rs/rsAdapter.cpp12
-rw-r--r--libs/rs/rsAllocation.cpp4
-rw-r--r--libs/rs/rsElement.cpp4
-rw-r--r--libs/rs/rsFont.cpp4
-rw-r--r--libs/rs/rsMesh.cpp2
-rw-r--r--libs/rs/rsObjectBase.cpp137
-rw-r--r--libs/rs/rsObjectBase.h33
-rw-r--r--libs/rs/rsProgram.cpp4
-rw-r--r--libs/rs/rsProgramFragment.cpp7
-rw-r--r--libs/rs/rsProgramRaster.cpp2
-rw-r--r--libs/rs/rsProgramStore.cpp9
-rw-r--r--libs/rs/rsProgramVertex.cpp3
-rw-r--r--libs/rs/rsSampler.cpp4
-rw-r--r--libs/rs/rsScript.cpp2
-rw-r--r--libs/rs/rsScriptC.cpp6
-rw-r--r--libs/rs/rsType.cpp22
-rw-r--r--libs/rs/rsType.h3
18 files changed, 130 insertions, 130 deletions
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index e63cc9b..d078d46 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -288,7 +288,7 @@ typedef struct {
// Async commands for returning new IDS
-void * rsaTypeCreate(RsContext, RsElement, uint32_t dimCount,
+RsType rsaTypeCreate(RsContext, RsElement, uint32_t dimCount,
const RsDimension *dims, const uint32_t *vals);
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index ef69b75..1d1425c 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -27,15 +27,11 @@ using namespace android::renderscript;
Adapter1D::Adapter1D(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
reset();
}
Adapter1D::Adapter1D(Context *rsc, Allocation *a) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
reset();
setAllocation(a);
}
@@ -76,7 +72,7 @@ void Adapter1D::data(const void *data)
void Adapter1D::serialize(OStream *stream) const
{
-
+
}
Adapter1D *Adapter1D::createFromStream(Context *rsc, IStream *stream)
@@ -145,15 +141,11 @@ void rsi_Adapter1DData(Context *rsc, RsAdapter1D va, const void *data)
Adapter2D::Adapter2D(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
reset();
}
Adapter2D::Adapter2D(Context *rsc, Allocation *a) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
reset();
setAllocation(a);
}
@@ -200,7 +192,7 @@ void Adapter2D::data(const void *data)
void Adapter2D::serialize(OStream *stream) const
{
-
+
}
Adapter2D *Adapter2D::createFromStream(Context *rsc, IStream *stream)
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 6748bb4..fc41a72 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -57,8 +57,6 @@ Allocation::Allocation(Context *rsc, const Type *type, void *bmp,
void Allocation::init(Context *rsc, const Type *type)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mPtr = NULL;
mCpuWrite = false;
@@ -478,7 +476,7 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream)
uint32_t dataSize = stream->loadU32();
if(dataSize != type->getSizeBytes()) {
LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
- delete type;
+ ObjectBase::checkDelete(type);
return NULL;
}
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index 9e6fbd5..dc021fc 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -30,8 +30,6 @@ using namespace android::renderscript;
Element::Element(Context *rsc) : ObjectBase(rsc)
{
mBits = 0;
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mFields = NULL;
mFieldCount = 0;
mHasReference = false;
@@ -140,7 +138,7 @@ Element *Element::createFromStream(Context *rsc, IStream *stream)
for (uint32_t ct=0; ct < rsc->mStateElement.mElements.size(); ct++) {
Element *ee = rsc->mStateElement.mElements[ct];
if(ee->isEqual(elem)) {
- delete elem;
+ ObjectBase::checkDelete(elem);
ee->incUserRef();
return ee;
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 633129a..d171a48 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -36,8 +36,6 @@ using namespace android::renderscript;
Font::Font(Context *rsc) : ObjectBase(rsc), mCachedGlyphs(NULL)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mInitialized = false;
mHasKerning = false;
mFace = NULL;
@@ -308,7 +306,7 @@ Font * Font::create(Context *rsc, const char *name, uint32_t fontSize, uint32_t
return newFont;
}
- delete newFont;
+ ObjectBase::checkDelete(newFont);
return NULL;
}
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index 8e43f24..761be93 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -33,8 +33,6 @@ using namespace android::renderscript;
Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mPrimitives = NULL;
mPrimitivesCount = 0;
mVertexBuffers = NULL;
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 46b1750..724172e 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -22,6 +22,7 @@
#include "rsContextHostStub.h"
#endif
+
using namespace android;
using namespace android::renderscript;
@@ -34,101 +35,119 @@ ObjectBase::ObjectBase(Context *rsc)
mRSC = rsc;
mNext = NULL;
mPrev = NULL;
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
+
+#if RS_OBJECT_DEBUG
+ mStack.update(2);
+#endif
rsAssert(rsc);
add();
+ //LOGV("ObjectBase %p con", this);
}
ObjectBase::~ObjectBase()
{
//LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount);
+#if RS_OBJECT_DEBUG
+ mStack.dump();
+#endif
+
+ if(mPrev || mNext) {
+ // While the normal practice is to call remove before we call
+ // delete. Its possible for objects without a re-use list
+ // for avoiding duplication to be created on the stack. In those
+ // cases we need to remove ourself here.
+ asyncLock();
+ remove();
+ asyncUnlock();
+ }
+
rsAssert(!mUserRefCount);
rsAssert(!mSysRefCount);
- remove();
}
void ObjectBase::dumpLOGV(const char *op) const
{
if (mName.size()) {
- LOGV("%s RSobj %p, name %s, refs %i,%i from %s,%i links %p,%p,%p",
- op, this, mName.string(), mUserRefCount, mSysRefCount, mAllocFile, mAllocLine, mNext, mPrev, mRSC);
+ LOGV("%s RSobj %p, name %s, refs %i,%i links %p,%p,%p",
+ op, this, mName.string(), mUserRefCount, mSysRefCount, 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);
+ LOGV("%s RSobj %p, no-name, refs %i,%i links %p,%p,%p",
+ op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
}
}
void ObjectBase::incUserRef() const
{
- lockUserRef();
- mUserRefCount++;
- unlockUserRef();
- //LOGV("ObjectBase %p inc ref %i", this, mUserRefCount);
+ android_atomic_inc(&mUserRefCount);
+ //LOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
}
-void ObjectBase::prelockedIncUserRef() const
+void ObjectBase::incSysRef() const
{
- mUserRefCount++;
+ android_atomic_inc(&mSysRefCount);
+ //LOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
}
-void ObjectBase::incSysRef() const
+void ObjectBase::preDestroy() const
{
- mSysRefCount ++;
- //LOGV("ObjectBase %p inc ref %i", this, mSysRefCount);
}
-bool ObjectBase::checkDelete() const
+bool ObjectBase::checkDelete(const ObjectBase *ref)
{
- if (!(mSysRefCount | mUserRefCount)) {
- lockUserRef();
-
- // Recheck the user ref count since it can be incremented from other threads.
- if (mUserRefCount) {
- unlockUserRef();
- return false;
- }
+ if (!ref) {
+ return false;
+ }
- if (mRSC && mRSC->props.mLogObjects) {
- dumpLOGV("checkDelete");
- }
- unlockUserRef();
- delete this;
- return true;
+ asyncLock();
+ // This lock protects us against the non-RS threads changing
+ // the ref counts. At this point we should be the only thread
+ // working on them.
+ if (ref->mUserRefCount || ref->mSysRefCount) {
+ asyncUnlock();
+ return false;
}
- return false;
+
+ ref->remove();
+ // At this point we can unlock because there should be no possible way
+ // for another thread to reference this object.
+ ref->preDestroy();
+ asyncUnlock();
+ delete ref;
+ return true;
}
+
bool ObjectBase::decUserRef() const
{
- lockUserRef();
+ //LOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
rsAssert(mUserRefCount > 0);
- //dumpLOGV("decUserRef");
- mUserRefCount--;
- unlockUserRef();
- bool ret = checkDelete();
- return ret;
+ if ((android_atomic_dec(&mUserRefCount) <= 1) &&
+ (android_atomic_acquire_load(&mSysRefCount) <= 0)) {
+ return checkDelete(this);
+ }
+ return false;
}
bool ObjectBase::zeroUserRef() const
{
- lockUserRef();
- // This can only happen during cleanup and is therefore
- // thread safe.
- mUserRefCount = 0;
- //dumpLOGV("zeroUserRef");
- unlockUserRef();
- bool ret = checkDelete();
- return ret;
+ //LOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
+ android_atomic_acquire_store(0, &mUserRefCount);
+ if (android_atomic_acquire_load(&mSysRefCount) <= 0) {
+ return checkDelete(this);
+ }
+ return false;
}
bool ObjectBase::decSysRef() const
{
+ //LOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
rsAssert(mSysRefCount > 0);
- mSysRefCount --;
- //dumpLOGV("decSysRef");
- return checkDelete();
+ if ((android_atomic_dec(&mSysRefCount) <= 1) &&
+ (android_atomic_acquire_load(&mUserRefCount) <= 0)) {
+ return checkDelete(this);
+ }
+ return false;
}
void ObjectBase::setName(const char *name)
@@ -141,19 +160,19 @@ void ObjectBase::setName(const char *name, uint32_t len)
mName.setTo(name, len);
}
-void ObjectBase::lockUserRef()
+void ObjectBase::asyncLock()
{
pthread_mutex_lock(&gObjectInitMutex);
}
-void ObjectBase::unlockUserRef()
+void ObjectBase::asyncUnlock()
{
pthread_mutex_unlock(&gObjectInitMutex);
}
void ObjectBase::add() const
{
- pthread_mutex_lock(&gObjectInitMutex);
+ asyncLock();
rsAssert(!mNext);
rsAssert(!mPrev);
@@ -164,12 +183,11 @@ void ObjectBase::add() const
}
mRSC->mObjHead = this;
- pthread_mutex_unlock(&gObjectInitMutex);
+ asyncUnlock();
}
void ObjectBase::remove() const
{
- lockUserRef();
//LOGV("calling remove rsc %p", mRSC);
if (!mRSC) {
rsAssert(!mPrev);
@@ -188,7 +206,6 @@ void ObjectBase::remove() const
}
mPrev = NULL;
mNext = NULL;
- unlockUserRef();
}
void ObjectBase::zeroAllUserRef(Context *rsc)
@@ -219,7 +236,7 @@ void ObjectBase::zeroAllUserRef(Context *rsc)
void ObjectBase::dumpAll(Context *rsc)
{
- lockUserRef();
+ asyncLock();
LOGV("Dumping all objects");
const ObjectBase * o = rsc->mObjHead;
@@ -229,22 +246,22 @@ void ObjectBase::dumpAll(Context *rsc)
o = o->mNext;
}
- unlockUserRef();
+ asyncUnlock();
}
bool ObjectBase::isValid(const Context *rsc, const ObjectBase *obj)
{
- lockUserRef();
+ asyncLock();
const ObjectBase * o = rsc->mObjHead;
while (o) {
if (o == obj) {
- unlockUserRef();
+ asyncUnlock();
return true;
}
o = o->mNext;
}
- unlockUserRef();
+ asyncUnlock();
return false;
}
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index 8d1ace1..5f03db5 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -19,6 +19,11 @@
#include "rsUtils.h"
+#define RS_OBJECT_DEBUG 0
+
+#if RS_OBJECT_DEBUG
+ #include <utils/CallStack.h>
+#endif
namespace android {
namespace renderscript {
@@ -31,7 +36,6 @@ class ObjectBase
{
public:
ObjectBase(Context *rsc);
- virtual ~ObjectBase();
void incSysRef() const;
bool decSysRef() const;
@@ -39,7 +43,8 @@ public:
void incUserRef() const;
bool decUserRef() const;
bool zeroUserRef() const;
- void prelockedIncUserRef() const;
+
+ static bool checkDelete(const ObjectBase *);
const char * getName() const {
return mName.string();
@@ -58,13 +63,18 @@ public:
static bool isValid(const Context *rsc, const ObjectBase *obj);
- static void lockUserRef();
- static void unlockUserRef();
+ // The async lock is taken during object creation in non-rs threads
+ // and object deletion in the rs thread.
+ static void asyncLock();
+ static void asyncUnlock();
protected:
- const char *mAllocFile;
- uint32_t mAllocLine;
+ // Called inside the async lock for any object list management that is
+ // necessary in derived classes.
+ virtual void preDestroy() const;
+
Context *mRSC;
+ virtual ~ObjectBase();
private:
static pthread_mutex_t gObjectInitMutex;
@@ -72,14 +82,17 @@ private:
void add() const;
void remove() const;
- bool checkDelete() const;
-
String8 mName;
mutable int32_t mSysRefCount;
mutable int32_t mUserRefCount;
mutable const ObjectBase * mPrev;
mutable const ObjectBase * mNext;
+
+#if RS_OBJECT_DEBUG
+ CallStack mStack;
+#endif
+
};
template<class T>
@@ -104,6 +117,10 @@ public:
}
}
+ ObjectBaseRef & operator= (const ObjectBaseRef &ref) {
+ return ObjectBaseRef(ref);
+ }
+
~ObjectBaseRef() {
clear();
}
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 10e00e6..72d1b02 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -31,8 +31,6 @@ using namespace android::renderscript;
Program::Program(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mDirty = true;
mShaderID = 0;
mAttribCount = 0;
@@ -55,8 +53,6 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength,
const uint32_t * params, uint32_t paramLength) :
ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mDirty = true;
mShaderID = 0;
mAttribCount = 0;
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 81b4fa4..33399d5 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -36,9 +36,6 @@ ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
uint32_t paramLength) :
Program(rsc, shaderText, shaderLength, params, paramLength)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
-
mConstantColor[0] = 1.f;
mConstantColor[1] = 1.f;
mConstantColor[2] = 1.f;
@@ -182,8 +179,8 @@ ProgramFragmentState::ProgramFragmentState()
ProgramFragmentState::~ProgramFragmentState()
{
- delete mPF;
-
+ ObjectBase::checkDelete(mPF);
+ mPF = NULL;
}
void ProgramFragmentState::init(Context *rsc)
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index 62d060d..5f8c4ba 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -36,8 +36,6 @@ ProgramRaster::ProgramRaster(Context *rsc,
bool pointSprite) :
Program(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mPointSmooth = pointSmooth;
mLineSmooth = lineSmooth;
mPointSprite = pointSprite;
diff --git a/libs/rs/rsProgramStore.cpp b/libs/rs/rsProgramStore.cpp
index 586a89f..876299f 100644
--- a/libs/rs/rsProgramStore.cpp
+++ b/libs/rs/rsProgramStore.cpp
@@ -33,8 +33,6 @@ using namespace android::renderscript;
ProgramStore::ProgramStore(Context *rsc) :
Program(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mDitherEnable = true;
mBlendEnable = false;
mColorRWriteEnable = true;
@@ -236,8 +234,8 @@ ProgramStoreState::ProgramStoreState()
ProgramStoreState::~ProgramStoreState()
{
- delete mPFS;
-
+ ObjectBase::checkDelete(mPFS);
+ mPFS = NULL;
}
void ProgramStoreState::init(Context *rsc)
@@ -258,9 +256,8 @@ namespace renderscript {
void rsi_ProgramStoreBegin(Context * rsc, RsElement in, RsElement out)
{
- delete rsc->mStateFragmentStore.mPFS;
+ ObjectBase::checkDelete(rsc->mStateFragmentStore.mPFS);
rsc->mStateFragmentStore.mPFS = new ProgramStore(rsc);
-
}
void rsi_ProgramStoreDepthFunc(Context *rsc, RsDepthFunc func)
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index a785262..d12439f 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -37,9 +37,6 @@ ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText,
uint32_t paramLength) :
Program(rsc, shaderText, shaderLength, params, paramLength)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
-
init(rsc);
}
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 180d78e..cfae7b2 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -33,8 +33,6 @@ using namespace android::renderscript;
Sampler::Sampler(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
// Should not get called.
rsAssert(0);
}
@@ -47,8 +45,6 @@ Sampler::Sampler(Context *rsc,
RsSamplerValue wrapR,
float aniso) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mMagFilter = magFilter;
mMinFilter = minFilter;
mWrapS = wrapS;
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index c5632b5..ef380d2 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -21,8 +21,6 @@ using namespace android::renderscript;
Script::Script(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
memset(&mEnviroment, 0, sizeof(mEnviroment));
mSlots = NULL;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index a2910d7..165fa71 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -35,8 +35,6 @@ using namespace android::renderscript;
ScriptC::ScriptC(Context *rsc) : Script(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mBccScript = NULL;
memset(&mProgram, 0, sizeof(mProgram));
}
@@ -524,11 +522,11 @@ RsScript rsi_ScriptCCreate(Context * rsc)
{
ScriptCState *ss = &rsc->mScriptC;
- ObjectBaseRef<ScriptC> s = ss->mScript.get();
+ ObjectBaseRef<ScriptC> s(ss->mScript);
ss->mScript.clear();
+ s->incUserRef();
ss->runCompiler(rsc, s.get());
- s->incUserRef();
ss->clear(rsc);
return s.get();
}
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 27b1b4f..82ad33e 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -27,8 +27,6 @@ using namespace android::renderscript;
Type::Type(Context *rsc) : ObjectBase(rsc)
{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
mLODs = 0;
mLODCount = 0;
mAttribs = NULL;
@@ -36,7 +34,7 @@ Type::Type(Context *rsc) : ObjectBase(rsc)
clear();
}
-Type::~Type()
+void Type::preDestroy()
{
for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
if (mRSC->mStateType.mTypes[ct] == this) {
@@ -44,6 +42,10 @@ Type::~Type()
break;
}
}
+}
+
+Type::~Type()
+{
if (mLODs) {
delete [] mLODs;
mLODs = NULL;
@@ -401,7 +403,7 @@ void rsi_TypeGetNativeData(Context *rsc, RsType type, uint32_t *typeData, uint32
}
}
-void * rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
+RsType rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
const RsDimension *dims, const uint32_t *vals)
{
Context *rsc = static_cast<Context *>(con);
@@ -428,7 +430,7 @@ void * rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
}
}
- ObjectBase::lockUserRef();
+ ObjectBase::asyncLock();
for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
Type *t = stc->mTypes[ct];
if (t->getElement() != e) continue;
@@ -437,11 +439,11 @@ void * rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
if (t->getDimZ() != dimZ) continue;
if (t->getDimLOD() != dimLOD) continue;
if (t->getDimFaces() != dimFaces) continue;
- t->prelockedIncUserRef();
- ObjectBase::unlockUserRef();
+ t->incUserRef();
+ ObjectBase::asyncUnlock();
return t;
}
- ObjectBase::unlockUserRef();
+ ObjectBase::asyncUnlock();
Type * st = new Type(rsc);
st->incUserRef();
@@ -453,9 +455,9 @@ void * rsaTypeCreate(RsContext con, RsElement _e, uint32_t dimCount,
st->setDimFaces(dimFaces);
st->compute();
- ObjectBase::lockUserRef();
+ ObjectBase::asyncLock();
stc->mTypes.push(st);
- ObjectBase::unlockUserRef();
+ ObjectBase::asyncUnlock();
return st;
}
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index a0c77ab..6b89413 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -124,6 +124,9 @@ protected:
bool isValidGLComponent(uint32_t fieldIdx);
void makeGLComponents();
+protected:
+ virtual void preDestroy();
+
private:
Type(const Type &);
};