ANativeWindow: update queue/dequeue/cancel w/ sync

This change deprecates the existing queueBuffer, dequeueBuffer, lockBuffer, and
cancelBuffer functions, and replaces them with a queueBuffer, dequeueBuffer,
and cancelBuffer function that accepts or returns a libsync fence file
descriptor.  It also adds the native_window_dequeue_buffer_and_wait convenience
function.

Change-Id: Ifaac91164d014993d7d1d96e0303e04e429f4d00
diff --git a/include/system/window.h b/include/system/window.h
index 8e00bcd..685e068 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -17,11 +17,14 @@
 #ifndef SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H
 #define SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H
 
+#include <cutils/native_handle.h>
+#include <limits.h>
 #include <stdint.h>
 #include <string.h>
+#include <sync/sync.h>
 #include <sys/cdefs.h>
 #include <system/graphics.h>
-#include <cutils/native_handle.h>
+#include <unistd.h>
 
 __BEGIN_DECLS
 
@@ -38,6 +41,14 @@
 
 // ---------------------------------------------------------------------------
 
+// This #define may be used to conditionally compile device-specific code to
+// support either the prior ANativeWindow interface, which did not pass libsync
+// fences around, or the new interface that does.  This #define is only present
+// when the ANativeWindow interface does include libsync support.
+#define ANDROID_NATIVE_WINDOW_HAS_SYNC 1
+
+// ---------------------------------------------------------------------------
+
 typedef const native_handle_t* buffer_handle_t;
 
 // ---------------------------------------------------------------------------
@@ -379,8 +390,12 @@
      * allowed if a specific buffer count has been set.
      *
      * Returns 0 on success or -errno on error.
+     *
+     * XXX: This function is deprecated.  It will continue to work for some
+     * time for binary compatibility, but the new dequeueBuffer function that
+     * outputs a fence file descriptor should be used in its place.
      */
