]> git.sesse.net Git - vlc/blobdiff - modules/video_output/android/nativewindowpriv.c
android/surface: fix prototype
[vlc] / modules / video_output / android / nativewindowpriv.c
index e5f88123e6fce4e78543d44d11eeba25dd29eb53..7564216d09a9a81b38e2ea14b7a17c0853528513 100644 (file)
 #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
@@ -143,13 +151,15 @@ 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_HC_OR_LATER
-    priv->usage |= GRALLOC_USAGE_EXTERNAL_DISP;
+        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();
@@ -225,41 +235,61 @@ 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_JBMR2_OR_LATER
-    err = priv->anw->dequeueBuffer_DEPRECATED( priv->anw, &anb );
+    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_JBMR2_OR_LATER
-    err = priv->anw->lockBuffer_DEPRECATED( priv->anw, anb );
-#else
     err = priv->anw->lockBuffer( priv->anw, anb );
-#endif
     CHECK_ERR();
 
+#endif
     return 0;
 }
 
-int ANativeWindowPriv_queue( native_window_priv *priv, void *p_handle )
+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;
@@ -267,7 +297,7 @@ int ANativeWindowPriv_queue( native_window_priv *priv, void *p_handle )
     CHECK_ANB();
 
 #if ANDROID_JBMR2_OR_LATER
-    err = priv->anw->queueBuffer_DEPRECATED( priv->anw, anb );
+    err = priv->anw->queueBuffer( priv->anw, anb, i_fence_fd );
 #else
     err = priv->anw->queueBuffer( priv->anw, anb );
 #endif
@@ -276,7 +306,13 @@ int ANativeWindowPriv_queue( native_window_priv *priv, void *p_handle )
     return 0;
 }
 
-int ANativeWindowPriv_cancel( 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;
@@ -284,7 +320,7 @@ int ANativeWindowPriv_cancel( native_window_priv *priv, void *p_handle )
     CHECK_ANB();
 
 #if ANDROID_JBMR2_OR_LATER
-    err = priv->anw->cancelBuffer_DEPRECATED( priv->anw, anb );
+    err = priv->anw->cancelBuffer( priv->anw, anb, i_fence_fd );
 #else
     err = priv->anw->cancelBuffer( priv->anw, anb );
 #endif
@@ -293,15 +329,27 @@ int ANativeWindowPriv_cancel( native_window_priv *priv, void *p_handle )
     return 0;
 }
 
-int ANativeWindowPriv_lockData( native_window_priv *priv, void *p_handle,
+int ANativeWindowPriv_cancel( native_window_priv *priv, void *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 = (ANativeWindowBuffer_t *)p_handle;
+    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();
 
+    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();
@@ -316,16 +364,22 @@ int ANativeWindowPriv_lockData( native_window_priv *priv, void *p_handle,
     return 0;
 }
 
-int ANativeWindowPriv_unlockData( 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();
 
-    err = priv->gralloc->unlock(priv->gralloc, anb->handle);
+    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;
 }