From f88b9eb9c5f5d18bec2419471b1dedfb6136bc43 Mon Sep 17 00:00:00 2001 From: "Kristian H. Kristensen" Date: Mon, 10 Aug 2020 19:05:05 -0700 Subject: [PATCH] egl/android: Add support for CrOS buffer info perform op This uses a new gralloc perform op that returns the buffer info we need. No need to guess at formats, hard code offsets and recalculate strides. This also gives us the format modifier as well as aux planes for compressed RGBA buffers. Part-of: --- src/egl/drivers/dri2/platform_android.c | 69 ++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c index 9621b1b9c1a..9d3598726d4 100644 --- a/src/egl/drivers/dri2/platform_android.c +++ b/src/egl/drivers/dri2/platform_android.c @@ -331,6 +331,71 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp, NULL); } +/* More recent CrOS gralloc has a perform op that fills out the struct below + * with canonical information about the buffer and its modifier, planes, + * offsets and strides. If we have this, we can skip straight to + * createImageFromDmaBufs2() and avoid all the guessing and recalculations. + * This also gives us the modifier and plane offsets/strides for multiplanar + * compressed buffers (eg Intel CCS buffers) in order to make that work in Android. + */ + +static const char cros_gralloc_module_name[] = "CrOS Gralloc"; + +#define CROS_GRALLOC_DRM_GET_BUFFER_INFO 4 + +struct cros_gralloc0_buffer_info { + uint32_t drm_fourcc; + int num_fds; + int fds[4]; + uint64_t modifier; + int offset[4]; + int stride[4]; +}; + +static __DRIimage * +droid_create_image_from_cros_info(_EGLDisplay *disp, + struct ANativeWindowBuffer *buf) +{ + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + struct cros_gralloc0_buffer_info info; + unsigned error; + + if (strcmp(dri2_dpy->gralloc->common.name, cros_gralloc_module_name) == 0 && + dri2_dpy->gralloc->perform && + dri2_dpy->image->base.version >= 15 && + dri2_dpy->image->createImageFromDmaBufs2 != NULL && + dri2_dpy->gralloc->perform(dri2_dpy->gralloc, + CROS_GRALLOC_DRM_GET_BUFFER_INFO, + buf->handle, &info) == 0) { + return dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen, + buf->width, buf->height, + info.drm_fourcc, info.modifier, + info.fds, info.num_fds, + info.stride, info.offset, + EGL_ITU_REC601_EXT, + EGL_YUV_FULL_RANGE_EXT, + EGL_YUV_CHROMA_SITING_0_EXT, + EGL_YUV_CHROMA_SITING_0_EXT, + &error, + NULL); + } + + return NULL; +} + +static __DRIimage * +droid_create_image_from_native_buffer(_EGLDisplay *disp, + struct ANativeWindowBuffer *buf) +{ + __DRIimage *dri_image; + + dri_image = droid_create_image_from_cros_info(disp, buf); + if (dri_image) + return dri_image; + + return droid_create_image_from_prime_fds(disp, buf); +} + static EGLBoolean droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) { @@ -729,7 +794,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) } dri2_surf->dri_image_back = - droid_create_image_from_prime_fds(disp, dri2_surf->buffer); + droid_create_image_from_native_buffer(disp, dri2_surf->buffer); if (!dri2_surf->dri_image_back) { _eglLog(_EGL_WARNING, "failed to create DRI image from FD"); return -1; @@ -987,7 +1052,7 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp, } __DRIimage *dri_image = - droid_create_image_from_prime_fds(disp, buf); + droid_create_image_from_native_buffer(disp, buf); #ifdef HAVE_DRM_GRALLOC if (dri_image == NULL) -- 2.30.2