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

Commit 6eaede6a authored by Pablo Ceballos's avatar Pablo Ceballos Committed by Android (Google) Code Review
Browse files

Merge changes from topic 'single_buffer_mode'

* changes:
  SF: Force refresh when in single buffer mode
  BQ: Add support for single buffer mode
parents 180d61db 06312184
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -118,6 +118,13 @@ class BufferItem : public Flattenable<BufferItem> {
    // Describes the portion of the surface that has been modified since the
    // previous frame
    Region mSurfaceDamage;

    // Indicates that the BufferQueue is in single buffer mode
    bool mSingleBufferMode;

    // 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;
};

} // namespace android
+28 −2
Original line number Diff line number Diff line
@@ -107,10 +107,10 @@ private:

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

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

    // stillTracking returns true iff the buffer item is still being tracked
@@ -271,6 +271,32 @@ private:
    // enqueue buffers without blocking.
    bool mAsyncMode;

    // mSingleBufferMode indicates whether or not single buffer mode is enabled.
    // In single buffer mode, the last buffer that was dequeued is cached and
    // returned to all calls to dequeueBuffer and acquireBuffer. This allows the
    // consumer and producer to access the same buffer simultaneously.
    bool mSingleBufferMode;

    // When single buffer mode is enabled, this tracks which slot contains the
    // shared buffer.
    int mSingleBufferSlot;

    // Cached data about the shared buffer in single buffer mode
    struct SingleBufferCache {
        SingleBufferCache(Rect _crop, uint32_t _transform, int _scalingMode,
                android_dataspace _dataspace)
        : crop(_crop),
          transform(_transform),
          scalingMode(_scalingMode),
          dataspace(_dataspace) {
        };

        Rect crop;
        uint32_t transform;
        uint32_t scalingMode;
        android_dataspace dataspace;
    } mSingleBufferCache;

}; // class BufferQueueCore

} // namespace android
+3 −0
Original line number Diff line number Diff line
@@ -173,6 +173,9 @@ public:
    // See IGraphicBufferProducer::getNextFrameNumber
    virtual uint64_t getNextFrameNumber() const override;

    // See IGraphicBufferProducer::setSingleBufferMode
    virtual status_t setSingleBufferMode(bool singleBufferMode);

private:
    // This is required by the IBinder::DeathRecipient interface
    virtual void binderDied(const wp<IBinder>& who);
