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

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

Merge "libgui: Add dequeue/attach timeout"

parents 635ca317 127fc63e
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -174,7 +174,10 @@ public:
    virtual uint64_t getNextFrameNumber() const override;

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

    // See IGraphicBufferProducer::setDequeueTimeout
    virtual status_t setDequeueTimeout(nsecs_t timeout) override;

private:
    // This is required by the IBinder::DeathRecipient interface
@@ -216,6 +219,10 @@ private:
    int mCurrentCallbackTicket; // Protected by mCallbackMutex
    Condition mCallbackCondition;

    // Sets how long dequeueBuffer or attachBuffer will block if a buffer or
    // slot is not yet available.
    nsecs_t mDequeueTimeout;

}; // class BufferQueueProducer

} // namespace android
+17 −0
Original line number Diff line number Diff line
@@ -177,6 +177,8 @@ public:
    // * WOULD_BLOCK - no buffer is currently available, and blocking is disabled
    //                 since both the producer/consumer are controlled by app
    // * NO_MEMORY - out of memory, cannot allocate the graphics buffer.
    // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while
    //               waiting for a buffer to become available.
    //
    // All other negative values are an unknown error returned downstream
    // from the graphics allocator (typically errno).
@@ -248,6 +250,8 @@ public:
    // * WOULD_BLOCK - no buffer slot is currently available, and blocking is
    //                 disabled since both the producer/consumer are
    //                 controlled by the app.
    // * TIMED_OUT - the timeout set by setDequeueTimeout was exceeded while
    //               waiting for a slot to become available.
    virtual status_t attachBuffer(int* outSlot,
            const sp<GraphicBuffer>& buffer) = 0;

@@ -518,6 +522,19 @@ public:
    // 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;

    // Sets how long dequeueBuffer will wait for a buffer to become available
    // before returning an error (TIMED_OUT).
    //
    // This timeout also affects the attachBuffer call, which will block if
    // there is not a free slot available into which the attached buffer can be
    // placed.
    //
    // By default, the BufferQueue will wait forever, which is indicated by a
    // timeout of -1. If set (to a value other than -1), this will disable
    // non-blocking mode and its corresponding spare buffer (which is used to
    // ensure a buffer is always available).
    virtual status_t setDequeueTimeout(nsecs_t timeout) = 0;
};

// ----------------------------------------------------------------------------
+3 −0
Original line number Diff line number Diff line
@@ -117,6 +117,9 @@ public:
     * in <system/window.h>. */
    int setScalingMode(int mode);

    // See IGraphicBufferProducer::setDequeueTimeout
    status_t setDequeueTimeout(nsecs_t timeout);

protected:
    virtual ~Surface();

+25 −4
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) :
    mCallbackMutex(),
    mNextCallbackTicket(0),
    mCurrentCallbackTicket(0),
    mCallbackCondition() {}
    mCallbackCondition(),
    mDequeueTimeout(-1) {}

BufferQueueProducer::~BufferQueueProducer() {}

@@ -271,8 +272,16 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
                    (acquiredCount <= mCore->mMaxAcquiredBufferCount)) {
                return WOULD_BLOCK;
            }
            if (mDequeueTimeout >= 0) {
                status_t result = mCore->mDequeueCondition.waitRelative(
                        mCore->mMutex, mDequeueTimeout);
                if (result == TIMED_OUT) {
                    return result;
                }
            } else {
                mCore->mDequeueCondition.wait(mCore->mMutex);
            }
        }
    } // while (tryAgain)

    return NO_ERROR;
@@ -1012,8 +1021,11 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
    }

    mCore->mBufferHasBeenQueued = false;
    mCore->mDequeueBufferCannotBlock =  mCore->mConsumerControlledByApp &&
            producerControlledByApp;
    mCore->mDequeueBufferCannotBlock = false;
    if (mDequeueTimeout < 0) {
        mCore->mDequeueBufferCannotBlock =
                mCore->mConsumerControlledByApp && producerControlledByApp;
    }
    mCore->mAllowAllocation = true;

    return status;
@@ -1247,7 +1259,16 @@ status_t BufferQueueProducer::setSingleBufferMode(bool singleBufferMode) {
        mCore->mSingleBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT;
    }
    mCore->mSingleBufferMode = singleBufferMode;
    return NO_ERROR;
}

status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) {
    ATRACE_CALL();
    BQ_LOGV("setDequeueTimeout: %" PRId64, timeout);

    Mutex::Autolock lock(mCore->mMutex);
    mDequeueTimeout = timeout;
    mCore->mDequeueBufferCannotBlock = false;
    return NO_ERROR;
}

+21 −1
Original line number Diff line number Diff line
@@ -51,7 +51,8 @@ enum {
    SET_MAX_DEQUEUED_BUFFER_COUNT,
    SET_ASYNC_MODE,
    GET_NEXT_FRAME_NUMBER,
    SET_SINGLE_BUFFER_MODE
    SET_SINGLE_BUFFER_MODE,
    SET_DEQUEUE_TIMEOUT,
};

class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -353,6 +354,18 @@ public:
        }
        return result;
    }

    virtual status_t setDequeueTimeout(nsecs_t timeout) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt64(timeout);
        status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("setDequeueTimeout failed to transact: %d", result);
            return result;
        }
        return reply.readInt32();
    }
};

// Out-of-line virtual method definition to trigger vtable emission in this
@@ -548,6 +561,13 @@ status_t BnGraphicBufferProducer::onTransact(
            reply->writeInt32(result);
            return NO_ERROR;
        }
        case SET_DEQUEUE_TIMEOUT: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            nsecs_t timeout = data.readInt64();
            status_t result = setDequeueTimeout(timeout);
            reply->writeInt32(result);
            return NO_ERROR;
        }
    }
    return BBinder::onTransact(code, data, reply, flags);
}
Loading