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

Commit fdeac6c9 authored by Chong Zhang's avatar Chong Zhang
Browse files

Release buffer slot basing on reference counter

This patch introduces counter which stores number
of references kept by CodecBuffers for each GraphicBuffer
on given slot.
The counter is decreased after codec buffers emptied
and increased after buffers submitted. When counter
becomes 0 it means that given buffer slot shall be
released.

Bug: 30024369

Cherry-picked with (rebase and fix) from:

https://android-review.googlesource.com/#/c/246510/2

Change-Id: I4ecd7902a6a525f9a598682d9cccc0f771752280
parent 31682cd2
Loading
Loading
Loading
Loading
+23 −12
Original line number Diff line number Diff line
@@ -139,7 +139,6 @@ GraphicBufferSource::GraphicBufferSource(
    mRepeatLastFrameTimestamp(-1ll),
    mLatestBufferId(-1),
    mLatestBufferFrameNum(0),
    mLatestBufferUseCount(0),
    mLatestBufferFence(Fence::NO_FENCE),
    mRepeatBufferDeferred(false),
    mTimePerCaptureUs(-1ll),
@@ -398,12 +397,16 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header, int f
    sp<Fence> fence = new Fence(fenceFd);
    if (mBufferSlot[id] != NULL &&
        mBufferSlot[id]->handle == codecBuffer.mGraphicBuffer->handle) {
        ALOGV("cbi %d matches bq slot %d, handle=%p",
                cbi, id, mBufferSlot[id]->handle);
        mBufferUseCount[id]--;

        if (id == mLatestBufferId) {
            CHECK_GT(mLatestBufferUseCount--, 0);
        } else {
        ALOGV("codecBufferEmptied: slot=%d, cbi=%d, useCount=%d, handle=%p",
                id, cbi, mBufferUseCount[id], mBufferSlot[id]->handle);

        if (mBufferUseCount[id] < 0) {
            ALOGW("mBufferUseCount for bq slot %d < 0 (=%d)", id, mBufferUseCount[id]);
            mBufferUseCount[id] = 0;
        }
        if (id != mLatestBufferId && mBufferUseCount[id] == 0) {
            releaseBuffer(id, codecBuffer.mFrameNumber, mBufferSlot[id], fence);
        }
    } else {
@@ -614,6 +617,7 @@ bool GraphicBufferSource::fillCodecBuffer_l() {
    if (item.mGraphicBuffer != NULL) {
        ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mSlot);
        mBufferSlot[item.mSlot] = item.mGraphicBuffer;
        mBufferUseCount[item.mSlot] = 0;
    }

    if (item.mDataSpace != mLastDataSpace) {
@@ -699,7 +703,7 @@ bool GraphicBufferSource::repeatLatestBuffer_l() {
        return false;
    }

    ++mLatestBufferUseCount;
    ++mBufferUseCount[item.mSlot];

    /* repeat last frame up to kRepeatLastFrameCount times.
     * in case of static scene, a single repeat might not get rid of encoder
@@ -720,10 +724,8 @@ bool GraphicBufferSource::repeatLatestBuffer_l() {

void GraphicBufferSource::setLatestBuffer_l(
        const BufferItem &item, bool dropped) {
    ALOGV("setLatestBuffer_l");

    if (mLatestBufferId >= 0) {
        if (mLatestBufferUseCount == 0) {
        if (mBufferUseCount[mLatestBufferId] == 0) {
            releaseBuffer(mLatestBufferId, mLatestBufferFrameNum,
                    mBufferSlot[mLatestBufferId], mLatestBufferFence);
            // mLatestBufferFence will be set to new fence just below
@@ -734,7 +736,13 @@ void GraphicBufferSource::setLatestBuffer_l(
    mLatestBufferFrameNum = item.mFrameNumber;
    mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;

    mLatestBufferUseCount = dropped ? 0 : 1;
    if (!dropped) {
        ++mBufferUseCount[item.mSlot];
    }

    ALOGV("setLatestBuffer_l: slot=%d, useCount=%d",
            item.mSlot, mBufferUseCount[item.mSlot]);

    mRepeatBufferDeferred = false;
    mRepeatLastFrameCount = kRepeatLastFrameCount;
    mLatestBufferFence = item.mFence;
@@ -842,7 +850,7 @@ int64_t GraphicBufferSource::getTimestamp(const BufferItem &item) {
}

status_t GraphicBufferSource::submitBuffer_l(const BufferItem &item, int cbi) {
    ALOGV("submitBuffer_l cbi=%d", cbi);
    ALOGV("submitBuffer_l: slot=%d, cbi=%d", item.mSlot, cbi);

    int64_t timeUs = getTimestamp(item);
    if (timeUs < 0ll) {
@@ -935,6 +943,7 @@ int GraphicBufferSource::findMatchingCodecBuffer_l(
void GraphicBufferSource::releaseBuffer(
        int &id, uint64_t frameNum,
        const sp<GraphicBuffer> buffer, const sp<Fence> &fence) {
    ALOGV("releaseBuffer: slot=%d", id);
    if (mIsPersistent) {
        mConsumer->detachBuffer(id);
        mBufferSlot[id] = NULL;
@@ -978,6 +987,7 @@ void GraphicBufferSource::onFrameAvailable(const BufferItem& /*item*/) {
            if (item.mGraphicBuffer != NULL) {
                ALOGV("onFrameAvailable: setting mBufferSlot %d", item.mSlot);
                mBufferSlot[item.mSlot] = item.mGraphicBuffer;
                mBufferUseCount[item.mSlot] = 0;
            }

            releaseBuffer(item.mSlot, item.mFrameNumber,
@@ -1011,6 +1021,7 @@ void GraphicBufferSource::onBuffersReleased() {
    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
        if ((slotMask & 0x01) != 0) {
            mBufferSlot[i] = NULL;
            mBufferUseCount[i] = 0;
        }
        slotMask >>= 1;
    }
+1 −1
Original line number Diff line number Diff line
@@ -295,6 +295,7 @@ private:
    // is done processing a GraphicBuffer, we can use this to map back
    // to a slot number.
    sp<GraphicBuffer> mBufferSlot[BufferQueue::NUM_BUFFER_SLOTS];
    int32_t mBufferUseCount[BufferQueue::NUM_BUFFER_SLOTS];

    // Tracks codec buffers.
    Vector<CodecBuffer> mCodecBuffers;
@@ -327,7 +328,6 @@ private:

    int mLatestBufferId;
    uint64_t mLatestBufferFrameNum;
    int32_t mLatestBufferUseCount;
    sp<Fence> mLatestBufferFence;

    // The previous buffer should've been repeated but