summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jason Sams <rjsams@android.com> 2009-09-25 14:51:22 -0700
committer Jason Sams <rjsams@android.com> 2009-09-25 14:51:22 -0700
commita9e7a05b84470257637c97d65f6562aa832c66ef (patch)
tree04a3175485ae7492c3387003c244953b6880c514
parenta0cad2f5d19d95cfe496ebb82f3227dd4ed7c169 (diff)
Improve renderscript context teardown. Track object in the system and then force their cleanup by releasing all user references once destroy context is called. Java layer will no longer send destroy notifications for objects garbage collected once a context is destroyed.
-rw-r--r--graphics/java/android/renderscript/BaseObj.java3
-rw-r--r--graphics/java/android/renderscript/RenderScript.java4
-rw-r--r--libs/rs/java/Fountain/src/com/android/fountain/Fountain.java8
-rw-r--r--libs/rs/java/Fountain/src/com/android/fountain/FountainView.java26
-rw-r--r--libs/rs/rsAdapter.cpp12
-rw-r--r--libs/rs/rsAdapter.h14
-rw-r--r--libs/rs/rsAllocation.cpp12
-rw-r--r--libs/rs/rsAllocation.h2
-rw-r--r--libs/rs/rsComponent.cpp6
-rw-r--r--libs/rs/rsComponent.h4
-rw-r--r--libs/rs/rsContext.cpp7
-rw-r--r--libs/rs/rsContext.h2
-rw-r--r--libs/rs/rsElement.cpp9
-rw-r--r--libs/rs/rsElement.h4
-rw-r--r--libs/rs/rsFileA3D.cpp2
-rw-r--r--libs/rs/rsLight.cpp4
-rw-r--r--libs/rs/rsLight.h2
-rw-r--r--libs/rs/rsLocklessFifo.cpp6
-rw-r--r--libs/rs/rsMesh.cpp2
-rw-r--r--libs/rs/rsMesh.h4
-rw-r--r--libs/rs/rsObjectBase.cpp106
-rw-r--r--libs/rs/rsObjectBase.h23
-rw-r--r--libs/rs/rsProgram.cpp2
-rw-r--r--libs/rs/rsProgram.h2
-rw-r--r--libs/rs/rsProgramFragment.cpp8
-rw-r--r--libs/rs/rsProgramFragment.h2
-rw-r--r--libs/rs/rsProgramFragmentStore.cpp8
-rw-r--r--libs/rs/rsProgramFragmentStore.h2
-rw-r--r--libs/rs/rsProgramRaster.cpp10
-rw-r--r--libs/rs/rsProgramRaster.h3
-rw-r--r--libs/rs/rsProgramVertex.cpp8
-rw-r--r--libs/rs/rsProgramVertex.h2
-rw-r--r--libs/rs/rsSampler.cpp10
-rw-r--r--libs/rs/rsSampler.h7
-rw-r--r--libs/rs/rsScript.cpp2
-rw-r--r--libs/rs/rsScript.h2
-rw-r--r--libs/rs/rsScriptC.cpp5
-rw-r--r--libs/rs/rsScriptC.h2
-rw-r--r--libs/rs/rsSimpleMesh.cpp4
-rw-r--r--libs/rs/rsSimpleMesh.h2
-rw-r--r--libs/rs/rsThreadIO.cpp4
-rw-r--r--libs/rs/rsType.cpp4
-rw-r--r--libs/rs/rsType.h2
43 files changed, 254 insertions, 99 deletions
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index c25f16a60f2d..c626d5d1ea39 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -60,9 +60,10 @@ class BaseObj {
protected void finalize() throws Throwable
{
if (!mDestroyed) {
- if(mID != 0) {
+ if(mID != 0 && mRS.isAlive()) {
mRS.nObjDestroyOOB(mID);
}
+ mRS = null;
mID = 0;
mDestroyed = true;
Log.v(RenderScript.LOG_TAG,
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index f815f52830a3..ed616914af3b 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -219,6 +219,10 @@ public class RenderScript {
mDev = 0;
}
+ boolean isAlive() {
+ return mContext != 0;
+ }
+
void pause() {
nContextPause();
}
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
index 58c78faf433b..9ae3e6703471 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/Fountain.java
@@ -62,6 +62,8 @@ public class Fountain extends Activity {
@Override
protected void onResume() {
+ Log.e("rs", "onResume");
+
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onResume();
@@ -70,12 +72,16 @@ public class Fountain extends Activity {
@Override
protected void onPause() {
+ Log.e("rs", "onPause");
+
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
mView.onPause();
- Runtime.getRuntime().exit(0);
+
+
+ //Runtime.getRuntime().exit(0);
}
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
index 1b07f9828b7d..116afd0c3dbb 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java
@@ -49,14 +49,40 @@ public class FountainView extends RSSurfaceView {
private RenderScript mRS;
private FountainRS mRender;
+ private void destroyRS() {
+ if(mRS != null) {
+ mRS = null;
+ destroyRenderScript();
+ }
+ java.lang.System.gc();
+ }
+
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
super.surfaceChanged(holder, format, w, h);
+ Log.e("rs", "surfaceChanged");
+ destroyRS();
+
+
mRS = createRenderScript(false, true);
mRender = new FountainRS();
mRender.init(mRS, getResources(), w, h);
}
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ // Surface will be destroyed when we return
+ Log.v("rs", "surfaceDestroyed");
+ destroyRS();
+
+ try {
+ java.lang.Thread.sleep(5000);
+ } catch(InterruptedException e) {
+
+ }
+ Runtime.getRuntime().exit(0);
+ }
+
+
@Override
public boolean onTouchEvent(MotionEvent ev)
diff --git a/libs/rs/rsAdapter.cpp b/libs/rs/rsAdapter.cpp
index d20e91015fb3..9a3bbb1f9d93 100644
--- a/libs/rs/rsAdapter.cpp
+++ b/libs/rs/rsAdapter.cpp
@@ -21,12 +21,12 @@ using namespace android;
using namespace android::renderscript;
-Adapter1D::Adapter1D()
+Adapter1D::Adapter1D(Context *rsc) : ObjectBase(rsc)
{
reset();
}
-Adapter1D::Adapter1D(Allocation *a)
+Adapter1D::Adapter1D(Context *rsc, Allocation *a) : ObjectBase(rsc)
{
reset();
setAllocation(a);
@@ -71,7 +71,7 @@ namespace renderscript {
RsAdapter1D rsi_Adapter1DCreate(Context *rsc)
{
- Adapter1D *a = new Adapter1D();
+ Adapter1D *a = new Adapter1D(rsc);
a->incUserRef();
return a;
}
@@ -125,12 +125,12 @@ void rsi_Adapter1DData(Context *rsc, RsAdapter1D va, const void *data)
//////////////////////////
-Adapter2D::Adapter2D()
+Adapter2D::Adapter2D(Context *rsc) : ObjectBase(rsc)
{
reset();
}
-Adapter2D::Adapter2D(Allocation *a)
+Adapter2D::Adapter2D(Context *rsc, Allocation *a) : ObjectBase(rsc)
{
reset();
setAllocation(a);
@@ -184,7 +184,7 @@ namespace renderscript {
RsAdapter2D rsi_Adapter2DCreate(Context *rsc)
{
- Adapter2D *a = new Adapter2D();
+ Adapter2D *a = new Adapter2D(rsc);
a->incUserRef();
return a;
}
diff --git a/libs/rs/rsAdapter.h b/libs/rs/rsAdapter.h
index 865535e93f31..cb2872e4399c 100644
--- a/libs/rs/rsAdapter.h
+++ b/libs/rs/rsAdapter.h
@@ -23,15 +23,15 @@
namespace android {
namespace renderscript {
-
+
class Adapter1D : public ObjectBase
{
public:
// By policy this allocation will hold a pointer to the type
// but will not destroy it on destruction.
- Adapter1D();
- Adapter1D(Allocation *);
+ Adapter1D(Context *);
+ Adapter1D(Context *, Allocation *);
void reset();
void * getElement(uint32_t x);
@@ -64,8 +64,8 @@ class Adapter2D : public ObjectBase
public:
// By policy this allocation will hold a pointer to the type
// but will not destroy it on destruction.
- Adapter2D();
- Adapter2D(Allocation *);
+ Adapter2D(Context *);
+ Adapter2D(Context *, Allocation *);
void reset();
void * getElement(uint32_t x, uint32_t y) const;
@@ -79,8 +79,8 @@ public:
inline void setFace(uint32_t face) {mFace = face;}
//void setArray(uint32_t num, uint32_t value);
- void data(const void *data);
- void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data);
+ void data(const void *data);
+ void subData(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data);
protected:
ObjectBaseRef<Allocation> mAllocation;
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index cb82624688aa..96e128b6e29a 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -22,7 +22,7 @@
using namespace android;
using namespace android::renderscript;
-Allocation::Allocation(const Type *type)
+Allocation::Allocation(Context *rsc, const Type *type) : ObjectBase(rsc)
{
mPtr = NULL;
@@ -90,7 +90,7 @@ void Allocation::uploadToTexture(uint32_t lodOffset)
}
glBindTexture(GL_TEXTURE_2D, mTextureID);
- Adapter2D adapt(this);
+ Adapter2D adapt(getContext(), this);
for(uint32_t lod = 0; (lod + lodOffset) < mType->getLODCount(); lod++) {
adapt.setLOD(lod+lodOffset);
@@ -186,14 +186,14 @@ RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype)
{
const Type * type = static_cast<const Type *>(vtype);
- Allocation * alloc = new Allocation(type);
+ Allocation * alloc = new Allocation(rsc, type);
alloc->incUserRef();
return alloc;
}
RsAllocation rsi_AllocationCreateSized(Context *rsc, RsElement e, size_t count)
{
- Type * type = new Type();
+ Type * type = new Type(rsc);
type->setDimX(count);
type->setElement(static_cast<Element *>(e));
type->compute();
@@ -371,8 +371,8 @@ RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h
cvt(texAlloc->getPtr(), data, w * h);
if (genMips) {
- Adapter2D adapt(texAlloc);
- Adapter2D adapt2(texAlloc);
+ Adapter2D adapt(rsc, texAlloc);
+ Adapter2D adapt2(rsc, texAlloc);
for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
adapt.setLOD(lod);
adapt2.setLOD(lod + 1);
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 1f58ec59a6eb..1b83267bb346 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -33,7 +33,7 @@ class Allocation : public ObjectBase
public:
// By policy this allocation will hold a pointer to the type
// but will not destroy it on destruction.
- Allocation(const Type *);
+ Allocation(Context *rsc, const Type *);
virtual ~Allocation();
void setCpuWritable(bool);
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index 4a043f3b714d..67184ffacc27 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -21,7 +21,7 @@ using namespace android;
using namespace android::renderscript;
-Component::Component()
+Component::Component(Context *rsc) : ObjectBase(rsc)
{
mType = FLOAT;
mKind = USER;
@@ -29,9 +29,9 @@ Component::Component()
mBits = 0;
}
-Component::Component(
+Component::Component(Context *rsc,
DataKind dk, DataType dt,
- bool isNormalized, uint32_t bits, const char * name)
+ bool isNormalized, uint32_t bits, const char * name) : ObjectBase(rsc)
{
mType = dt;
mKind = dk;
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index 58565246b69a..290cd57e3ab3 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -44,7 +44,7 @@ public:
};
- Component(DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *);
+ Component(Context *rsc, DataKind dk, DataType dt, bool isNorm, uint32_t bits, const char *);
virtual ~Component();
DataType getType() const {return mType;}
@@ -66,7 +66,7 @@ protected:
String8 mName;
private:
- Component();
+ Component(Context *rsc);
};
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2fe762c3df30..6c18ddbd1ad2 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -269,6 +269,12 @@ void * Context::threadProc(void *vrsc)
}
LOGV("RS Thread exiting");
+ ObjectBase::zeroAllUserRef(rsc);
+ rsc->mRaster.set(NULL);
+ rsc->mFragment.set(NULL);
+ rsc->mVertex.set(NULL);
+ rsc->mFragmentStore.set(NULL);
+
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(rsc->mEGL.mDisplay, rsc->mEGL.mSurface);
@@ -286,6 +292,7 @@ Context::Context(Device *dev, Surface *sur, bool useDepth)
mExit = false;
mUseDepth = useDepth;
mPaused = false;
+ mObjHead = NULL;
int status;
pthread_attr_t threadAttr;
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 0a886cd6a131..28a9de29a560 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -145,6 +145,8 @@ public:
bool logTimes;
+ mutable const ObjectBase * mObjHead;
+
protected:
Device *mDev;
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index b5267b36459c..e7ae2474f64e 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -22,13 +22,13 @@ using namespace android;
using namespace android::renderscript;
-Element::Element()
+Element::Element(Context *rsc) : ObjectBase(rsc)
{
mComponents = NULL;
mComponentCount = 0;
}
-Element::Element(uint32_t count)
+Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc)
{
mComponents = new ObjectBaseRef<Component> [count];
mComponentCount = count;
@@ -197,7 +197,8 @@ void rsi_ElementBegin(Context *rsc)
void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
{
ElementState * sec = &rsc->mStateElement;
- Component *c = new Component(static_cast<Component::DataKind>(dk),
+ Component *c = new Component(rsc,
+ static_cast<Component::DataKind>(dk),
static_cast<Component::DataType>(dt),
isNormalized,
bits,
@@ -208,7 +209,7 @@ void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalize
RsElement rsi_ElementCreate(Context *rsc)
{
ElementState * sec = &rsc->mStateElement;
- Element *se = new Element(sec->mComponentBuildList.size());
+ Element *se = new Element(rsc, sec->mComponentBuildList.size());
for (size_t ct = 0; ct < se->getComponentCount(); ct++) {
se->setComponent(ct, sec->mComponentBuildList[ct]);
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 7b5a83d291fb..82da4417c9b1 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -28,7 +28,7 @@ namespace renderscript {
class Element : public ObjectBase
{
public:
- Element(uint32_t count);
+ Element(Context *, uint32_t count);
~Element();
@@ -59,7 +59,7 @@ protected:
ObjectBaseRef<Component> * mComponents;
//uint32_t *mOffsetTable;
- Element();
+ Element(Context *);
};
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index 347ef2323560..c566665ab35a 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -242,7 +242,7 @@ void FileA3D::IO::loadString(String8 *s)
void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
{
- Mesh * m = new Mesh;
+ Mesh * m = new Mesh(rsc);
m->mPrimitivesCount = io->loadU32();
m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];
diff --git a/libs/rs/rsLight.cpp b/libs/rs/rsLight.cpp
index ad06c1f394e0..e9b8ef9bf356 100644
--- a/libs/rs/rsLight.cpp
+++ b/libs/rs/rsLight.cpp
@@ -22,7 +22,7 @@ using namespace android;
using namespace android::renderscript;
-Light::Light(bool isLocal, bool isMono)
+Light::Light(Context *rsc, bool isLocal, bool isMono) : ObjectBase(rsc)
{
mIsLocal = isLocal;
mIsMono = isMono;
@@ -104,7 +104,7 @@ void rsi_LightSetMonochromatic(Context *rsc, bool isMono)
RsLight rsi_LightCreate(Context *rsc)
{
- Light *l = new Light(rsc->mStateLight.mIsLocal,
+ Light *l = new Light(rsc, rsc->mStateLight.mIsLocal,
rsc->mStateLight.mIsMono);
l->incUserRef();
return l;
diff --git a/libs/rs/rsLight.h b/libs/rs/rsLight.h
index b0c33862f52d..d8796e6814af 100644
--- a/libs/rs/rsLight.h
+++ b/libs/rs/rsLight.h
@@ -29,7 +29,7 @@ namespace renderscript {
class Light : public ObjectBase
{
public:
- Light(bool isLocal, bool isMono);
+ Light(Context *, bool isLocal, bool isMono);
virtual ~Light();
// Values, mutable after creation.
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index f4f5d40cc157..b0540a6eac47 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -131,6 +131,12 @@ const void * LocklessCommandFifo::get(uint32_t *command, uint32_t *bytesData)
mSignalToWorker.wait();
}
+ if (mInShutdown) {
+ *command = 0;
+ *bytesData = 0;
+ return 0;
+ }
+
*command = reinterpret_cast<const uint16_t *>(mGet)[0];
*bytesData = reinterpret_cast<const uint16_t *>(mGet)[1];
if (*command) {
diff --git a/libs/rs/rsMesh.cpp b/libs/rs/rsMesh.cpp
index aeb52eda4434..73aef62110a0 100644
--- a/libs/rs/rsMesh.cpp
+++ b/libs/rs/rsMesh.cpp
@@ -22,7 +22,7 @@ using namespace android::renderscript;
#include <GLES/gl.h>
#include <GLES/glext.h>
-Mesh::Mesh()
+Mesh::Mesh(Context *rsc) : ObjectBase(rsc)
{
mVerticies = NULL;
mVerticiesCount = 0;
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index be207a3adab0..5201abd24632 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -29,7 +29,7 @@ namespace renderscript {
class Mesh : public ObjectBase
{
public:
- Mesh();
+ Mesh(Context *);
~Mesh();
struct Verticies_t
@@ -42,7 +42,7 @@ public:
size_t mOffsetCoord;
size_t mOffsetTex;
size_t mOffsetNorm;
-
+
size_t mSizeCoord;
size_t mSizeTex;
size_t mSizeNorm;
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index 7e7afabe0550..acfc5ceede67 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -15,22 +15,39 @@
*/
#include "rsObjectBase.h"
+#include "rsContext.h"
using namespace android;
using namespace android::renderscript;
-ObjectBase::ObjectBase()
+ObjectBase::ObjectBase(Context *rsc)
{
mUserRefCount = 0;
mSysRefCount = 0;
mName = NULL;
+ mRSC = NULL;
+ mNext = NULL;
+ mPrev = NULL;
+ setContext(rsc);
}
ObjectBase::~ObjectBase()
{
- //LOGV("~ObjectBase %p ref %i", this, mRefCount);
+ //LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount);
rsAssert(!mUserRefCount);
rsAssert(!mSysRefCount);
+ remove();
+}
+
+void ObjectBase::setContext(Context *rsc)
+{
+ if (mRSC) {
+ remove();
+ }
+ mRSC = rsc;
+ if (rsc) {
+ add();
+ }
}
void ObjectBase::incUserRef() const
@@ -45,11 +62,8 @@ void ObjectBase::incSysRef() const
//LOGV("ObjectBase %p inc ref %i", this, mRefCount);
}
-void ObjectBase::decUserRef() const
+bool ObjectBase::checkDelete() const
{
- rsAssert(mUserRefCount > 0);
- mUserRefCount --;
- //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
if (!(mSysRefCount | mUserRefCount)) {
if (mName) {
LOGV("Deleting RS object %p, name %s", this, mName);
@@ -57,22 +71,32 @@ void ObjectBase::decUserRef() const
LOGV("Deleting RS object %p, no name", this);
}
delete this;
+ return true;
}
+ return false;
}
-void ObjectBase::decSysRef() const
+bool ObjectBase::decUserRef() const
+{
+ rsAssert(mUserRefCount > 0);
+ mUserRefCount --;
+ //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
+ return checkDelete();
+}
+
+bool ObjectBase::zeroUserRef() const
+{
+ mUserRefCount = 0;
+ //LOGV("ObjectBase %p dec ref %i", this, mRefCount);
+ return checkDelete();
+}
+
+bool ObjectBase::decSysRef() const
{
rsAssert(mSysRefCount > 0);
mSysRefCount --;
//LOGV("ObjectBase %p dec ref %i", this, mRefCount);
- if (!(mSysRefCount | mUserRefCount)) {
- if (mName) {
- LOGV("Deleting RS object %p, name %s", this, mName);
- } else {
- LOGV("Deleting RS object %p, no name", this);
- }
- delete this;
- }
+ return checkDelete();
}
void ObjectBase::setName(const char *name)
@@ -96,3 +120,55 @@ void ObjectBase::setName(const char *name, uint32_t len)
}
}
+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)
+{
+ 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);
+ }
+ }
+}
+
diff --git a/libs/rs/rsObjectBase.h b/libs/rs/rsObjectBase.h
index d1e6baa0badb..be400caac04e 100644
--- a/libs/rs/rsObjectBase.h
+++ b/libs/rs/rsObjectBase.h
@@ -23,18 +23,21 @@
namespace android {
namespace renderscript {
+class Context;
+
// An element is a group of Components that occupies one cell in a structure.
class ObjectBase
{
public:
- ObjectBase();
+ ObjectBase(Context *rsc);
virtual ~ObjectBase();
void incSysRef() const;
- void decSysRef() const;
+ bool decSysRef() const;
void incUserRef() const;
- void decUserRef() const;
+ bool decUserRef() const;
+ bool zeroUserRef() const;
const char * getName() const {
return mName;
@@ -42,12 +45,24 @@ public:
void setName(const char *);
void setName(const char *, uint32_t len);
+ Context * getContext() const {return mRSC;}
+ void setContext(Context *);
+
+ static void zeroAllUserRef(Context *rsc);
+
private:
+ void add() const;
+ void remove() const;
+
+ bool checkDelete() const;
+
char * mName;
+ Context *mRSC;
mutable int32_t mSysRefCount;
mutable int32_t mUserRefCount;
-
+ mutable const ObjectBase * mPrev;
+ mutable const ObjectBase * mNext;
};
template<class T>
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 18eacfb34f88..051483f408f9 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -21,7 +21,7 @@ using namespace android;
using namespace android::renderscript;
-Program::Program(Element *in, Element *out)
+Program::Program(Context *rsc, Element *in, Element *out) : ObjectBase(rsc)
{
mElementIn.set(in);
mElementOut.set(out);
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index bb3d9ac37aba..26b78ddde257 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -29,7 +29,7 @@ namespace renderscript {
class Program : public ObjectBase
{
public:
- Program(Element *in, Element *out);
+ Program(Context *, Element *in, Element *out);
virtual ~Program();
void bindAllocation(Allocation *);
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 6cf64a4ecf33..5f685ff57355 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -24,8 +24,8 @@ using namespace android;
using namespace android::renderscript;
-ProgramFragment::ProgramFragment(Element *in, Element *out, bool pointSpriteEnable) :
- Program(in, out)
+ProgramFragment::ProgramFragment(Context *rsc, Element *in, Element *out, bool pointSpriteEnable) :
+ Program(rsc, in, out)
{
for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
mEnvModes[ct] = RS_TEX_ENV_MODE_REPLACE;
@@ -186,7 +186,7 @@ ProgramFragmentState::~ProgramFragmentState()
void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
{
- ProgramFragment *pf = new ProgramFragment(NULL, NULL, false);
+ ProgramFragment *pf = new ProgramFragment(rsc, NULL, NULL, false);
mDefault.set(pf);
}
@@ -197,7 +197,7 @@ namespace renderscript {
void rsi_ProgramFragmentBegin(Context * rsc, RsElement in, RsElement out, bool pointSpriteEnable)
{
delete rsc->mStateFragment.mPF;
- rsc->mStateFragment.mPF = new ProgramFragment((Element *)in, (Element *)out, pointSpriteEnable);
+ rsc->mStateFragment.mPF = new ProgramFragment(rsc, (Element *)in, (Element *)out, pointSpriteEnable);
}
void rsi_ProgramFragmentBindTexture(Context *rsc, RsProgramFragment vpf, uint32_t slot, RsAllocation a)
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index 51117ebeab6c..d783c0df9749 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -32,7 +32,7 @@ public:
- ProgramFragment(Element *in, Element *out, bool pointSpriteEnable);
+ ProgramFragment(Context *, Element *in, Element *out, bool pointSpriteEnable);
virtual ~ProgramFragment();
virtual void setupGL(const Context *, ProgramFragmentState *);
diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp
index 317948496777..39802c7b9d1a 100644
--- a/libs/rs/rsProgramFragmentStore.cpp
+++ b/libs/rs/rsProgramFragmentStore.cpp
@@ -24,8 +24,8 @@ using namespace android;
using namespace android::renderscript;
-ProgramFragmentStore::ProgramFragmentStore(Element *in, Element *out) :
- Program(in, out)
+ProgramFragmentStore::ProgramFragmentStore(Context *rsc, Element *in, Element *out) :
+ Program(rsc, in, out)
{
mDitherEnable = true;
mBlendEnable = false;
@@ -213,7 +213,7 @@ ProgramFragmentStoreState::~ProgramFragmentStoreState()
void ProgramFragmentStoreState::init(Context *rsc, int32_t w, int32_t h)
{
- ProgramFragmentStore *pfs = new ProgramFragmentStore(NULL, NULL);
+ ProgramFragmentStore *pfs = new ProgramFragmentStore(rsc, NULL, NULL);
mDefault.set(pfs);
}
@@ -224,7 +224,7 @@ namespace renderscript {
void rsi_ProgramFragmentStoreBegin(Context * rsc, RsElement in, RsElement out)
{
delete rsc->mStateFragmentStore.mPFS;
- rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore((Element *)in, (Element *)out);
+ rsc->mStateFragmentStore.mPFS = new ProgramFragmentStore(rsc, (Element *)in, (Element *)out);
}
diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h
index e646e03ef136..b71e35f90b6c 100644
--- a/libs/rs/rsProgramFragmentStore.h
+++ b/libs/rs/rsProgramFragmentStore.h
@@ -28,7 +28,7 @@ class ProgramFragmentStoreState;
class ProgramFragmentStore : public Program
{
public:
- ProgramFragmentStore(Element *in, Element *out);
+ ProgramFragmentStore(Context *, Element *in, Element *out);
virtual ~ProgramFragmentStore();
virtual void setupGL(const Context *, ProgramFragmentStoreState *);
diff --git a/libs/rs/rsProgramRaster.cpp b/libs/rs/rsProgramRaster.cpp
index b968fe1508b5..2a9c4abd2cb6 100644
--- a/libs/rs/rsProgramRaster.cpp
+++ b/libs/rs/rsProgramRaster.cpp
@@ -24,12 +24,13 @@ using namespace android;
using namespace android::renderscript;
-ProgramRaster::ProgramRaster(Element *in,
+ProgramRaster::ProgramRaster(Context *rsc,
+ Element *in,
Element *out,
bool pointSmooth,
bool lineSmooth,
bool pointSprite) :
- Program(in, out)
+ Program(rsc, in, out)
{
mPointSmooth = pointSmooth;
mLineSmooth = lineSmooth;
@@ -95,7 +96,7 @@ ProgramRasterState::~ProgramRasterState()
void ProgramRasterState::init(Context *rsc, int32_t w, int32_t h)
{
- ProgramRaster *pr = new ProgramRaster(NULL, NULL, false, false, false);
+ ProgramRaster *pr = new ProgramRaster(rsc, NULL, NULL, false, false, false);
mDefault.set(pr);
}
@@ -108,7 +109,8 @@ RsProgramRaster rsi_ProgramRasterCreate(Context * rsc, RsElement in, RsElement o
bool lineSmooth,
bool pointSprite)
{
- ProgramRaster *pr = new ProgramRaster(static_cast<Element *>(in),
+ ProgramRaster *pr = new ProgramRaster(rsc,
+ static_cast<Element *>(in),
static_cast<Element *>(out),
pointSmooth,
lineSmooth,
diff --git a/libs/rs/rsProgramRaster.h b/libs/rs/rsProgramRaster.h
index 5984868cc778..da68f67de1c6 100644
--- a/libs/rs/rsProgramRaster.h
+++ b/libs/rs/rsProgramRaster.h
@@ -28,7 +28,8 @@ class ProgramRasterState;
class ProgramRaster : public Program
{
public:
- ProgramRaster(Element *in,
+ ProgramRaster(Context *rsc,
+ Element *in,
Element *out,
bool pointSmooth,
bool lineSmooth,
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index dda56d79db35..9eb32ff269df 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -24,8 +24,8 @@ using namespace android;
using namespace android::renderscript;
-ProgramVertex::ProgramVertex(Element *in, Element *out) :
- Program(in, out)
+ProgramVertex::ProgramVertex(Context *rsc, Element *in, Element *out) :
+ Program(rsc, in, out)
{
mTextureMatrixEnable = false;
mLightCount = 0;
@@ -141,7 +141,7 @@ void ProgramVertexState::init(Context *rsc, int32_t w, int32_t h)
rsi_TypeAdd(rsc, RS_DIMENSION_X, 48);
mAllocType = rsi_TypeCreate(rsc);
- ProgramVertex *pv = new ProgramVertex(NULL, NULL);
+ ProgramVertex *pv = new ProgramVertex(rsc, NULL, NULL);
Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType);
mDefaultAlloc.set(alloc);
mDefault.set(pv);
@@ -163,7 +163,7 @@ namespace renderscript {
void rsi_ProgramVertexBegin(Context *rsc, RsElement in, RsElement out)
{
delete rsc->mStateVertex.mPV;
- rsc->mStateVertex.mPV = new ProgramVertex((Element *)in, (Element *)out);
+ rsc->mStateVertex.mPV = new ProgramVertex(rsc, (Element *)in, (Element *)out);
}
RsProgramVertex rsi_ProgramVertexCreate(Context *rsc)
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index 32d147c483c7..b3a8b8dacb8c 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -30,7 +30,7 @@ class ProgramVertex : public Program
public:
const static uint32_t MAX_LIGHTS = 8;
- ProgramVertex(Element *in, Element *out);
+ ProgramVertex(Context *, Element *in, Element *out);
virtual ~ProgramVertex();
virtual void setupGL(const Context *rsc, ProgramVertexState *state);
diff --git a/libs/rs/rsSampler.cpp b/libs/rs/rsSampler.cpp
index 3f56faa7f15c..99091a911816 100644
--- a/libs/rs/rsSampler.cpp
+++ b/libs/rs/rsSampler.cpp
@@ -25,17 +25,18 @@ using namespace android;
using namespace android::renderscript;
-Sampler::Sampler()
+Sampler::Sampler(Context *rsc) : ObjectBase(rsc)
{
// Should not get called.
rsAssert(0);
}
-Sampler::Sampler(RsSamplerValue magFilter,
+Sampler::Sampler(Context *rsc,
+ RsSamplerValue magFilter,
RsSamplerValue minFilter,
RsSamplerValue wrapS,
RsSamplerValue wrapT,
- RsSamplerValue wrapR)
+ RsSamplerValue wrapR) : ObjectBase(rsc)
{
mMagFilter = magFilter;
mMinFilter = minFilter;
@@ -138,7 +139,8 @@ RsSampler rsi_SamplerCreate(Context *rsc)
SamplerState * ss = &rsc->mStateSampler;
- Sampler * s = new Sampler(ss->mMagFilter,
+ Sampler * s = new Sampler(rsc,
+ ss->mMagFilter,
ss->mMinFilter,
ss->mWrapS,
ss->mWrapT,
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 4b504f68cc44..ccf9b4dad5bd 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -31,7 +31,8 @@ class SamplerState;
class Sampler : public ObjectBase
{
public:
- Sampler(RsSamplerValue magFilter,
+ Sampler(Context *,
+ RsSamplerValue magFilter,
RsSamplerValue minFilter,
RsSamplerValue wrapS,
RsSamplerValue wrapT,
@@ -55,12 +56,12 @@ protected:
int32_t mBoundSlot;
private:
- Sampler();
+ Sampler(Context *);
};
-class SamplerState
+class SamplerState
{
public:
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 76fed3b04e3c..f9526fe0bfdf 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -19,7 +19,7 @@
using namespace android;
using namespace android::renderscript;
-Script::Script()
+Script::Script(Context *rsc) : ObjectBase(rsc)
{
memset(&mEnviroment, 0, sizeof(mEnviroment));
mEnviroment.mClearColor[0] = 0;
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index 97cb67a83cf6..0067fc88b78a 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -36,7 +36,7 @@ class Script : public ObjectBase
public:
typedef void (* InvokeFunc_t)(void);
- Script();
+ Script(Context *);
virtual ~Script();
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 22d42ac8287a..fc2744f7c662 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -33,7 +33,7 @@ using namespace android::renderscript;
ScriptC * sc = (ScriptC *) tls->mScript
-ScriptC::ScriptC()
+ScriptC::ScriptC(Context *rsc) : Script(rsc)
{
mAccScript = NULL;
memset(&mProgram, 0, sizeof(mProgram));
@@ -106,7 +106,7 @@ void ScriptCState::clear()
}
delete mScript;
- mScript = new ScriptC();
+ mScript = new ScriptC(NULL);
mInt32Defines.clear();
mFloatDefines.clear();
@@ -391,6 +391,7 @@ RsScript rsi_ScriptCCreate(Context * rsc)
ss->runCompiler(rsc, s);
s->incUserRef();
+ s->setContext(rsc);
for (int ct=0; ct < MAX_SCRIPT_BANKS; ct++) {
s->mTypes[ct].set(ss->mConstantBufferTypes[ct].get());
s->mSlotNames[ct] = ss->mSlotNames[ct];
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 16eb8de5fda0..96161d8c01fb 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -37,7 +37,7 @@ public:
typedef int (*RunScript_t)(uint32_t launchIndex);
typedef void (*VoidFunc_t)();
- ScriptC();
+ ScriptC(Context *);
virtual ~ScriptC();
struct Program_t {
diff --git a/libs/rs/rsSimpleMesh.cpp b/libs/rs/rsSimpleMesh.cpp
index 447bcee63e84..fe06e0cca596 100644
--- a/libs/rs/rsSimpleMesh.cpp
+++ b/libs/rs/rsSimpleMesh.cpp
@@ -22,7 +22,7 @@ using namespace android::renderscript;
#include <GLES/gl.h>
#include <GLES/glext.h>
-SimpleMesh::SimpleMesh()
+SimpleMesh::SimpleMesh(Context *rsc) : ObjectBase(rsc)
{
}
@@ -104,7 +104,7 @@ namespace renderscript {
RsSimpleMesh rsi_SimpleMeshCreate(Context *rsc, RsType prim, RsType idx, RsType *vtx, uint32_t vtxCount, uint32_t primType)
{
- SimpleMesh *sm = new SimpleMesh();
+ SimpleMesh *sm = new SimpleMesh(rsc);
sm->incUserRef();
sm->mIndexType.set((const Type *)idx);
diff --git a/libs/rs/rsSimpleMesh.h b/libs/rs/rsSimpleMesh.h
index dc5e19c6d1a9..1e5c908a0c50 100644
--- a/libs/rs/rsSimpleMesh.h
+++ b/libs/rs/rsSimpleMesh.h
@@ -29,7 +29,7 @@ namespace renderscript {
class SimpleMesh : public ObjectBase
{
public:
- SimpleMesh();
+ SimpleMesh(Context *);
~SimpleMesh();
ObjectBaseRef<const Type> mIndexType;
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 4072f066526d..964901a0426d 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -46,6 +46,10 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand)
con->timerSet(Context::RS_TIMER_IDLE);
}
const void * data = mToCore.get(&cmdID, &cmdSize);
+ if (!cmdSize) {
+ // exception occured, probably shutdown.
+ return false;
+ }
if (con->logTimes) {
con->timerSet(Context::RS_TIMER_INTERNAL);
}
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 1838fa62490f..010e49bcde47 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -20,7 +20,7 @@
using namespace android;
using namespace android::renderscript;
-Type::Type()
+Type::Type(Context *rsc) : ObjectBase(rsc)
{
mLODs = 0;
mLODCount = 0;
@@ -363,7 +363,7 @@ RsType rsi_TypeCreate(Context *rsc)
{
TypeState * stc = &rsc->mStateType;
- Type * st = new Type();
+ Type * st = new Type(rsc);
st->incUserRef();
st->setDimX(stc->mX);
st->setDimY(stc->mY);
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 6c39a4ce2396..087e50df88ac 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -27,7 +27,7 @@ namespace renderscript {
class Type : public ObjectBase
{
public:
- Type();
+ Type(Context *);
virtual ~Type();
Type * createTex2D(const Element *, size_t w, size_t h, bool mip);