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

Commit 72f096fb authored by Jamie Gennis's avatar Jamie Gennis Committed by Android (Google) Code Review
Browse files

BufferQueue: use max acquired buffer count

This change makes BufferQueue derive the min undequeued buffer count from a max
acquired buffer count that is set by the consumer.  This value may be set at
any time that a producer is not connected to the BufferQueue rather than at
BufferQueue construction time.

Change-Id: Icf9f1d91ec612a079968ba0a4621deffe48f4e22
parent 1847f7fd
Loading
Loading
Loading
Loading
+22 −10
Original line number Original line Diff line number Diff line
@@ -92,13 +92,11 @@ public:
    };
    };




    // BufferQueue manages a pool of gralloc memory slots to be used
    // BufferQueue manages a pool of gralloc memory slots to be used by
    // by producers and consumers.
    // producers and consumers. allowSynchronousMode specifies whether or not
    // allowSynchronousMode specifies whether or not synchronous mode can be
    // synchronous mode can be enabled by the producer. allocator is used to
    // enabled.
    // allocate all the needed gralloc buffers.
    // bufferCount sets the minimum number of undequeued buffers for this queue
    BufferQueue(bool allowSynchronousMode = true,
    BufferQueue(bool allowSynchronousMode = true,
            int bufferCount = MIN_UNDEQUEUED_BUFFERS,
            const sp<IGraphicBufferAlloc>& allocator = NULL);
            const sp<IGraphicBufferAlloc>& allocator = NULL);
    virtual ~BufferQueue();
    virtual ~BufferQueue();


@@ -257,6 +255,11 @@ public:
    // take effect once the client sets the count back to zero.
    // take effect once the client sets the count back to zero.
    status_t setDefaultMaxBufferCount(int bufferCount);
    status_t setDefaultMaxBufferCount(int bufferCount);


    // setMaxAcquiredBufferCount sets the maximum number of buffers that can
    // be acquired by the consumer at one time.  This call will fail if a
    // producer is connected to the BufferQueue.
    status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);

    // isSynchronousMode returns whether the SurfaceTexture is currently in
    // isSynchronousMode returns whether the SurfaceTexture is currently in
    // synchronous mode.
    // synchronous mode.
    bool isSynchronousMode() const;
    bool isSynchronousMode() const;
@@ -307,12 +310,16 @@ private:
    // given the current BufferQueue state.
    // given the current BufferQueue state.
    int getMinMaxBufferCountLocked() const;
    int getMinMaxBufferCountLocked() const;


    // getMinUndequeuedBufferCountLocked returns the minimum number of buffers
    // that must remain in a state other than DEQUEUED.
    int getMinUndequeuedBufferCountLocked() const;

    // getMaxBufferCountLocked returns the maximum number of buffers that can
    // getMaxBufferCountLocked returns the maximum number of buffers that can
    // be allocated at once.  This value depends upon the following member
    // be allocated at once.  This value depends upon the following member
    // variables:
    // variables:
    //
    //
    //      mSynchronousMode
    //      mSynchronousMode
    //      mMinUndequeuedBuffers
    //      mMaxAcquiredBufferCount
    //      mDefaultMaxBufferCount
    //      mDefaultMaxBufferCount
    //      mOverrideMaxBufferCount
    //      mOverrideMaxBufferCount
    //
    //
@@ -442,9 +449,14 @@ private:
    // in requestBuffers() if a width and height of zero is specified.
    // in requestBuffers() if a width and height of zero is specified.
    uint32_t mDefaultHeight;
    uint32_t mDefaultHeight;


    // mMinUndequeuedBuffers is a constraint on the number of buffers
    // mMaxAcquiredBufferCount is the number of buffers that the consumer may
    // not dequeued at any time
    // acquire at one time.  It defaults to 1 and can be changed by the
    int mMinUndequeuedBuffers;
    // consumer via the setMaxAcquiredBufferCount method, but this may only be
    // done when no producer is connected to the BufferQueue.
    //
    // This value is used to derive the value returned for the
    // MIN_UNDEQUEUED_BUFFERS query by the producer.
    int mMaxAcquiredBufferCount;


    // mDefaultMaxBufferCount is the default limit on the number of buffers
    // mDefaultMaxBufferCount is the default limit on the number of buffers
    // that will be allocated at one time.  This default limit is set by the
    // that will be allocated at one time.  This default limit is set by the
+2 −1
Original line number Original line Diff line number Diff line
@@ -31,10 +31,11 @@ namespace android {


BufferItemConsumer::BufferItemConsumer(uint32_t consumerUsage,
BufferItemConsumer::BufferItemConsumer(uint32_t consumerUsage,
        int bufferCount, bool synchronousMode) :
        int bufferCount, bool synchronousMode) :
    ConsumerBase(new BufferQueue(true, bufferCount) )
    ConsumerBase(new BufferQueue(true) )
{
{
    mBufferQueue->setConsumerUsageBits(consumerUsage);
    mBufferQueue->setConsumerUsageBits(consumerUsage);
    mBufferQueue->setSynchronousMode(synchronousMode);
    mBufferQueue->setSynchronousMode(synchronousMode);
    mBufferQueue->setMaxAcquiredBufferCount(bufferCount);
}
}


BufferItemConsumer::~BufferItemConsumer() {
BufferItemConsumer::~BufferItemConsumer() {
+29 −14
Original line number Original line Diff line number Diff line
@@ -81,12 +81,12 @@ static const char* scalingModeName(int scalingMode) {
    }
    }
}
}


