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

Commit 23b4abe0 authored by Pablo Ceballos's avatar Pablo Ceballos
Browse files

BQ: Improved buffer/slot tracking

- Explicitly track active buffers and unused slots on top of the
  already existing tracking for free slots and free buffers.

Change-Id: Ife2678678e96f0eb0b3fb21571058378134bd868
parent c2a3d7aa
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -125,6 +125,10 @@ class BufferItem : public Flattenable<BufferItem> {
    // Indicates that this buffer was queued by the producer. When in single
    // buffer mode acquire() can return a BufferItem that wasn't in the queue.
    bool mQueuedBuffer;

    // Indicates that this BufferItem contains a stale buffer which has already
    // been released by the BufferQueue.
    bool mIsStale;
};

} // namespace android
+20 −7
Original line number Diff line number Diff line
@@ -105,17 +105,23 @@ private:
    // connected, mDequeueCondition must be broadcast.
    int getMaxBufferCountLocked() const;

    // freeBufferLocked frees the GraphicBuffer and sync resources for the
    // This performs the same computation but uses the given arguments instead
    // of the member variables for mMaxBufferCount, mAsyncMode, and
    // mDequeueBufferCannotBlock.
    int getMaxBufferCountLocked(bool asyncMode,
            bool dequeueBufferCannotBlock, int maxBufferCount) const;

    // clearBufferSlotLocked frees the GraphicBuffer and sync resources for the
    // given slot.
    void freeBufferLocked(int slot, bool validate = true);
    void clearBufferSlotLocked(int slot);

    // freeAllBuffersLocked frees the GraphicBuffer and sync resources for
    // all slots, even if they're currently dequeued, queued, or acquired.
    void freeAllBuffersLocked();

    // stillTracking returns true iff the buffer item is still being tracked
    // in one of the slots.
    bool stillTracking(const BufferItem* item) const;
    // If delta is positive, makes more slots available. If negative, takes
    // away slots. Returns false if the request can't be met.
    bool adjustAvailableSlotsLocked(int delta);

    // waitWhileAllocatingLocked blocks until mIsAllocating is false.
    void waitWhileAllocatingLocked() const;
@@ -179,13 +185,20 @@ private:
    Fifo mQueue;

    // mFreeSlots contains all of the slots which are FREE and do not currently
    // have a buffer attached
    // have a buffer attached.
    std::set<int> mFreeSlots;

    // mFreeBuffers contains all of the slots which are FREE and currently have
    // a buffer attached
    // a buffer attached.
    std::list<int> mFreeBuffers;

    // mUnusedSlots contains all slots that are currently unused. They should be
    // free and not have a buffer attached.
    std::list<int> mUnusedSlots;

    // mActiveBuffers contains all slots which have a non-FREE buffer attached.
    std::set<int> mActiveBuffers;

    // mDequeueCondition is a condition variable used for dequeueBuffer in
    // synchronous mode.
    mutable Condition mDequeueCondition;
+4 −5
Original line number Diff line number Diff line
@@ -187,9 +187,9 @@ private:
    // BufferQueueCore::INVALID_BUFFER_SLOT otherwise
    int getFreeBufferLocked() const;

    // Returns the next free slot if one less than or equal to maxBufferCount
    // is available or BufferQueueCore::INVALID_BUFFER_SLOT otherwise
    int getFreeSlotLocked(int maxBufferCount) const;
    // Returns the next free slot if one is available or
    // BufferQueueCore::INVALID_BUFFER_SLOT otherwise
    int getFreeSlotLocked() const;

    // 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
@@ -200,8 +200,7 @@ private:
        Dequeue,
        Attach,
    };
    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, int* found,
            status_t* returnFlags) const;
    status_t waitForFreeSlotThenRelock(FreeSlotCaller caller, int* found) const;

    sp<BufferQueueCore> mCore;

+8 −14
Original line number Diff line number Diff line
@@ -174,14 +174,15 @@ struct BufferState {
struct BufferSlot {

    BufferSlot()
    : mEglDisplay(EGL_NO_DISPLAY),
    : mGraphicBuffer(nullptr),
      mEglDisplay(EGL_NO_DISPLAY),
      mBufferState(),
      mRequestBufferCalled(false),
      mFrameNumber(0),
      mEglFence(EGL_NO_SYNC_KHR),
      mFence(Fence::NO_FENCE),
      mAcquireCalled(false),
      mNeedsCleanupOnRelease(false),
      mAttachedByConsumer(false) {
      mNeedsReallocation(false) {
    }

    // mGraphicBuffer points to the buffer allocated for this slot or is NULL
@@ -191,8 +192,6 @@ struct BufferSlot {
    // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
    EGLDisplay mEglDisplay;

    static const char* bufferStateName(BufferState state);

    // mBufferState is the current state of this buffer slot.
    BufferState mBufferState;

@@ -227,15 +226,10 @@ struct BufferSlot {
    // Indicates whether this buffer has been seen by a consumer yet
    bool mAcquireCalled;

    // Indicates whether this buffer needs to be cleaned up by the
    // 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;
    // Indicates whether the buffer was re-allocated without notifying the
    // producer. If so, it needs to set the BUFFER_NEEDS_REALLOCATION flag when
    // dequeued to prevent the producer from using a stale cached buffer.
    bool mNeedsReallocation;
};

} // namespace android
+6 −2
Original line number Diff line number Diff line
@@ -199,7 +199,9 @@ public:
    // cannot be less than maxAcquiredBufferCount.
    //
    // Return of a value other than NO_ERROR means an error has occurred:
    // * BAD_VALUE - bufferCount was out of range (see above).
    // * BAD_VALUE - one of the below conditions occurred:
    //             * bufferCount was out of range (see above).
    //             * failure to adjust the number of available slots.
    // * INVALID_OPERATION - attempting to call this after a producer connected.
    virtual status_t setMaxBufferCount(int bufferCount) = 0;

@@ -212,7 +214,9 @@ public:
    // to be exceeded.
    //
    // Return of a value other than NO_ERROR means an error has occurred:
    // * BAD_VALUE - maxAcquiredBuffers was out of range (see above).
    // * BAD_VALUE - one of the below conditions occurred:
    //             * maxAcquiredBuffers was out of range (see above).
    //             * failure to adjust the number of available slots.
    // * INVALID_OPERATION - attempting to call this after a producer connected.
    virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) = 0;

Loading