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

Commit d9822a38 authored by Dan Stoza's avatar Dan Stoza
Browse files

BufferQueueProducer: add detachNextBuffer

Adds a new method, IGBP::detachNextBuffer, that effectively does
dequeue + request + detach in a single call, but does not need to
know anything about the dequeued buffer, and will not block on
dequeue. This is mostly for the upcoming StreamSplitter to use in
its onBufferReleased callback.

Change-Id: Ie88a69de109003acebaa486a5b44c8a455726550
parent 7f605bd4
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -199,6 +199,10 @@ public:
    // See IGraphicBufferProducer::detachBuffer
    virtual status_t detachProducerBuffer(int slot);

    // See IGraphicBufferProducer::detachNextBuffer
    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            sp<Fence>* outFence);

    // See IGraphicBufferProducer::attachBuffer
    virtual status_t attachProducerBuffer(int* slot,
            const sp<GraphicBuffer>& buffer);
+4 −0
Original line number Diff line number Diff line
@@ -99,6 +99,10 @@ public:
    // See IGraphicBufferProducer::detachBuffer
    virtual status_t detachBuffer(int slot);

    // See IGraphicBufferProducer::detachNextBuffer
    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            sp<Fence>* outFence);

    // See IGraphicBufferProducer::attachBuffer
    virtual status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer);

+21 −0
Original line number Diff line number Diff line
@@ -185,6 +185,27 @@ public:
    //               it refers to is not currently dequeued and requested.
    virtual status_t detachBuffer(int slot) = 0;

    // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer,
    // and detachBuffer in sequence, except for two things:
    //
    // 1) It is unnecessary to know the dimensions, format, or usage of the
    //    next buffer.
    // 2) It will not block, since if it cannot find an appropriate buffer to
    //    return, it will return an error instead.
    //
    // Only slots that are free but still contain a GraphicBuffer will be
    // considered, and the oldest of those will be returned. outBuffer is
    // equivalent to outBuffer from the requestBuffer call, and outFence is
    // equivalent to fence from the dequeueBuffer call.
    //
    // Return of a value other than NO_ERROR means an error has occurred:
    // * NO_INIT - the buffer queue has been abandoned.
    // * BAD_VALUE - either outBuffer or outFence were NULL.
    // * NO_MEMORY - no slots were found that were both free and contained a
    //               GraphicBuffer.
    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            sp<Fence>* outFence) = 0;

    // attachBuffer attempts to transfer ownership of a buffer to the buffer
    // queue. If this call succeeds, it will be as if this buffer was dequeued
    // from the returned slot number. As such, this call will fail if attaching
+5 −0
Original line number Diff line number Diff line
@@ -103,6 +103,11 @@ status_t BufferQueue::detachProducerBuffer(int slot) {
    return mProducer->detachBuffer(slot);
}

status_t BufferQueue::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
        sp<Fence>* outFence) {
    return mProducer->detachNextBuffer(outBuffer, outFence);
}

status_t BufferQueue::attachProducerBuffer(int* slot,
        const sp<GraphicBuffer>& buffer) {
    return mProducer->attachBuffer(slot, buffer);
+44 −0
Original line number Diff line number Diff line
@@ -393,6 +393,50 @@ status_t BufferQueueProducer::detachBuffer(int slot) {
    return NO_ERROR;
}

status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
        sp<Fence>* outFence) {
    ATRACE_CALL();

    if (outBuffer == NULL) {
        BQ_LOGE("detachNextBuffer: outBuffer must not be NULL");
        return BAD_VALUE;
    } else if (outFence == NULL) {
        BQ_LOGE("detachNextBuffer: outFence must not be NULL");
        return BAD_VALUE;
    }

    Mutex::Autolock lock(mCore->mMutex);

    if (mCore->mIsAbandoned) {
        BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned");
        return NO_INIT;
    }

    // Find the oldest valid slot
    int found = BufferQueueCore::INVALID_BUFFER_SLOT;
    for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
        if (mSlots[s].mBufferState == BufferSlot::FREE &&
                mSlots[s].mGraphicBuffer != NULL) {
            if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
                    mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
                found = s;
            }
        }
    }

    if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
        return NO_MEMORY;
    }

    BQ_LOGV("detachNextBuffer detached slot %d", found);

    *outBuffer = mSlots[found].mGraphicBuffer;
    *outFence = mSlots[found].mFence;
    mCore->freeBufferLocked(found);

    return NO_ERROR;
}

status_t BufferQueueProducer::attachBuffer(int* outSlot,
        const sp<android::GraphicBuffer>& buffer) {
    ATRACE_CALL();
Loading