From a2fb87eea6d45ac02c9e669699481711ae70ef50 Mon Sep 17 00:00:00 2001 From: David Stevens Date: Thu, 26 Nov 2020 13:52:58 +0900 Subject: [PATCH] egl/android: implement image cleanup callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to ANDROID_get_native_client_buffer, EGL implementations must guarantee that the lifetime of an EGLClientBuffer returned by eglGetNativeClientBufferANDROID is at least as long as that of the EGLImage which is bound to. Do this by acquiring a reference to the underlying AHardwareBuffer for all ANativeWindowBuffers which are bound to an _EGLImage. Signed-off-by: David Stevens Reviewed-by: Tapani Pälli Part-of: --- src/android_stub/meson.build | 2 +- src/android_stub/nativewindow_stub.cpp | 15 ++++++ src/egl/drivers/dri2/platform_android.c | 72 ++++++++++++++++--------- 3 files changed, 64 insertions(+), 25 deletions(-) create mode 100644 src/android_stub/nativewindow_stub.cpp diff --git a/src/android_stub/meson.build b/src/android_stub/meson.build index a4dc349d28f..86f88caea34 100644 --- a/src/android_stub/meson.build +++ b/src/android_stub/meson.build @@ -1,7 +1,7 @@ if with_android_stub stub_libs = [] - foreach lib : ['backtrace', 'cutils', 'hardware', 'log', 'sync'] + foreach lib : ['backtrace', 'cutils', 'hardware', 'log', 'nativewindow', 'sync'] stub_libs += shared_library( lib, files(lib + '_stub.cpp'), diff --git a/src/android_stub/nativewindow_stub.cpp b/src/android_stub/nativewindow_stub.cpp new file mode 100644 index 00000000000..dc0ea675560 --- /dev/null +++ b/src/android_stub/nativewindow_stub.cpp @@ -0,0 +1,15 @@ +#include + +extern "C" { + +AHardwareBuffer* ANativeWindowBuffer_getHardwareBuffer(ANativeWindowBuffer* anwb) { + return nullptr; +} + +void AHardwareBuffer_acquire(AHardwareBuffer* buffer) { +} + +void AHardwareBuffer_release(AHardwareBuffer* buffer) { +} + +} diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c index 070030ad395..22f48f27c8f 100644 --- a/src/egl/drivers/dri2/platform_android.c +++ b/src/egl/drivers/dri2/platform_android.c @@ -188,6 +188,7 @@ get_native_buffer_name(struct ANativeWindowBuffer *buf) static __DRIimage * droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, struct ANativeWindowBuffer *buf, + void *priv, int num_fds, int fds[3]) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); @@ -269,12 +270,13 @@ droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, EGL_YUV_CHROMA_SITING_0_EXT, EGL_YUV_CHROMA_SITING_0_EXT, &error, - NULL); + priv); } static __DRIimage * droid_create_image_from_prime_fds(_EGLDisplay *disp, - struct ANativeWindowBuffer *buf) + struct ANativeWindowBuffer *buf, + void *priv) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); int pitches[4] = { 0 }, offsets[4] = { 0 }; @@ -289,7 +291,8 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp, if (is_yuv(buf->format)) { __DRIimage *image; - image = droid_create_image_from_prime_fds_yuv(disp, buf, num_fds, fds); + image = droid_create_image_from_prime_fds_yuv( + disp, buf, priv, num_fds, fds); /* * HACK: https://issuetracker.google.com/32077885 * There is no API available to properly query the IMPLEMENTATION_DEFINED @@ -328,7 +331,7 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp, EGL_YUV_CHROMA_SITING_0_EXT, EGL_YUV_CHROMA_SITING_0_EXT, &error, - NULL); + priv); } /* More recent CrOS gralloc has a perform op that fills out the struct below @@ -354,7 +357,8 @@ struct cros_gralloc0_buffer_info { static __DRIimage * droid_create_image_from_cros_info(_EGLDisplay *disp, - struct ANativeWindowBuffer *buf) + struct ANativeWindowBuffer *buf, + void* priv) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct cros_gralloc0_buffer_info info; @@ -377,7 +381,7 @@ droid_create_image_from_cros_info(_EGLDisplay *disp, EGL_YUV_CHROMA_SITING_0_EXT, EGL_YUV_CHROMA_SITING_0_EXT, &error, - NULL); + priv); } return NULL; @@ -385,15 +389,16 @@ droid_create_image_from_cros_info(_EGLDisplay *disp, static __DRIimage * droid_create_image_from_native_buffer(_EGLDisplay *disp, - struct ANativeWindowBuffer *buf) + struct ANativeWindowBuffer *buf, + void *priv) { __DRIimage *dri_image; - dri_image = droid_create_image_from_cros_info(disp, buf); + dri_image = droid_create_image_from_cros_info(disp, buf, priv); if (dri_image) return dri_image; - return droid_create_image_from_prime_fds(disp, buf); + return droid_create_image_from_prime_fds(disp, buf, priv); } static EGLBoolean @@ -794,7 +799,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) } dri2_surf->dri_image_back = - droid_create_image_from_native_buffer(disp, dri2_surf->buffer); + droid_create_image_from_native_buffer(disp, dri2_surf->buffer, NULL); if (!dri2_surf->dri_image_back) { _eglLog(_EGL_WARNING, "failed to create DRI image from FD"); return -1; @@ -974,7 +979,8 @@ static int get_format(int format) static __DRIimage * droid_create_image_from_name(_EGLDisplay *disp, - struct ANativeWindowBuffer *buf) + struct ANativeWindowBuffer *buf, + void *priv) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); int name; @@ -997,7 +1003,7 @@ droid_create_image_from_name(_EGLDisplay *disp, format, name, buf->stride, - NULL); + priv); } #endif /* HAVE_DRM_GRALLOC */ @@ -1051,15 +1057,19 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp, } __DRIimage *dri_image = - droid_create_image_from_native_buffer(disp, buf); + droid_create_image_from_native_buffer(disp, buf, buf); #ifdef HAVE_DRM_GRALLOC if (dri_image == NULL) - dri_image = droid_create_image_from_name(disp, buf); + dri_image = droid_create_image_from_name(disp, buf, buf); #endif - if (dri_image) + if (dri_image) { +#if ANDROID_API_LEVEL >= 26 + AHardwareBuffer_acquire(ANativeWindowBuffer_getHardwareBuffer(buf)); +#endif return dri2_create_image_from_dri(disp, dri_image); + } return NULL; } @@ -1172,6 +1182,17 @@ droid_get_capability(void *loaderPrivate, enum dri_loader_cap cap) } } +static void +droid_destroy_loader_image_state(void *loaderPrivate) +{ +#if ANDROID_API_LEVEL >= 26 + if (loaderPrivate) { + AHardwareBuffer_release( + ANativeWindowBuffer_getHardwareBuffer(loaderPrivate)); + } +#endif +} + static EGLBoolean droid_add_configs_for_visuals(_EGLDisplay *disp) { @@ -1269,12 +1290,13 @@ static const struct dri2_egl_display_vtbl droid_display_vtbl = { #ifdef HAVE_DRM_GRALLOC static const __DRIdri2LoaderExtension droid_dri2_loader_extension = { - .base = { __DRI_DRI2_LOADER, 4 }, + .base = { __DRI_DRI2_LOADER, 5 }, - .getBuffers = NULL, - .flushFrontBuffer = droid_flush_front_buffer, - .getBuffersWithFormat = droid_get_buffers_with_format, - .getCapability = droid_get_capability, + .getBuffers = NULL, + .flushFrontBuffer = droid_flush_front_buffer, + .getBuffersWithFormat = droid_get_buffers_with_format, + .getCapability = droid_get_capability, + .destroyLoaderImageState = droid_destroy_loader_image_state, }; static const __DRIextension *droid_dri2_loader_extensions[] = { @@ -1289,11 +1311,13 @@ static const __DRIextension *droid_dri2_loader_extensions[] = { #endif /* HAVE_DRM_GRALLOC */ static const __DRIimageLoaderExtension droid_image_loader_extension = { - .base = { __DRI_IMAGE_LOADER, 2 }, + .base = { __DRI_IMAGE_LOADER, 4 }, - .getBuffers = droid_image_get_buffers, - .flushFrontBuffer = droid_flush_front_buffer, - .getCapability = droid_get_capability, + .getBuffers = droid_image_get_buffers, + .flushFrontBuffer = droid_flush_front_buffer, + .getCapability = droid_get_capability, + .flushSwapBuffers = NULL, + .destroyLoaderImageState = droid_destroy_loader_image_state, }; static void