-    int     (*dequeueBuffer)(struct ANativeWindow* window,
+    int     (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,
                 struct ANativeWindowBuffer** buffer);
 
     /*
@@ -389,9 +404,14 @@
      * dequeueBuffer first.
      *
      * Returns 0 on success or -errno on error.
+     *
+     * XXX: This function is deprecated.  It will continue to work for some
+     * time for binary compatibility, but it is essentially a no-op, and calls
+     * to it should be removed.
      */
-    int     (*lockBuffer)(struct ANativeWindow* window,
+    int     (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,
                 struct ANativeWindowBuffer* buffer);
+
     /*
      * Hook called by EGL when modifications to the render buffer are done.
      * This unlocks and post the buffer.
@@ -405,8 +425,13 @@
      * Buffers MUST be queued in the same order than they were dequeued.
      *
      * Returns 0 on success or -errno on error.
+     *
+     * XXX: This function is deprecated.  It will continue to work for some
+     * time for binary compatibility, but the new queueBuffer function that
+     * takes a fence file descriptor should be used in its place (pass a value
+     * of -1 for the fence file descriptor if there is no valid one to pass).
      */
-    int     (*queueBuffer)(struct ANativeWindow* window,
+    int     (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,
                 struct ANativeWindowBuffer* buffer);
 
     /*
@@ -463,12 +488,86 @@
      * reference if they might use the buffer after queueing or canceling it.
      * Holding a reference to a buffer after queueing or canceling it is only
      * allowed if a specific buffer count has been set.
+     *
+     * XXX: This function is deprecated.  It will continue to work for some
+     * time for binary compatibility, but the new cancelBuffer function that
+     * takes a fence file descriptor should be used in its place (pass a value
+     * of -1 for the fence file descriptor if there is no valid one to pass).
      */
-    int     (*cancelBuffer)(struct ANativeWindow* window,
+    int     (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,
                 struct ANativeWindowBuffer* buffer);
 
+    /*
+     * Hook called by EGL to acquire a buffer. This call may block if no
+     * buffers are available.
+     *
+     * The window holds a reference to the buffer between dequeueBuffer and
+     * either queueBuffer or cancelBuffer, so clients only need their own
+     * reference if they might use the buffer after queueing or canceling it.
+     * Holding a reference to a buffer after queueing or canceling it is only
+     * allowed if a specific buffer count has been set.
+     *
+     * The libsync fence file descriptor returned in the int pointed to by the
+     * fenceFd argument will refer to the fence that must signal before the
+     * dequeued buffer may be written to.  A value of -1 indicates that the
+     * caller may access the buffer immediately without waiting on a fence.  If
+     * a valid file descriptor is returned (i.e. any value except -1) then the
+     * caller is responsible for closing the file descriptor.
+     *
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*dequeueBuffer)(struct ANativeWindow* window,
+                struct ANativeWindowBuffer** buffer, int* fenceFd);
 
-    void* reserved_proc[2];
+    /*
+     * Hook called by EGL when modifications to the render buffer are done.
+     * This unlocks and post the buffer.
+     *
+     * The window holds a reference to the buffer between dequeueBuffer and
+     * either queueBuffer or cancelBuffer, so clients only need their own
+     * reference if they might use the buffer after queueing or canceling it.
+     * Holding a reference to a buffer after queueing or canceling it is only
+     * allowed if a specific buffer count has been set.
+     *
+     * The fenceFd argument specifies a libsync fence file descriptor for a
+     * fence that must signal before the buffer can be accessed.  If the buffer
+     * can be accessed immediately then a value of -1 should be used.  The
+     * caller must not use the file descriptor after it is passed to
+     * queueBuffer, and the ANativeWindow implementation is responsible for
+     * closing it.
+     *
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*queueBuffer)(struct ANativeWindow* window,
+                struct ANativeWindowBuffer* buffer, int fenceFd);
+
+    /*
+     * 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.
+     *
+     * The window holds a reference to the buffer between dequeueBuffer and
+     * either queueBuffer or cancelBuffer, so clients only need their own
+     * reference if they might use the buffer after queueing or canceling it.
+     * Holding a reference to a buffer after queueing or canceling it is only
+     * allowed if a specific buffer count has been set.
+     *
+     * The fenceFd argument specifies a libsync fence file decsriptor for a
+     * fence that must signal before the buffer can be accessed.  If the buffer
+     * can be accessed immediately then a value of -1 should be used.
+     *
+     * Note that if the client has not waited on the fence that was returned
+     * from dequeueBuffer, that same fence should be passed to cancelBuffer to
+     * ensure that future uses of the buffer are preceded by a wait on that
+     * fence.  The caller must not use the file descriptor after it is passed
+     * to cancelBuffer, and the ANativeWindow implementation is responsible for
+     * closing it.
+     *
+     * Returns 0 on success or -errno on error.
+     */
+    int     (*cancelBuffer)(struct ANativeWindow* window,
+                struct ANativeWindowBuffer* buffer, int fenceFd);
 };
 
  /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C).
@@ -551,7 +650,7 @@
 /*
  * native_window_set_active_rect(..., active_rect)
  *
- * This function is deprectated and will be removed soon.  For now it simply
+ * This function is deprecated and will be removed soon.  For now it simply
  * sets the post-transform crop for compatibility while multi-project commits
  * get checked.
  */
@@ -717,6 +816,28 @@
     return window->perform(window, NATIVE_WINDOW_API_DISCONNECT, api);
 }
 
+/*
+ * native_window_dequeue_buffer_and_wait(...)
+ * Dequeue a buffer and wait on the fence associated with that buffer.  The
+ * buffer may safely be accessed immediately upon this function returning.  An
+ * error is returned if either of the dequeue or the wait operations fail.
+ */
+static inline int native_window_dequeue_buffer_and_wait(ANativeWindow *anw,
+        struct ANativeWindowBuffer** anb) {
+    int fenceFd = -1;
+    int err = anw->dequeueBuffer(anw, anb, &fenceFd);
+    if (err == 0 && fenceFd != -1) {
+        err = sync_wait(fenceFd, UINT_MAX);
+        if (err == 0) {
+            close(fenceFd);
+        } else {
+            anw->cancelBuffer(anw, *anb, fenceFd);
+            *anb = NULL;
+        }
+    }
+    return err;
+}
+
 
 __END_DECLS