BufferQueue::BufferQueue(bool allowSynchronousMode, int bufferCount,
BufferQueue::BufferQueue(bool allowSynchronousMode,
        const sp<IGraphicBufferAlloc>& allocator) :
        const sp<IGraphicBufferAlloc>& allocator) :
    mDefaultWidth(1),
    mDefaultWidth(1),
    mDefaultHeight(1),
    mDefaultHeight(1),
    mMinUndequeuedBuffers(bufferCount),
    mMaxAcquiredBufferCount(1),
    mDefaultMaxBufferCount(bufferCount + 1),
    mDefaultMaxBufferCount(2),
    mOverrideMaxBufferCount(0),
    mOverrideMaxBufferCount(0),
    mSynchronousMode(false),
    mSynchronousMode(false),
    mAllowSynchronousMode(allowSynchronousMode),
    mAllowSynchronousMode(allowSynchronousMode),
@@ -233,8 +233,7 @@ int BufferQueue::query(int what, int* outValue)
        value = mDefaultBufferFormat;
        value = mDefaultBufferFormat;
        break;
        break;
    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
        value = mSynchronousMode ?
        value = getMinUndequeuedBufferCountLocked();
                (mMinUndequeuedBuffers-1) : mMinUndequeuedBuffers;
        break;
        break;
    case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
    case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
        value = (mQueue.size() >= 2);
        value = (mQueue.size() >= 2);
@@ -356,17 +355,18 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>& outFence,
            }
            }


            // See whether a buffer has been queued since the last
            // See whether a buffer has been queued since the last
            // setBufferCount so we know whether to perform the
            // setBufferCount so we know whether to perform the min undequeued
            // mMinUndequeuedBuffers check below.
            // buffers check below.
            if (mBufferHasBeenQueued) {
            if (mBufferHasBeenQueued) {
                // make sure the client is not trying to dequeue more buffers
                // make sure the client is not trying to dequeue more buffers
                // than allowed.
                // than allowed.
                const int avail = maxBufferCount - (dequeuedCount+1);
                const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1);
                if (avail < (mMinUndequeuedBuffers-int(mSynchronousMode))) {
                const int minUndequeuedCount = getMinUndequeuedBufferCountLocked();
                    ST_LOGE("dequeueBuffer: mMinUndequeuedBuffers=%d exceeded "
                if (newUndequeuedCount < minUndequeuedCount) {
                            "(dequeued=%d)",
                    ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) "
                            mMinUndequeuedBuffers-int(mSynchronousMode),
                            "exceeded (dequeued=%d undequeudCount=%d)",
                            dequeuedCount);
                            minUndequeuedCount, dequeuedCount,
                            newUndequeuedCount);
                    return -EBUSY;
                    return -EBUSY;
                }
                }
            }
            }
@@ -954,6 +954,16 @@ status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) {
    return setDefaultMaxBufferCountLocked(bufferCount);
    return setDefaultMaxBufferCountLocked(bufferCount);
}
}


status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) {
    ATRACE_CALL();
    Mutex::Autolock lock(mMutex);
    if (mConnectedApi != NO_CONNECTED_API) {
        return INVALID_OPERATION;
    }
    mMaxAcquiredBufferCount = maxAcquiredBuffers;
    return OK;
}

void BufferQueue::freeAllBuffersExceptHeadLocked() {
void BufferQueue::freeAllBuffersExceptHeadLocked() {
    int head = -1;
    int head = -1;
    if (!mQueue.empty()) {
    if (!mQueue.empty()) {
@@ -996,7 +1006,12 @@ status_t BufferQueue::drainQueueAndFreeBuffersLocked() {
}
}


int BufferQueue::getMinMaxBufferCountLocked() const {
int BufferQueue::getMinMaxBufferCountLocked() const {
    return mSynchronousMode ? mMinUndequeuedBuffers : mMinUndequeuedBuffers + 1;
    return getMinUndequeuedBufferCountLocked() + 1;
}

int BufferQueue::getMinUndequeuedBufferCountLocked() const {
    return mSynchronousMode ? mMaxAcquiredBufferCount :
            mMaxAcquiredBufferCount + 1;
}
}


int BufferQueue::getMaxBufferCountLocked() const {
int BufferQueue::getMaxBufferCountLocked() const {
+2 −1
Original line number Original line Diff line number Diff line
@@ -30,7 +30,7 @@
namespace android {
namespace android {


CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
    ConsumerBase(new BufferQueue(true, maxLockedBuffers) ),
    ConsumerBase(new BufferQueue(true) ),
    mMaxLockedBuffers(maxLockedBuffers),
    mMaxLockedBuffers(maxLockedBuffers),
    mCurrentLockedBuffers(0)
    mCurrentLockedBuffers(0)
{
{
@@ -41,6 +41,7 @@ CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :


    mBufferQueue->setSynchronousMode(true);
    mBufferQueue->setSynchronousMode(true);
    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
    mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
    mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
}
}


CpuConsumer::~CpuConsumer() {
CpuConsumer::~CpuConsumer() {
+1 −2
Original line number Original line Diff line number Diff line
@@ -67,8 +67,7 @@ public:
 */
 */


FramebufferSurface::FramebufferSurface():
FramebufferSurface::FramebufferSurface():
    ConsumerBase(new BufferQueue(true, NUM_FRAME_BUFFERS,
    ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
            new GraphicBufferAlloc())),
    fbDev(0),
    fbDev(0),
    mCurrentBufferSlot(-1),
    mCurrentBufferSlot(-1),
    mCurrentBuffer(0)
    mCurrentBuffer(0)