]> git.sesse.net Git - vlc/blobdiff - modules/video_output/android/nativewindowpriv.c
android/surface: fix prototype
[vlc] / modules / video_output / android / nativewindowpriv.c
index 120eb1a04c9a372eeb6962ecd1a7471923f07058..7564216d09a9a81b38e2ea14b7a17c0853528513 100644 (file)
 
 #include <android/native_window.h>
 
-#if ANDROID_API <= 13
+#define ANDROID_HC_OR_LATER (ANDROID_API >= 11)
+#define ANDROID_ICS_OR_LATER (ANDROID_API >= 14)
+#define ANDROID_JBMR2_OR_LATER (ANDROID_API >= 18)
+
+#if ANDROID_JBMR2_OR_LATER
+/* for waiting for fence_fd returned by dequeueBuffer */
+#include <linux/ioctl.h>
+#include <linux/types.h>
+#define SYNC_IOC_MAGIC '>'
+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __s32)
+#endif
+
+#if ANDROID_ICS_OR_LATER
+#include <system/window.h>
+#else
 #include <ui/android_native_buffer.h>
 #include <ui/egl/android_natives.h>
-#else
-#include <system/window.h>
 #endif
 
 #include <hardware/gralloc.h>
@@ -45,7 +57,7 @@
 #define NO_ERROR 0
 typedef int32_t status_t;
 
-#if ANDROID_API <= 13
+#if !ANDROID_ICS_OR_LATER
 typedef android_native_buffer_t ANativeWindowBuffer_t;
 #endif
 typedef struct native_window_priv native_window_priv;
@@ -79,14 +91,14 @@ struct native_window_priv
 
 static int window_connect( ANativeWindow *anw )
 {
-#if ANDROID_API >= 14
+#if ANDROID_ICS_OR_LATER
     return native_window_api_connect( anw, NATIVE_WINDOW_API_MEDIA );
 #endif
 }
 
 static int window_disconnect( ANativeWindow *anw )
 {
-#if ANDROID_API >= 14
+#if ANDROID_ICS_OR_LATER
     return native_window_api_disconnect( anw, NATIVE_WINDOW_API_MEDIA );
 #endif
 }
