From 1ea233c6f30a74e6ff5456c3521328237b01eed8 Mon Sep 17 00:00:00 2001 From: Haixia Shi Date: Thu, 2 Jun 2016 12:48:23 -0700 Subject: [PATCH] platform_android: prevent deadlock in droid_swap_buffers To avoid blocking other EGL calls, release the display mutex before we enqueue buffer to android frameworks and re-acquire the mutex upon return. v2: moved lock/unlock inside droid_window_enqueue_buffer(). TEST=verify pinch zoom in Photos app no longer causes hangs Signed-off-by: Haixia Shi Reviewed-by: Emil Velikov --- src/egl/drivers/dri2/platform_android.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c index 70bbdff33ae..b1d7272092c 100644 --- a/src/egl/drivers/dri2/platform_android.c +++ b/src/egl/drivers/dri2/platform_android.c @@ -160,8 +160,14 @@ droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) } static EGLBoolean -droid_window_enqueue_buffer(struct dri2_egl_surface *dri2_surf) +droid_window_enqueue_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf) { + /* To avoid blocking other EGL calls, release the display mutex before + * we enter droid_window_enqueue_buffer() and re-acquire the mutex upon + * return. + */ + mtx_unlock(&disp->Mutex); + #if ANDROID_VERSION >= 0x0402 /* Queue the buffer without a sync fence. This informs the ANativeWindow * that it may access the buffer immediately. @@ -185,14 +191,15 @@ droid_window_enqueue_buffer(struct dri2_egl_surface *dri2_surf) dri2_surf->buffer->common.decRef(&dri2_surf->buffer->common); dri2_surf->buffer = NULL; + mtx_lock(&disp->Mutex); return EGL_TRUE; } static void -droid_window_cancel_buffer(struct dri2_egl_surface *dri2_surf) +droid_window_cancel_buffer(_EGLDisplay *disp, struct dri2_egl_surface *dri2_surf) { /* no cancel buffer? */ - droid_window_enqueue_buffer(dri2_surf); + droid_window_enqueue_buffer(disp, dri2_surf); } static __DRIbuffer * @@ -325,7 +332,7 @@ droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (dri2_surf->buffer) - droid_window_cancel_buffer(dri2_surf); + droid_window_cancel_buffer(disp, dri2_surf); dri2_surf->window->common.decRef(&dri2_surf->window->common); } @@ -435,7 +442,7 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) dri2_flush_drawable_for_swapbuffers(disp, draw); if (dri2_surf->buffer) - droid_window_enqueue_buffer(dri2_surf); + droid_window_enqueue_buffer(disp, dri2_surf); (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); -- 2.30.2