#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
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();
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;
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
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;
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
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();
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;
}