+143 −42
Original line number Diff line number Diff line
@@ -29,11 +29,153 @@ namespace android {

class Fence;

// BufferState tracks the states in which a buffer slot can be.
struct BufferState {

    // All slots are initially FREE (not dequeued, queued, acquired, or shared).
    BufferState()
    : mDequeueCount(0),
      mQueueCount(0),
      mAcquireCount(0),
      mShared(false) {
    }

    uint32_t mDequeueCount;
    uint32_t mQueueCount;
    uint32_t mAcquireCount;
    bool mShared;

    // A buffer can be in one of five states, represented as below:
    //
    //         | mShared | mDequeueCount | mQueueCount | mAcquireCount |
    // --------|---------|---------------|-------------|---------------|
    // FREE    |  false  |       0       |      0      |       0       |
    // DEQUEUED|  false  |       1       |      0      |       0       |
    // QUEUED  |  false  |       0       |      1      |       0       |
    // ACQUIRED|  false  |       0       |      0      |       1       |
    // SHARED  |  true   |      any      |     any     |      any      |
    //
    // FREE indicates that the buffer is available to be dequeued by the
    // producer. The slot is "owned" by BufferQueue. It transitions to DEQUEUED
    // when dequeueBuffer is called.
    //
    // DEQUEUED indicates that the buffer has been dequeued by the producer, but
    // has not yet been queued or canceled. The producer may modify the
    // buffer's contents as soon as the associated release fence is signaled.
    // The slot is "owned" by the producer. It can transition to QUEUED (via
    // queueBuffer or attachBuffer) or back to FREE (via cancelBuffer or
    // detachBuffer).
    //
    // QUEUED indicates that the buffer has been filled by the producer and
    // queued for use by the consumer. The buffer contents may continue to be
    // modified for a finite time, so the contents must not be accessed until
    // the associated fence is signaled. The slot is "owned" by BufferQueue. It
    // can transition to ACQUIRED (via acquireBuffer) or to FREE (if another
    // buffer is queued in asynchronous mode).
    //
    // ACQUIRED indicates that the buffer has been acquired by the consumer. As
    // with QUEUED, the contents must not be accessed by the consumer until the
    // acquire fence is signaled. The slot is "owned" by the consumer. It
    // transitions to FREE when releaseBuffer (or detachBuffer) is called. A
    // detached buffer can also enter the ACQUIRED state via attachBuffer.
    //
    // SHARED indicates that this buffer is being used in single-buffer
    // mode. It can be in any combination of the other states at the same time,
    // except for FREE (since that excludes being in any other state). It can
    // also be dequeued, queued, or acquired multiple times.

    inline bool isFree() const {
        return !isAcquired() && !isDequeued() && !isQueued();
    }

    inline bool isDequeued() const {
        return mDequeueCount > 0;
    }

    inline bool isQueued() const {
        return mQueueCount > 0;
    }

    inline bool isAcquired() const {
        return mAcquireCount > 0;
    }

    inline bool isShared() const {
        return mShared;
    }

    inline void reset() {
        *this = BufferState();
    }

    const char* string() const;

    inline void dequeue() {
        mDequeueCount++;
    }

    inline void detachProducer() {
        if (mDequeueCount > 0) {
            mDequeueCount--;
        }
    }

    inline void attachProducer() {
        mDequeueCount++;
    }

    inline void queue() {
        if (mDequeueCount > 0) {
            mDequeueCount--;
        }
        mQueueCount++;
    }

    inline void cancel() {
        if (mDequeueCount > 0) {
            mDequeueCount--;
        }
    }

    inline void freeQueued() {
        if (mQueueCount > 0) {
            mQueueCount--;
        }
    }

    inline void acquire() {
        if (mQueueCount > 0) {
            mQueueCount--;
        }
        mAcquireCount++;
    }

    inline void acquireNotInQueue() {
        mAcquireCount++;
    }

    inline void release() {
        if (mAcquireCount > 0) {
            mAcquireCount--;
        }
    }

    inline void detachConsumer() {
        if (mAcquireCount > 0) {
            mAcquireCount--;
        }
    }

    inline void attachConsumer() {
        mAcquireCount++;
    }
};

struct BufferSlot {

    BufferSlot()
    : mEglDisplay(EGL_NO_DISPLAY),
      mBufferState(BufferSlot::FREE),
      mBufferState(),
      mRequestBufferCalled(false),
      mFrameNumber(0),
      mEglFence(EGL_NO_SYNC_KHR),
@@ -49,47 +191,6 @@ struct BufferSlot {
    // mEglDisplay is the EGLDisplay used to create EGLSyncKHR objects.
    EGLDisplay mEglDisplay;

    // BufferState represents the different states in which a buffer slot
    // can be.  All slots are initially FREE.
    enum BufferState {
        // FREE indicates that the buffer is available to be dequeued
        // by the producer.  The buffer may be in use by the consumer for
        // a finite time, so the buffer must not be modified until the
        // associated fence is signaled.
        //
        // The slot is "owned" by BufferQueue.  It transitions to DEQUEUED
        // when dequeueBuffer is called.
        FREE = 0,

        // DEQUEUED indicates that the buffer has been dequeued by the
        // producer, but has not yet been queued or canceled.  The
        // producer may modify the buffer's contents as soon as the
        // associated ready fence is signaled.
        //
        // The slot is "owned" by the producer.  It can transition to
        // QUEUED (via queueBuffer) or back to FREE (via cancelBuffer).
        DEQUEUED = 1,

        // QUEUED indicates that the buffer has been filled by the
        // producer and queued for use by the consumer.  The buffer
        // contents may continue to be modified for a finite time, so
        // the contents must not be accessed until the associated fence
        // is signaled.
        //
        // The slot is "owned" by BufferQueue.  It can transition to
        // ACQUIRED (via acquireBuffer) or to FREE (if another buffer is
        // queued in asynchronous mode).
        QUEUED = 2,

        // ACQUIRED indicates that the buffer has been acquired by the
        // consumer.  As with QUEUED, the contents must not be accessed
        // by the consumer until the fence is signaled.
        //
        // The slot is "owned" by the consumer.  It transitions to FREE
        // when releaseBuffer is called.
        ACQUIRED = 3
    };

    static const char* bufferStateName(BufferState state);

    // mBufferState is the current state of this buffer slot.
+7 −0
Original line number Diff line number Diff line
@@ -511,6 +511,13 @@ public:

    // Returns the number of the next frame which will be dequeued.
    virtual uint64_t getNextFrameNumber() const = 0;

    // Used to enable/disable single buffer mode.
    //
    // In single buffer mode the last buffer that was dequeued will be cached
    // and returned to all calls to dequeueBuffer and acquireBuffer. This allows
    // the producer and consumer to simultaneously access the same buffer.
    virtual status_t setSingleBufferMode(bool singleBufferMode) = 0;
};

// ----------------------------------------------------------------------------
Loading