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

Commit c9ed7d37 authored by Dan Stoza's avatar Dan Stoza Committed by Android (Google) Code Review
Browse files

Merge "BufferQueue: Allow detaching/reattaching buffers"

parents e98151e0 9f3053de
Loading
Loading
Loading
Loading
+54 −3
Original line number Diff line number Diff line
@@ -28,10 +28,43 @@
#include <binder/IBinder.h>

namespace android {
// ----------------------------------------------------------------------------

class BufferQueue : public BnGraphicBufferProducer,
                    public BnGraphicBufferConsumer,
// BQProducer and BQConsumer are thin shim classes to allow methods with the
// same signature in both IGraphicBufferProducer and IGraphicBufferConsumer.
// This will stop being an issue when we deprecate creating BufferQueues
// directly (as opposed to using the *Producer and *Consumer interfaces).
class BQProducer : public BnGraphicBufferProducer {
public:
    virtual status_t detachProducerBuffer(int slot) = 0;
    virtual status_t attachProducerBuffer(int* slot,
            const sp<GraphicBuffer>& buffer) = 0;

    virtual status_t detachBuffer(int slot) {
        return detachProducerBuffer(slot);
    }

    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
        return attachProducerBuffer(slot, buffer);
    }
};

class BQConsumer : public BnGraphicBufferConsumer {
public:
    virtual status_t detachConsumerBuffer(int slot) = 0;
    virtual status_t attachConsumerBuffer(int* slot,
            const sp<GraphicBuffer>& buffer) = 0;

    virtual status_t detachBuffer(int slot) {
        return detachConsumerBuffer(slot);
    }

    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
        return attachConsumerBuffer(slot, buffer);
    }
};

class BufferQueue : public BQProducer,
                    public BQConsumer,
                    private IBinder::DeathRecipient {
public:
    // BufferQueue will keep track of at most this value of buffers.
@@ -73,6 +106,10 @@ public:
        wp<ConsumerListener> mConsumerListener;
    };

    static void createBufferQueue(sp<BnGraphicBufferProducer>* outProducer,
            sp<BnGraphicBufferConsumer>* outConsumer,
            const sp<IGraphicBufferAlloc>& allocator = NULL);

    // BufferQueue manages a pool of gralloc memory slots to be used by
    // producers and consumers. allocator is used to allocate all the
    // needed gralloc buffers.
@@ -157,6 +194,13 @@ public:
    virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
            uint32_t width, uint32_t height, uint32_t format, uint32_t usage);

    // See IGraphicBufferProducer::detachBuffer
    virtual status_t detachProducerBuffer(int slot);

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

    // queueBuffer returns a filled buffer to the BufferQueue.
    //
    // Additional data is provided in the QueueBufferInput struct.  Notably,
@@ -223,6 +267,13 @@ public:
    // is CLOCK_MONOTONIC.
    virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen);

    // See IGraphicBufferConsumer::detachBuffer
    virtual status_t detachConsumerBuffer(int slot);

    // See IGraphicBufferConsumer::attachBuffer
    virtual status_t attachConsumerBuffer(int* slot,
            const sp<GraphicBuffer>& buffer);

    // releaseBuffer releases a buffer slot from the consumer back to the
    // BufferQueue.  This may be done while the buffer's contents are still
    // being accessed.  The fence will signal when the buffer is no longer
+6 −0
Original line number Diff line number Diff line
@@ -49,6 +49,12 @@ public:
    virtual status_t acquireBuffer(BufferItem* outBuffer,
            nsecs_t expectedPresent);

    // See IGraphicBufferConsumer::detachBuffer
    virtual status_t detachBuffer(int slot);

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

    // releaseBuffer releases a buffer slot from the consumer back to the
    // BufferQueue.  This may be done while the buffer's contents are still
    // being accessed.  The fence will signal when the buffer is no longer
+14 −0
Original line number Diff line number Diff line
@@ -96,6 +96,12 @@ public:
    virtual status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence, bool async,
            uint32_t width, uint32_t height, uint32_t format, uint32_t usage);

    // See IGraphicBufferProducer::detachBuffer
    virtual status_t detachBuffer(int slot);

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

    // queueBuffer returns a filled buffer to the BufferQueue.
    //
    // Additional data is provided in the QueueBufferInput struct.  Notably,
@@ -151,6 +157,14 @@ private:
    // This is required by the IBinder::DeathRecipient interface
    virtual void binderDied(const wp<IBinder>& who);

    // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may
    // block if there are no available slots and we are not in non-blocking
    // mode (producer and consumer controlled by the application). If it blocks,
    // it will release mCore->mMutex while blocked so that other operations on
    // the BufferQueue may succeed.
    status_t waitForFreeSlotThenRelock(const char* caller, bool async,
            int* found, status_t* returnFlags) const;

    sp<BufferQueueCore> mCore;

    // This references mCore->mSlots. Lock mCore->mMutex while accessing.
+7 −1
Original line number Diff line number Diff line
@@ -38,7 +38,8 @@ struct BufferSlot {
      mFrameNumber(0),
      mEglFence(EGL_NO_SYNC_KHR),
      mAcquireCalled(false),
      mNeedsCleanupOnRelease(false) {
      mNeedsCleanupOnRelease(false),
      mAttachedByConsumer(false) {
    }

    // mGraphicBuffer points to the buffer allocated for this slot or is NULL
@@ -129,6 +130,11 @@ struct BufferSlot {
    // consumer.  This is set when a buffer in ACQUIRED state is freed.
    // It causes releaseBuffer to return STALE_BUFFER_SLOT.
    bool mNeedsCleanupOnRelease;

    // Indicates whether the buffer was attached on the consumer side.
    // If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when dequeued
    // to prevent the producer from using a stale cached buffer.
    bool mAttachedByConsumer;
};

} // namespace android
+30 −0
Original line number Diff line number Diff line
@@ -139,6 +139,36 @@ public:
    // * INVALID_OPERATION - too many buffers have been acquired
    virtual status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen) = 0;

    // detachBuffer attempts to remove all ownership of the buffer in the given
    // slot from the buffer queue. If this call succeeds, the slot will be
    // freed, and there will be no way to obtain the buffer from this interface.
    // The freed slot will remain unallocated until either it is selected to
    // hold a freshly allocated buffer in dequeueBuffer or a buffer is attached
    // to the slot. The buffer must have already been acquired.
    //
    // Return of a value other than NO_ERROR means an error has occurred:
    // * BAD_VALUE - the given slot number is invalid, either because it is
    //               out of the range [0, NUM_BUFFER_SLOTS) or because the slot
    //               it refers to is not currently acquired.
    virtual status_t detachBuffer(int slot) = 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 acquired
    // from the returned slot number. As such, this call will fail if attaching
    // this buffer would cause too many buffers to be simultaneously acquired.
    //
    // If the buffer is successfully attached, its frameNumber is initialized
    // to 0. This must be passed into the releaseBuffer call or else the buffer
    // will be deallocated as stale.
    //
    // Return of a value other than NO_ERROR means an error has occurred:
    // * BAD_VALUE - outSlot or buffer were NULL
    // * INVALID_OPERATION - cannot attach the buffer because it would cause too
    //                       many buffers to be acquired.
    // * NO_MEMORY - no free slots available
    virtual status_t attachBuffer(int *outSlot,
            const sp<GraphicBuffer>& buffer) = 0;

    // releaseBuffer releases a buffer slot from the consumer back to the
    // BufferQueue.  This may be done while the buffer's contents are still
    // being accessed.  The fence will signal when the buffer is no longer
Loading