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

Commit 46b489f3 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "fix [2835280] Add support for cancelling buffers to ANativeWindow" into gingerbread

parents 566b728c 19957553
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -114,8 +114,9 @@ public:

    int32_t     identity;       // surface's identity (const)
    int32_t     token;          // surface's token (for debugging)
    int32_t     reserved32[1];
    Statistics  stats;
    int8_t      headBuf;        // last retired buffer
    uint8_t     reservedBytes[3];
    int32_t     reserved;
    BufferData  buffers[NUM_BUFFER_MAX];     // 1024 bytes
};
@@ -201,6 +202,7 @@ public:
    status_t undoDequeue(int buf);
    
    status_t lock(int buf);
    status_t cancel(int buf);
    status_t queue(int buf);
    bool needNewBuffer(int buffer) const;
    status_t setDirtyRegion(int buffer, const Region& reg);
@@ -230,8 +232,9 @@ private:
        inline ssize_t operator()();
    };

    struct UndoDequeueUpdate : public UpdateBase {
        inline UndoDequeueUpdate(SharedBufferBase* sbb);
    struct CancelUpdate : public UpdateBase {
        int tail, buf;
        inline CancelUpdate(SharedBufferBase* sbb, int tail, int buf);
        inline ssize_t operator()();
    };

@@ -256,7 +259,6 @@ private:
    int mNumBuffers;

    int32_t tail;
    int32_t undoDequeueTail;
    int32_t queued_head;
    // statistics...
    nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
+2 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@ private:
     */
    static int setSwapInterval(ANativeWindow* window, int interval);
    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
    static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
    static int query(ANativeWindow* window, int what, int* value);
@@ -207,6 +208,7 @@ private:
    int dequeueBuffer(android_native_buffer_t** buffer);
    int lockBuffer(android_native_buffer_t* buffer);
    int queueBuffer(android_native_buffer_t* buffer);
    int cancelBuffer(android_native_buffer_t* buffer);
    int query(int what, int* value);
    int perform(int operation, va_list args);

+11 −1
Original line number Diff line number Diff line
@@ -218,7 +218,17 @@ struct ANativeWindow
    int     (*perform)(struct ANativeWindow* window,
                int operation, ... );
    
    void* reserved_proc[3];
    /*
     * hook used to cancel a buffer that has been dequeued.
     * No synchronization is performed between dequeue() and cancel(), so
     * either external synchronization is needed, or these functions must be
     * called from the same thread.
     */
    int     (*cancelBuffer)(struct ANativeWindow* window,
                struct android_native_buffer_t* buffer);


    void* reserved_proc[2];
};

// Backwards compatibility...  please switch to ANativeWindow.
+19 −11
Original line number Diff line number Diff line
@@ -285,10 +285,12 @@ ssize_t SharedBufferClient::DequeueUpdate::operator()() {
    return NO_ERROR;
}

SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb)
    : UpdateBase(sbb) {    
SharedBufferClient::CancelUpdate::CancelUpdate(SharedBufferBase* sbb,
        int tail, int buf)
    : UpdateBase(sbb), tail(tail), buf(buf) {
}
ssize_t SharedBufferClient::UndoDequeueUpdate::operator()() {
ssize_t SharedBufferClient::CancelUpdate::operator()() {
    stack.index[tail] = buf;
    android_atomic_inc(&stack.available);
    return NO_ERROR;
}
@@ -319,7 +321,7 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() {
        return BAD_VALUE;

    // Preventively lock the current buffer before updating queued.
    android_atomic_write(stack.index[head], &stack.inUse);
    android_atomic_write(stack.headBuf, &stack.inUse);

    // Decrement the number of queued buffers 
    int32_t queued;
@@ -334,7 +336,9 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() {
    // the buffer we preventively locked upon entering this function

    head = (head + 1) % numBuffers;
    android_atomic_write(stack.index[head], &stack.inUse);
    const int8_t headBuf = stack.index[head];
    stack.headBuf = headBuf;
    android_atomic_write(headBuf, &stack.inUse);

    // head is only modified here, so we don't need to use cmpxchg
    android_atomic_write(head, &stack.head);
@@ -359,7 +363,7 @@ ssize_t SharedBufferServer::StatusUpdate::operator()() {
SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
        int surface, int num, int32_t identity)
    : SharedBufferBase(sharedClient, surface, identity),
      mNumBuffers(num), tail(0), undoDequeueTail(0)
      mNumBuffers(num), tail(0)
{
    SharedBufferStack& stack( *mSharedStack );
    tail = computeTail();
@@ -395,7 +399,6 @@ ssize_t SharedBufferClient::dequeue()
    DequeueUpdate update(this);
    updateCondition( update );

    undoDequeueTail = tail;
    int dequeued = stack.index[tail];
    tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail++=%d, %s",
@@ -407,15 +410,20 @@ ssize_t SharedBufferClient::dequeue()
}

status_t SharedBufferClient::undoDequeue(int buf)
{
    return cancel(buf);
}

status_t SharedBufferClient::cancel(int buf)
{
    RWLock::AutoRLock _rd(mLock);

    // TODO: we can only undo the previous dequeue, we should
    // enforce that in the api
    UndoDequeueUpdate update(this);
    // calculate the new position of the tail index (essentially tail--)
    int localTail = (tail + mNumBuffers - 1) % mNumBuffers;
    CancelUpdate update(this, localTail, buf);
    status_t err = updateCondition( update );
    if (err == NO_ERROR) {
        tail = undoDequeueTail;
        tail = localTail;
    }
    return err;
}
+34 −0
Original line number Diff line number Diff line
@@ -409,6 +409,7 @@ void Surface::init()
{
    ANativeWindow::setSwapInterval  = setSwapInterval;
    ANativeWindow::dequeueBuffer    = dequeueBuffer;
    ANativeWindow::cancelBuffer     = cancelBuffer;
    ANativeWindow::lockBuffer       = lockBuffer;
    ANativeWindow::queueBuffer      = queueBuffer;
    ANativeWindow::query            = query;
@@ -517,6 +518,12 @@ int Surface::dequeueBuffer(ANativeWindow* window,
    return self->dequeueBuffer(buffer);
}

int Surface::cancelBuffer(ANativeWindow* window,
        android_native_buffer_t* buffer) {
    Surface* self = getSelf(window);
    return self->cancelBuffer(buffer);
}

int Surface::lockBuffer(ANativeWindow* window, 
        android_native_buffer_t* buffer) {
    Surface* self = getSelf(window);
@@ -617,6 +624,33 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer)
    return err;
}

int Surface::cancelBuffer(android_native_buffer_t* buffer)
{
    status_t err = validate();
    switch (err) {
    case NO_ERROR:
        // no error, common case
        break;
    case INVALID_OPERATION:
        // legitimate errors here
        return err;
    default:
        // other errors happen because the surface is now invalid,
        // for instance because it has been destroyed. In this case,
        // we just fail silently (canceling a buffer is not technically
        // an error at this point)
        return NO_ERROR;
    }

    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));

    err = mSharedBufferClient->cancel(bufIdx);

    LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
    return err;
}


int Surface::lockBuffer(android_native_buffer_t* buffer)
{
    status_t err = validate();