[Mesa-dev] ANDROID: eglCreateImageKHR missing modifiers
Tomasz Figa
tfiga at chromium.org
Sat Jul 21 02:27:41 UTC 2018
Hi Martin,
On Sat, Jul 21, 2018 at 1:01 AM Martin Fuzzey
<martin.fuzzey at flowbird.group> wrote:
>
> Hi,
>
> I am testing mesa / etnaviv / gbm_gralloc under Android 8.1 on i.MX6
>
> I discovered the screen capture function was not working (it was
> producing empty buffers).
>
> The reason for this seems to be that eglCreateImageKHR() with
> EGL_NATIVE_BUFFER_ANDROID does not import the modifier information.
>
> I fixed it with the patch below, but I don't think this is the right way
> as it is adding back a dependency on the gralloc_handle structure.
As you noticed, this adds back the dependency on gralloc handle
structure. Moreover, it actually adds a dependency on the handle
having a binary format compatible with gralloc_gbm_handle_t. This is
not something that we can do in upstream Mesa, since there are more
platforms running gralloc implementations other than gbm_gralloc.
>
>
> --- a/src/egl/drivers/dri2/platform_android.c
> +++ b/src/egl/drivers/dri2/platform_android.c
> @@ -43,6 +43,8 @@
> #include "gralloc_drm.h"
> #endif /* HAVE_DRM_GRALLOC */
>
> +#include <gralloc_handle.h>
> +
> #define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
>
> struct droid_yuv_format {
> @@ -801,6 +803,9 @@ droid_create_image_from_prime_fd(_EGLDisplay *disp,
> _EGLContext *ctx,
> struct ANativeWindowBuffer *buf, int fd)
> {
> unsigned int pitch;
> + struct gralloc_gbm_handle_t *grh;
> + uint64_t modifier = 0;
> + bool have_modifier = false;
>
> if (is_yuv(buf->format)) {
> _EGLImage *image;
> @@ -829,17 +834,34 @@ droid_create_image_from_prime_fd(_EGLDisplay
> *disp, _EGLContext *ctx,
> return NULL;
> }
>
> - const EGLint attr_list[] = {
> + grh = (struct gralloc_gbm_handle_t *)buf->handle;
> + if (grh->magic == GRALLOC_HANDLE_MAGIC) {
> + modifier = grh->modifier;
> + have_modifier = true;
> + }
> +
> + EGLint attr_list[] = {
> EGL_WIDTH, buf->width,
> EGL_HEIGHT, buf->height,
> EGL_LINUX_DRM_FOURCC_EXT, fourcc,
> EGL_DMA_BUF_PLANE0_FD_EXT, fd,
> EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
> EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
> + EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, modifier & 0xffffffff,
> + EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, modifier >> 32,
> EGL_NONE, 0
> };
>
> - return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
> + if (!have_modifier) {
> + for (int i=0; i < ARRAY_SIZE(attr_list); i+=2) {
> + if (attr_list[i] == EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT) {
> + attr_list[i] = EGL_NONE;
> + break;
> + }
> + }
> + }
> +
> + return dri2_create_image_dma_buf(disp, ctx, NULL, (const EGLint
> *)attr_list);
> }
>
> What is the preferred way of fixing this?
Unfortunately, I don't have a very good solution for this. In Chrome
OS we just don't support modifiers in EGL/GLES on Android. Obviously
it would be a good idea to have some way to query gralloc for the
modifier, but I don't see Android providing any generic way to do it.
The least evil I can think of as a makeshift for now could be an
optional gralloc0 perform call that returns the modifier for given
buffer.
Best regards,
Tomasz
More information about the mesa-dev
mailing list