Loading include/private/surfaceflinger/SharedBufferStack.h +6 −4 Original line number Diff line number Diff line Loading @@ -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 }; Loading Loading @@ -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); Loading Loading @@ -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()(); }; Loading @@ -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]; Loading include/surfaceflinger/Surface.h +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading include/ui/egl/android_natives.h +11 −1 Original line number Diff line number Diff line Loading @@ -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. Loading libs/surfaceflinger_client/SharedBufferStack.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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", Loading @@ -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; } Loading libs/surfaceflinger_client/Surface.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading Loading
include/private/surfaceflinger/SharedBufferStack.h +6 −4 Original line number Diff line number Diff line Loading @@ -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 }; Loading Loading @@ -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); Loading Loading @@ -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()(); }; Loading @@ -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]; Loading
include/surfaceflinger/Surface.h +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading @@ -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); Loading
include/ui/egl/android_natives.h +11 −1 Original line number Diff line number Diff line Loading @@ -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. Loading
libs/surfaceflinger_client/SharedBufferStack.cpp +19 −11 Original line number Diff line number Diff line Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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); Loading @@ -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(); Loading Loading @@ -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", Loading @@ -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; } Loading
libs/surfaceflinger_client/Surface.cpp +34 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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(); Loading