@@ -139,28 +151,34 @@ int ANativeWindowPriv_setup( native_window_priv *priv, int w, int h, int hal_for
     LOGD( "setup: %p, %d, %d, %X, %X\n",
           priv->anw, w, h, hal_format, hw_usage );
 
-    if (is_hw)
+    if( is_hw )
+    {
         priv->usage = hw_usage | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
-    else
-        priv->usage= GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN;
-#if ANDROID_API >= 11
-    priv->usage |= GRALLOC_USAGE_EXTERNAL_DISP;
+#if ANDROID_HC_OR_LATER
+        priv->usage |= GRALLOC_USAGE_EXTERNAL_DISP;
 #endif
+    }
+    else
+        priv->usage = GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN;
 
     err = native_window_set_usage( priv->anw, priv->usage );
     CHECK_ERR();
 
-#if ANDROID_API <= 13
-    err = native_window_set_buffers_geometry( priv->anw, w, h, hal_format );
-    CHECK_ERR();
-#else
-    err = native_window_set_scaling_mode( priv->anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW );
+#if ANDROID_ICS_OR_LATER
+    err = native_window_set_buffers_format( priv->anw, hal_format );
     CHECK_ERR();
 
+#if ANDROID_JBMR2_OR_LATER
+    err = native_window_set_buffers_user_dimensions( priv->anw, w, h );
+#else
     err = native_window_set_buffers_dimensions( priv->anw, w, h );
+#endif
     CHECK_ERR();
 
-    err = native_window_set_buffers_format( priv->anw, hal_format );
+    err = native_window_set_scaling_mode( priv->anw, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW );
+    CHECK_ERR();
+#else
+    err = native_window_set_buffers_geometry( priv->anw, w, h, hal_format );
     CHECK_ERR();
 #endif
 
@@ -171,7 +189,7 @@ int ANativeWindowPriv_getMinUndequeued( native_window_priv *priv, unsigned int *
 {
     status_t err;
 
-#if ANDROID_API >= 11
+#if ANDROID_HC_OR_LATER
     err = priv->anw->query( priv->anw, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, min_undequeued );
     CHECK_ERR();
 #endif
@@ -186,7 +204,7 @@ int ANativeWindowPriv_getMinUndequeued( native_window_priv *priv, unsigned int *
 
 int ANativeWindowPriv_getMaxBufferCount( native_window_priv *priv, unsigned int *max_buffer_count )
 {
-#if ANDROID_API >= 14
+#if ANDROID_ICS_OR_LATER
     *max_buffer_count = 32;
 #else
     *max_buffer_count = 15;
@@ -217,107 +235,151 @@ int ANativeWindowPriv_setCrop( native_window_priv *priv, int ofs_x, int ofs_y, i
     return native_window_set_crop( priv->anw, &crop );
 }
 
-int ANativeWindowPriv_dequeue( native_window_priv *priv, void **pp_handle )
+static int dequeue_fence( native_window_priv *priv, void **pp_handle,
+                          int *p_fence_fd )
 {
     ANativeWindowBuffer_t *anb;
     status_t err = NO_ERROR;
+    int i_fence_fd = -1;
 
-#if ANDROID_API >= 18
-    err = priv->anw->dequeueBuffer_DEPRECATED( priv->anw, &anb );
+#if ANDROID_JBMR2_OR_LATER
+    err = priv->anw->dequeueBuffer( priv->anw, &anb, &i_fence_fd );
+    CHECK_ERR();
+    if( !p_fence_fd && i_fence_fd != -1 )
+    {
+        __s32 timeout = 5000;
+        if( ioctl( i_fence_fd, SYNC_IOC_WAIT, &timeout ) != 0 )
+        {
+            priv->anw->queueBuffer( priv->anw, anb, i_fence_fd );
+            return -1;
+        }
+        close( i_fence_fd );
+        i_fence_fd = -1;
+    }
 #else
     err = priv->anw->dequeueBuffer( priv->anw, &anb );
-#endif
     CHECK_ERR();
+#endif
 
+    if( p_fence_fd )
+        *p_fence_fd = i_fence_fd;
     *pp_handle = anb;
 
     return 0;
 }
 
+int ANativeWindowPriv_dequeue( native_window_priv *priv, void **pp_handle )
+{
+    return dequeue_fence( priv, pp_handle, NULL );
+}
+
 int ANativeWindowPriv_lock( native_window_priv *priv, void *p_handle )
 {
+#if !ANDROID_JBMR2_OR_LATER
     ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
     status_t err = NO_ERROR;
 
     CHECK_ANB();
 
-#if ANDROID_API >= 18
-    err = priv->anw->lockBuffer_DEPRECATED( priv->anw, anb );
-#else
     err = priv->anw->lockBuffer( priv->anw, anb );
-#endif
     CHECK_ERR();
 
+#endif
     return 0;
 }
 
-int ANativeWindowPriv_lockData( native_window_priv *priv, void *p_handle,
-                                ANativeWindow_Buffer *p_out_anb )
+static int queue_fence( native_window_priv *priv, void *p_handle,
+                        int i_fence_fd )
 {
     ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
     status_t err = NO_ERROR;
-    void *p_data;
 
     CHECK_ANB();
 
-    err = priv->gralloc->lock( priv->gralloc, anb->handle, priv->usage,
-                               0, 0, anb->width, anb->height, &p_data );
+#if ANDROID_JBMR2_OR_LATER
+    err = priv->anw->queueBuffer( priv->anw, anb, i_fence_fd );
+#else
+    err = priv->anw->queueBuffer( priv->anw, anb );
+#endif
     CHECK_ERR();
-    if( p_out_anb ) {
-        p_out_anb->bits = p_data;
-        p_out_anb->width = anb->width;
-        p_out_anb->height = anb->height;
-        p_out_anb->stride = anb->stride;
-        p_out_anb->format = anb->format;
-    }
 
     return 0;
 }
 
-int ANativeWindowPriv_unlockData( native_window_priv *priv, void *p_handle )
+int ANativeWindowPriv_queue( native_window_priv *priv, void *p_handle )
+{
+    return queue_fence( priv, p_handle, -1 );
+}
+
+static int cancel_fence( native_window_priv *priv, void *p_handle,
+                         int i_fence_fd )
 {
     ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
     status_t err = NO_ERROR;
 
     CHECK_ANB();
 
-    err = priv->gralloc->unlock(priv->gralloc, anb->handle);
+#if ANDROID_JBMR2_OR_LATER
+    err = priv->anw->cancelBuffer( priv->anw, anb, i_fence_fd );
+#else
+    err = priv->anw->cancelBuffer( priv->anw, anb );
+#endif
     CHECK_ERR();
 
     return 0;
 }
 
-int ANativeWindowPriv_queue( native_window_priv *priv, void *p_handle )
+int ANativeWindowPriv_cancel( native_window_priv *priv, void *p_handle )
 {
-    ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
+    return cancel_fence( priv, p_handle, -1 );
+}
+
+int ANativeWindowPriv_lockData( native_window_priv *priv, void **pp_handle,
+                                ANativeWindow_Buffer *p_out_anb )
+{
+    ANativeWindowBuffer_t *anb;
     status_t err = NO_ERROR;
+    void *p_data;
 
+    err = dequeue_fence( priv, pp_handle, NULL );
+    CHECK_ERR();
+
+    anb = (ANativeWindowBuffer_t *)*pp_handle;
     CHECK_ANB();
 
-#if ANDROID_API >= 18
-    err = priv->anw->queueBuffer_DEPRECATED( priv->anw, anb );
-#else
-    err = priv->anw->queueBuffer( priv->anw, anb );
-#endif
+    err = ANativeWindowPriv_lock( priv, *pp_handle );
     CHECK_ERR();
 
+    err = priv->gralloc->lock( priv->gralloc, anb->handle, priv->usage,
+                               0, 0, anb->width, anb->height, &p_data );
+    CHECK_ERR();
+    if( p_out_anb ) {
+        p_out_anb->bits = p_data;
+        p_out_anb->width = anb->width;
+        p_out_anb->height = anb->height;
+        p_out_anb->stride = anb->stride;
+        p_out_anb->format = anb->format;
+    }
+
     return 0;
 }
 
-int ANativeWindowPriv_cancel( native_window_priv *priv, void *p_handle )
+int ANativeWindowPriv_unlockData( native_window_priv *priv, void *p_handle,
+                                  bool b_render )
 {
     ANativeWindowBuffer_t *anb = (ANativeWindowBuffer_t *)p_handle;
     status_t err = NO_ERROR;
 
     CHECK_ANB();
 
-#if ANDROID_API >= 18
-    err = priv->anw->cancelBuffer_DEPRECATED( priv->anw, anb );
-#else
-    err = priv->anw->cancelBuffer( priv->anw, anb );
-#endif
+    err = priv->gralloc->unlock( priv->gralloc, anb->handle );
     CHECK_ERR();
 
+    if( b_render )
+        queue_fence( priv, p_handle, -1 );
+    else
+        cancel_fence( priv, p_handle, -1 );
+
     return 0;
 }