fix [2835280] Add support for cancelling buffers to ANativeWindow
There is a new ANativeWindow::cancelBuffer() API that can be used to
cancel any dequeued buffer, BEFORE it's been enqueued. The buffer is
returned to the list of availlable buffers. dequeue and cancel are not
mutually thread safe, they must be called from the same thread or
external synchronization must be used.
Change-Id: I86cc7985bace8b6a93ad2c75d2bef5c3c2cb4d61
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 560ea67..d44aab9 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -409,6 +409,7 @@
{
ANativeWindow::setSwapInterval = setSwapInterval;
ANativeWindow::dequeueBuffer = dequeueBuffer;
+ ANativeWindow::cancelBuffer = cancelBuffer;
ANativeWindow::lockBuffer = lockBuffer;
ANativeWindow::queueBuffer = queueBuffer;
ANativeWindow::query = query;
@@ -517,6 +518,12 @@
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 @@
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();