egl/android: Fix build for Jelly Bean (v2)
authorChad Versace <chad.versace@linux.intel.com>
Thu, 20 Dec 2012 22:16:50 +0000 (14:16 -0800)
committerChad Versace <chad.versace@linux.intel.com>
Wed, 2 Jan 2013 22:55:36 +0000 (14:55 -0800)
In Jelly Bean, the interface to ANativeWindow changed. The change included
adding a new parameter the queueBuffer and dequeueBuffer methods,
removing the lockBuffer method, and requiring libsync.

v2:
  - s/fence_fd == -1/fence_fd != -1/
  - Fix leak. Close the fence_fd.

Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
src/egl/drivers/dri2/platform_android.c
src/egl/main/Android.mk

index 15bf0548b5cd338c34f592549bcf745cf1c4d53f..7ede48de69c5149dcec83f391277d949a14e015e 100644 (file)
 #include <errno.h>
 #include <dlfcn.h>
 
+#if ANDROID_VERSION >= 0x402
+#include <sync/sync.h>
+#endif
+
 /* for droid_get_pci_id */
 #include <xf86drm.h>
 #include <i915_drm.h>
@@ -79,11 +83,48 @@ get_native_buffer_name(struct ANativeWindowBuffer *buf)
 static EGLBoolean
 droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
 {
+#if ANDROID_VERSION >= 0x0402
+   int fence_fd;
+
+   if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer,
+                                        &fence_fd))
+      return EGL_FALSE;
+
+   /* If access to the buffer is controlled by a sync fence, then block on the
+    * fence.
+    *
+    * It may be more performant to postpone blocking until there is an
+    * immediate need to write to the buffer. But doing so would require adding
+    * hooks to the DRI2 loader.
+    *
+    * From the ANativeWindow::dequeueBuffer documentation:
+    *
+    *    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.
+    */
+    if (fence_fd >= 0) {
+       /* From the SYNC_IOC_WAIT documentation in <linux/sync.h>:
+        *
+        *    Waits indefinitely if timeout < 0.
+        */
+        int timeout = -1;
+        sync_wait(fence_fd, timeout);
+        close(fence_fd);
+   }
+
+   dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common);
+#else
    if (dri2_surf->window->dequeueBuffer(dri2_surf->window, &dri2_surf->buffer))
       return EGL_FALSE;
 
    dri2_surf->buffer->common.incRef(&dri2_surf->buffer->common);
    dri2_surf->window->lockBuffer(dri2_surf->window, dri2_surf->buffer);
+#endif
 
    return EGL_TRUE;
 }
@@ -91,7 +132,25 @@ droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
 static EGLBoolean
 droid_window_enqueue_buffer(struct dri2_egl_surface *dri2_surf)
 {
+#if ANDROID_VERSION >= 0x0402
+   /* Queue the buffer without a sync fence. This informs the ANativeWindow
+    * that it may access the buffer immediately.
+    *
+    * From ANativeWindow::dequeueBuffer:
+    *
+    *    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.
+    */
+   int fence_fd = -1;
+   dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer,
+                                  fence_fd);
+#else
    dri2_surf->window->queueBuffer(dri2_surf->window, dri2_surf->buffer);
+#endif
 
    dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common);
    dri2_surf->buffer = NULL;
index a4a00f3bb351d200f02b6da5280dfe92316c5f74..97e4860211a77f72a680dd263237862ca39ef660 100644 (file)
@@ -79,7 +79,12 @@ LOCAL_STATIC_LIBRARIES += libmesa_egl_dri2
 # require i915_dri and/or i965_dri
 LOCAL_REQUIRED_MODULES += \
        $(addsuffix _dri, $(filter i915 i965, $(MESA_GPU_DRIVERS)))
+
+ifeq ($(shell echo "$(MESA_ANDROID_VERSION) >= 4.2" | bc),1)
+    LOCAL_SHARED_LIBRARIES += \
+        libsync
 endif
+endif # MESA_BUILD_CLASSIC
 
 ifeq ($(strip $(MESA_BUILD_GALLIUM)),true)