}
Allocation::~Allocation() {
- if (mHal.state.hasReferences &&
- (mHal.state.hasFaces || mHal.state.hasMipmaps)) {
- LOGE("Cube/mip allocation with references unsupported, memory not cleaned up!");
- }
-
- uint32_t elemCount = mHal.state.dimensionX;
- if (mHal.state.dimensionY > 1) {
- elemCount *= mHal.state.dimensionY;
- }
- if (mHal.state.dimensionZ > 1) {
- elemCount *= mHal.state.dimensionZ;
- }
- decRefs(getPtr(), elemCount, 0);
+ freeChildrenUnlocked();
mRSC->mHal.funcs.allocation.destroy(mRSC, this);
}
}
}
+void Allocation::freeChildrenUnlocked () {
+ decRefs(getPtr(), mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes(), 0);
+}
+
+bool Allocation::freeChildren() {
+ if (mHal.state.hasReferences) {
+ incSysRef();
+ freeChildrenUnlocked();
+ return decSysRef();
+ }
+ return false;
+}
+
void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
}
void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
+ virtual bool freeChildren();
void sendDirty(const Context *rsc) const;
bool getHasGraphicsMipmaps() const {
Vector<const Program *> mToDirtyList;
private:
+ void freeChildrenUnlocked();
Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc);
};
mStateSampler.deinit(this);
mFBOCache.deinit(this);
}
+ ObjectBase::freeAllChildren(this);
//LOGV("destroyWorkerThreadResources 2");
mExit = true;
}
void ObjectBase::preDestroy() const {
}
+bool ObjectBase::freeChildren() {
+ return false;
+}
+
bool ObjectBase::checkDelete(const ObjectBase *ref) {
if (!ref) {
return false;
}
}
+void ObjectBase::freeAllChildren(Context *rsc) {
+ if (rsc->props.mLogObjects) {
+ LOGV("Forcing release of all child objects.");
+ }
+
+ // This operation can be slow, only to be called during context cleanup.
+ ObjectBase * o = (ObjectBase *)rsc->mObjHead;
+ while (o) {
+ if (o->freeChildren()) {
+ // deleted ref to self and possibly others, restart from head.
+ o = (ObjectBase *)rsc->mObjHead;
+ } else {
+ o = (ObjectBase *)o->mNext;
+ }
+ }
+
+ if (rsc->props.mLogObjects) {
+ LOGV("Objects remaining.");
+ dumpAll(rsc);
+ }
+}
+
void ObjectBase::dumpAll(Context *rsc) {
asyncLock();
void setName(const char *, uint32_t len);
Context * getContext() const {return mRSC;}
+ virtual bool freeChildren();
static void zeroAllUserRef(Context *rsc);
+ static void freeAllChildren(Context *rsc);
static void dumpAll(Context *rsc);
virtual void dumpLOGV(const char *prefix) const;
}
Program::~Program() {
+ freeChildren();
- for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) {
- bindAllocation(NULL, NULL, ct);
- }
-
- for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
- bindTexture(NULL, ct, NULL);
- bindSampler(NULL, ct, NULL);
- }
delete[] mHal.state.textures;
delete[] mHal.state.samplers;
delete[] mHal.state.textureTargets;
mHal.state.texturesCount = 0;
}
+bool Program::freeChildren() {
+ for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) {
+ bindAllocation(NULL, NULL, ct);
+ }
+
+ for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) {
+ bindTexture(NULL, ct, NULL);
+ bindSampler(NULL, ct, NULL);
+ }
+ return false;
+}
+
void Program::initMemberVars() {
mDirty = true;
Program(Context *, const char * shaderText, uint32_t shaderLength,
const uint32_t * params, uint32_t paramLength);
virtual ~Program();
+ virtual bool freeChildren();
void bindAllocation(Context *, Allocation *, uint32_t slot);