Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 777ec266 authored by Jason Sams's avatar Jason Sams
Browse files

Fix issue with freeing allocation with circular references.

Change-Id: I45871c20a192815eafee77f95e17a025f6dcf9d1
parent 85deb781
Loading
Loading
Loading
Loading
+14 −13
Original line number Diff line number Diff line
@@ -58,19 +58,7 @@ void Allocation::updateCache() {
}

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);
}

@@ -299,6 +287,19 @@ void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
    }
}

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) {
}

+2 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ public:

    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 {
@@ -127,6 +128,7 @@ protected:
    Vector<const Program *> mToDirtyList;

private:
    void freeChildrenUnlocked();
    Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc);
};

+1 −0
Original line number Diff line number Diff line
@@ -312,6 +312,7 @@ void Context::destroyWorkerThreadResources() {
         mStateSampler.deinit(this);
         mFBOCache.deinit(this);
    }
    ObjectBase::freeAllChildren(this);
    //LOGV("destroyWorkerThreadResources 2");
    mExit = true;
}
+26 −0
Original line number Diff line number Diff line
@@ -81,6 +81,10 @@ void ObjectBase::incSysRef() const {
void ObjectBase::preDestroy() const {
}

bool ObjectBase::freeChildren() {
    return false;
}

bool ObjectBase::checkDelete(const ObjectBase *ref) {
    if (!ref) {
        return false;
@@ -217,6 +221,28 @@ void ObjectBase::zeroAllUserRef(Context *rsc) {
    }
}

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();

+2 −0
Original line number Diff line number Diff line
@@ -50,8 +50,10 @@ public:
    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;
Loading