From d677120caed103414672efbb59927726dbd87f91 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Thu, 8 Jul 2021 19:39:58 +0000 Subject: [PATCH] egl/android: only apply front rendering usage in shared buffer mode When EGL_KHR_mutable_render_buffer extension is enabled, advertised configs unconditionally include EGL_MUTABLE_RENDER_BUFFER_BIT_KHR bit. However, f61337b5 starts requesting front rendering usage bit when EGL_MUTABLE_RENDER_BUFFER_BIT_KHR is seen on the SurfaceType, which essentially forces linear usage on all winsys BOs for gallium dri and i965 drivers on Android when cros gralloc is in use. This patch dynamically appends or strips the front rendering usage bit depends on whether EGL_RENDER_BUFFER is EGL_SINGLE_BUFFER or EGL_BACK_BUFFER. The next dequeuBuffer call will switch the buffer sharing mode while re-allocating winsys BOs given the updated gralloc usage bits if necessary. v2: handle ANativeWindow_setUsage on error Fixes: f61337b5 ("egl/android: check front rendering support for cros gralloc") Signed-off-by: Yiwei Zhang Reviewed-by: Rob Clark (v1) Part-of: --- src/egl/drivers/dri2/egl_dri2.h | 1 + src/egl/drivers/dri2/platform_android.c | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index af060d16d3f..6a7eedea112 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -346,6 +346,7 @@ struct dri2_egl_surface struct ANativeWindowBuffer *buffer; int age; } *color_buffers, *back; + uint32_t gralloc_usage; #endif /* surfaceless and device */ diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c index d211fd5aa40..d6f5d263a8d 100644 --- a/src/egl/drivers/dri2/platform_android.c +++ b/src/egl/drivers/dri2/platform_android.c @@ -549,6 +549,7 @@ static bool droid_set_shared_buffer_mode(_EGLDisplay *disp, _EGLSurface *surf, bool mode) { #if ANDROID_API_LEVEL >= 24 + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf); struct ANativeWindow *window = dri2_surf->window; @@ -563,6 +564,18 @@ droid_set_shared_buffer_mode(_EGLDisplay *disp, _EGLSurface *surf, bool mode) return false; } + if (mode) + dri2_surf->gralloc_usage |= dri2_dpy->front_rendering_usage; + else + dri2_surf->gralloc_usage &= ~dri2_dpy->front_rendering_usage; + + if (ANativeWindow_setUsage(window, dri2_surf->gralloc_usage)) { + _eglLog(_EGL_WARNING, + "failed ANativeWindow_setUsage(window=%p, usage=%u)", window, + dri2_surf->gralloc_usage); + return false; + } + return true; #else _eglLog(_EGL_FATAL, "%s:%d: internal error: unreachable", __FILE__, __LINE__); @@ -632,14 +645,18 @@ droid_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf, ANativeWindow_query(window, ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT, &dri2_surf->base.Height); - uint32_t usage = strcmp(dri2_dpy->driver_name, "kms_swrast") == 0 + dri2_surf->gralloc_usage = + strcmp(dri2_dpy->driver_name, "kms_swrast") == 0 ? GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN : GRALLOC_USAGE_HW_RENDER; - if (conf->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) - usage |= dri2_dpy->front_rendering_usage; + if (dri2_surf->base.ActiveRenderBuffer == EGL_SINGLE_BUFFER) + dri2_surf->gralloc_usage |= dri2_dpy->front_rendering_usage; - ANativeWindow_setUsage(window, usage); + if (ANativeWindow_setUsage(window, dri2_surf->gralloc_usage)) { + _eglError(EGL_BAD_NATIVE_WINDOW, "droid_create_surface"); + goto cleanup_surface; + } } config = dri2_get_dri_config(dri2_conf, type,