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

Commit f7519f3c authored by Naomi Luis's avatar Naomi Luis Committed by Giulio Cervera
Browse files

Hold a reference to the allocated buffers in GraphicBufferAlloc

Store the allocated GraphicBuffers in a vector list. This list is
cleared only when SurfaceTextures requests that the buffers be freed.
Premature deletion of GraphicBuffers and therefore deallocation of
gralloc handles are prevented.

This change partially reverts:
commit 5f05f99a
Author: Mathias Agopian <mathias@google.com>
Date:   Fri Apr 8 19:10:43 2011 -0700

    Fix a GraphicBuffer leak in SurfaceTexture

    This leak was intentional, it was there to deal with the fact that
    some gralloc implementations don't track buffer handles with
    file-descriptors so buffers needed to stay alive until there were
    registered, which is not guaranteed by binder transactions.

Change-Id: Ia732806bf8d8d15b66944569e8aa2120641d9812
CRs-fixed: 327655
parent e8eaa711
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -38,6 +38,14 @@ public:
     */
    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
            PixelFormat format, uint32_t usage, status_t* error) = 0;

#ifdef QCOM_HARDWARE
    /* Free all but one of the GraphicBuffer objects that the server is
     * currently referencing. If bufIndex is not a valid index of the buffers
     * the server is referencing, then all buffers are freed.
     */
    virtual void freeAllGraphicBuffersExcept(int bufIndex) = 0;
#endif
};

// ----------------------------------------------------------------------------
+21 −0
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@ namespace android {

enum {
    CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
#ifdef QCOM_HARDWARE
    FREE_ALL_GRAPHIC_BUFFERS_EXCEPT,
#endif
};

class BpGraphicBufferAlloc : public BpInterface<IGraphicBufferAlloc>
@@ -63,6 +66,16 @@ public:
        *error = result;
        return graphicBuffer;
    }

#ifdef QCOM_HARDWARE
    virtual void freeAllGraphicBuffersExcept(int bufIdx) {
        Parcel data, reply;
        data.writeInterfaceToken(
                IGraphicBufferAlloc::getInterfaceDescriptor());
        data.writeInt32(bufIdx);
        remote()->transact(FREE_ALL_GRAPHIC_BUFFERS_EXCEPT, data, &reply);
    }
#endif
};

IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
@@ -108,6 +121,14 @@ status_t BnGraphicBufferAlloc::onTransact(
            }
            return NO_ERROR;
        } break;
#ifdef QCOM_HARDWARE
        case FREE_ALL_GRAPHIC_BUFFERS_EXCEPT: {
            CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
            int bufIdx = data.readInt32();
            freeAllGraphicBuffersExcept(bufIdx);
            return NO_ERROR;
        } break;
#endif
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+6 −0
Original line number Diff line number Diff line
@@ -1104,6 +1104,9 @@ void SurfaceTexture::freeAllBuffersLocked() {
    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
        freeBufferLocked(i);
    }
#ifdef QCOM_HARDWARE
    mGraphicBufferAlloc->freeAllGraphicBuffersExcept(-1);
#endif
}

void SurfaceTexture::freeAllBuffersExceptHeadLocked() {
@@ -1120,6 +1123,9 @@ void SurfaceTexture::freeAllBuffersExceptHeadLocked() {
            freeBufferLocked(i);
        }
    }
#ifdef QCOM_HARDWARE
    mGraphicBufferAlloc->freeAllGraphicBuffersExcept(head);
#endif
}

status_t SurfaceTexture::drainQueueLocked() {
+16 −0
Original line number Diff line number Diff line
@@ -2724,9 +2724,25 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h
                w, h, strerror(-err), graphicBuffer->handle);
        return 0;
    }
#ifdef QCOM_HARDWARE
    Mutex::Autolock _l(mLock);
    mBuffers.add(graphicBuffer);
#endif
    return graphicBuffer;
}

#ifdef QCOM_HARDWARE
void GraphicBufferAlloc::freeAllGraphicBuffersExcept(int bufIdx) {
    Mutex::Autolock _l(mLock);
    if (0 <= bufIdx && bufIdx < mBuffers.size()) {
        sp<GraphicBuffer> b(mBuffers[bufIdx]);
        mBuffers.clear();
        mBuffers.add(b);
    } else {
        mBuffers.clear();
    }
}
#endif
// ---------------------------------------------------------------------------

GraphicPlane::GraphicPlane()
+6 −0
Original line number Diff line number Diff line
@@ -97,6 +97,12 @@ public:
    virtual ~GraphicBufferAlloc();
    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
        PixelFormat format, uint32_t usage, status_t* error);
#ifdef QCOM_HARDWARE
    virtual void freeAllGraphicBuffersExcept(int bufIdx);
private:
    Vector<sp<GraphicBuffer> > mBuffers;
    Mutex mLock;
#endif
};

// ---------------------------------------------------------------------------