arc-mesa-virgl: carry two upstream merge requests

The target merge request is 7805, which acquires AHardwareBuffers while
they are bound to EGLImages. Merge request 6055 is included as the
target merge request relies on its refactoring.

BUG=b:159356552
TEST=no flicker when changing resolutions in ArcCameraFpsTest

Change-Id: I10b667a1b44ad92fd6ec03e28459d924c120e45b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/2591998
Tested-by: David Stevens <stevensd@chromium.org>
Commit-Queue: Lepton Wu <lepton@chromium.org>
Reviewed-by: Lepton Wu <lepton@chromium.org>
diff --git a/media-libs/arc-mesa-virgl/arc-mesa-virgl-20.0.7-r13.ebuild b/media-libs/arc-mesa-virgl/arc-mesa-virgl-20.0.7-r14.ebuild
similarity index 100%
rename from media-libs/arc-mesa-virgl/arc-mesa-virgl-20.0.7-r13.ebuild
rename to media-libs/arc-mesa-virgl/arc-mesa-virgl-20.0.7-r14.ebuild
diff --git a/media-libs/arc-mesa-virgl/arc-mesa-virgl-20.ebuild b/media-libs/arc-mesa-virgl/arc-mesa-virgl-20.ebuild
index fedc790..27371fc 100644
--- a/media-libs/arc-mesa-virgl/arc-mesa-virgl-20.ebuild
+++ b/media-libs/arc-mesa-virgl/arc-mesa-virgl-20.ebuild
@@ -152,6 +152,21 @@
 
 	epatch "${FILESDIR}"/UPSTREAM-dri_util-Update-internal_format-to-GL_RGB8-for-MESA_.patch
 
+	# merge request 6055
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Call-createImageFromDmaBufs-directly.patch
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Look-up-prime-fds-in-droid_create_image_.patch
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Drop-unused-ctx-argument.patch
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Simplify-droid_create_image_from_name-pa.patch
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Move-droid_create_image_from_prime_fds-f.patch
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Use-droid_create_image_from_prime_fds-in.patch
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-Add-support-for-CrOS-buffer-info-perform.patch
+
+	# merge request 7805
+	epatch "${FILESDIR}"/UPSTREAM-egl-android-don-t-pass-loaderPriv-in-get_front_bo.patch
+	epatch "${FILESDIR}"/UPSTREAM-dri-add-image-cleanup-callback-to-loader-extensions.patch
+	epatch "${FILESDIR}"/BACKPORT-frontend-dri-plumb-loader-image-cleanup-callback.patch
+	epatch "${FILESDIR}"/BACKPORT-egl-android-implement-image-cleanup-callback.patch
+
 	default
 }
 
diff --git a/media-libs/arc-mesa-virgl/files/BACKPORT-egl-android-implement-image-cleanup-callback.patch b/media-libs/arc-mesa-virgl/files/BACKPORT-egl-android-implement-image-cleanup-callback.patch
new file mode 100644
index 0000000..91c3e42
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/BACKPORT-egl-android-implement-image-cleanup-callback.patch
@@ -0,0 +1,218 @@
+From d1b8ea27dd304b81dba02a9d1d74441fb2e6caea Mon Sep 17 00:00:00 2001
+From: David Stevens <stevensd@chromium.org>
+Date: Thu, 26 Nov 2020 13:52:58 +0900
+Subject: [PATCH 11/11] 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 <stevensd@chromium.org>
+Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7805>
+Change-Id: I4097fbcba91b1d5f6d7e0e423a84a808c101c347
+---
+ src/egl/drivers/dri2/platform_android.c | 72 ++++++++++++++++---------
+ 1 file changed, 48 insertions(+), 24 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 0395b5246e4..1abe7d157c5 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -207,6 +207,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);
+@@ -288,12 +289,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 };
+@@ -308,7 +310,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
+@@ -347,7 +350,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
+@@ -373,7 +376,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;
+@@ -396,7 +400,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;
+@@ -404,15 +408,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
+@@ -812,7 +817,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;
+@@ -973,7 +978,8 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+ #ifdef HAVE_DRM_GRALLOC
+ static _EGLImage *
+ 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);
+    __DRIimage *dri_image;
+@@ -997,7 +1003,7 @@ droid_create_image_from_name(_EGLDisplay *disp,
+ 					   format,
+ 					   name,
+ 					   buf->stride,
+-					   dri2_img);
++					   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;
+ }
+@@ -1173,6 +1183,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(_EGLDriver *drv, _EGLDisplay *disp)
+ {
+@@ -1277,12 +1298,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[] = {
+@@ -1297,11 +1319,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
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/BACKPORT-frontend-dri-plumb-loader-image-cleanup-callback.patch b/media-libs/arc-mesa-virgl/files/BACKPORT-frontend-dri-plumb-loader-image-cleanup-callback.patch
new file mode 100644
index 0000000..08dae36
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/BACKPORT-frontend-dri-plumb-loader-image-cleanup-callback.patch
@@ -0,0 +1,99 @@
+From 9277e452081670674dd9fabb909971da3b00c7f4 Mon Sep 17 00:00:00 2001
+From: David Stevens <stevensd@chromium.org>
+Date: Thu, 26 Nov 2020 13:15:55 +0900
+Subject: [PATCH 10/11] frontend/dri: plumb loader image cleanup callback
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: David Stevens <stevensd@chromium.org>
+Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7805>
+---
+ src/gallium/state_trackers/dri/dri2.c        |  3 +++
+ src/gallium/state_trackers/dri/dri_helpers.c | 13 +++++++++++++
+ src/gallium/state_trackers/dri/dri_screen.h  |  2 ++
+ 3 files changed, 18 insertions(+)
+
+diff --git a/src/gallium/state_trackers/dri/dri2.c b/src/gallium/state_trackers/dri/dri2.c
+index 8b4402a74aa..b9f0bd35b47 100644
+--- a/src/gallium/state_trackers/dri/dri2.c
++++ b/src/gallium/state_trackers/dri/dri2.c
+@@ -801,6 +801,7 @@ dri2_create_image_from_winsys(__DRIscreen *_screen,
+    img->layer = 0;
+    img->use = 0;
+    img->loader_private = loaderPrivate;
++   img->sPriv = _screen;
+ 
+    return img;
+ }
+@@ -1012,6 +1013,7 @@ dri2_create_image_common(__DRIscreen *_screen,
+    img->use = use;
+ 
+    img->loader_private = loaderPrivate;
++   img->sPriv = _screen;
+    return img;
+ }
+ 
+@@ -1260,6 +1262,7 @@ dri2_dup_image(__DRIimage *image, void *loaderPrivate)
+    /* This should be 0 for sub images, but dup is also used for base images. */
+    img->dri_components = image->dri_components;
+    img->loader_private = loaderPrivate;
++   img->sPriv = image->sPriv;
+ 
+    return img;
+ }
+diff --git a/src/gallium/state_trackers/dri/dri_helpers.c b/src/gallium/state_trackers/dri/dri_helpers.c
+index 90a8a392fad..615fc70c1e1 100644
+--- a/src/gallium/state_trackers/dri/dri_helpers.c
++++ b/src/gallium/state_trackers/dri/dri_helpers.c
+@@ -296,6 +296,7 @@ dri2_create_image_from_renderbuffer2(__DRIcontext *context,
+ 
+    img->dri_format = driGLFormatToImageFormat(rb->Format);
+    img->loader_private = loaderPrivate;
++   img->sPriv = context->driScreenPriv;
+ 
+    pipe_resource_reference(&img->texture, tex);
+ 
+@@ -315,6 +316,17 @@ dri2_create_image_from_renderbuffer(__DRIcontext *context,
+ void
+ dri2_destroy_image(__DRIimage *img)
+ {
++   const __DRIimageLoaderExtension *imgLoader = img->sPriv->image.loader;
++   const __DRIdri2LoaderExtension *dri2Loader = img->sPriv->dri2.loader;
++
++   if (imgLoader && imgLoader->base.version >= 4 &&
++         imgLoader->destroyLoaderImageState) {
++      imgLoader->destroyLoaderImageState(img->loader_private);
++   } else if (dri2Loader && dri2Loader->base.version >= 5 &&
++         dri2Loader->destroyLoaderImageState) {
++      dri2Loader->destroyLoaderImageState(img->loader_private);
++   }
++
+    pipe_resource_reference(&img->texture, NULL);
+    FREE(img);
+ }
+@@ -373,6 +385,7 @@ dri2_create_from_texture(__DRIcontext *context, int target, unsigned texture,
+    img->dri_format = driGLFormatToImageFormat(obj->Image[face][level]->TexFormat);
+ 
+    img->loader_private = loaderPrivate;
++   img->sPriv = context->driScreenPriv;
+ 
+    pipe_resource_reference(&img->texture, tex);
+ 
+diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
+index 1586439bba3..be8a5141237 100644
+--- a/src/gallium/state_trackers/dri/dri_screen.h
++++ b/src/gallium/state_trackers/dri/dri_screen.h
+@@ -118,6 +118,8 @@ struct __DRIimageRec {
+    enum __DRIChromaSiting horizontal_siting;
+    enum __DRIChromaSiting vertical_siting;
+ 
++   /* DRI loader screen */
++   __DRIscreen *sPriv;
+ };
+ 
+ static inline boolean
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-dri-add-image-cleanup-callback-to-loader-extensions.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-dri-add-image-cleanup-callback-to-loader-extensions.patch
new file mode 100644
index 0000000..89c2abe
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-dri-add-image-cleanup-callback-to-loader-extensions.patch
@@ -0,0 +1,75 @@
+From e0ded637ccc5a17437585b3417ce2d5a9eb30ffa Mon Sep 17 00:00:00 2001
+From: David Stevens <stevensd@chromium.org>
+Date: Thu, 26 Nov 2020 14:03:16 +0900
+Subject: [PATCH 09/11] dri: add image cleanup callback to loader extensions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The callback may be used by dri drivers to perform cleanup when images
+are destroyed. It is added to the dri2 and image loader extensions.
+
+Signed-off-by: David Stevens <stevensd@chromium.org>
+Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7805>
+---
+ include/GL/internal/dri_interface.h | 22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
+index e40106575c0..69969eebaa6 100644
+--- a/include/GL/internal/dri_interface.h
++++ b/include/GL/internal/dri_interface.h
+@@ -1106,7 +1106,7 @@ struct __DRIbufferRec {
+ };
+ 
+ #define __DRI_DRI2_LOADER "DRI_DRI2Loader"
+-#define __DRI_DRI2_LOADER_VERSION 4
++#define __DRI_DRI2_LOADER_VERSION 5
+ 
+ enum dri_loader_cap {
+    /* Whether the loader handles RGBA channel ordering correctly. If not,
+@@ -1177,6 +1177,15 @@ struct __DRIdri2LoaderExtensionRec {
+      * \since 4
+      */
+     unsigned (*getCapability)(void *loaderPrivate, enum dri_loader_cap cap);
++
++    /**
++     * Clean up any loader state associated with an image.
++     *
++     * \param loaderPrivate  Loader's private data that was previously passed
++     *                       into a __DRIimageExtensionRec::createImage function
++     * \since 5
++     */
++    void (*destroyLoaderImageState)(void *loaderPrivate);
+ };
+ 
+ /**
+@@ -2003,7 +2012,7 @@ struct __DRIimageList {
+ };
+ 
+ #define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
+-#define __DRI_IMAGE_LOADER_VERSION 3
++#define __DRI_IMAGE_LOADER_VERSION 4
+ 
+ struct __DRIimageLoaderExtensionRec {
+     __DRIextension base;
+@@ -2062,6 +2071,15 @@ struct __DRIimageLoaderExtensionRec {
+      * \since 3
+      */
+     void (*flushSwapBuffers)(__DRIdrawable *driDrawable, void *loaderPrivate);
++
++    /**
++     * Clean up any loader state associated with an image.
++     *
++     * \param loaderPrivate  Loader's private data that was previously passed
++     *                       into a __DRIimageExtensionRec::createImage function
++     * \since 4
++     */
++    void (*destroyLoaderImageState)(void *loaderPrivate);
+ };
+ 
+ /**
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Add-support-for-CrOS-buffer-info-perform.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Add-support-for-CrOS-buffer-info-perform.patch
new file mode 100644
index 0000000..374e3cc
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Add-support-for-CrOS-buffer-info-perform.patch
@@ -0,0 +1,113 @@
+From 9ef5282ff2991c9c58993844e1d4e387e128d9f3 Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Mon, 10 Aug 2020 19:05:05 -0700
+Subject: [PATCH 07/11] 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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ 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 73955b6299e..3b2dffad212 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -350,6 +350,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)
+ {
+@@ -747,7 +812,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;
+@@ -986,7 +1051,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.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Call-createImageFromDmaBufs-directly.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Call-createImageFromDmaBufs-directly.patch
new file mode 100644
index 0000000..f5bf085
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Call-createImageFromDmaBufs-directly.patch
@@ -0,0 +1,193 @@
+From a66dbd4f27c83c928b0c44893173816d61a91937 Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Thu, 6 Aug 2020 16:38:28 -0700
+Subject: [PATCH 01/11] egl/android: Call createImageFromDmaBufs directly
+
+Instead of building up EGL attribute lists and then having to parse
+them again, call the DRI driver directly and then use the
+dri2_create_image_from_dri() helper to wrap the __DRIimage in an
+EGLImage.
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ src/egl/drivers/dri2/egl_dri2.c         |  2 +-
+ src/egl/drivers/dri2/egl_dri2.h         |  3 +
+ src/egl/drivers/dri2/platform_android.c | 94 ++++++++++---------------
+ 3 files changed, 41 insertions(+), 58 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
+index 2a216ef1c80..d57f1486677 100644
+--- a/src/egl/drivers/dri2/egl_dri2.c
++++ b/src/egl/drivers/dri2/egl_dri2.c
+@@ -2141,7 +2141,7 @@ dri2_create_image(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx,
+                                        attr_list);
+ }
+ 
+-static _EGLImage *
++_EGLImage *
+ dri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image)
+ {
+    struct dri2_egl_image *dri2_img;
+diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
+index 96cf04d89e9..ac7f0de7ebd 100644
+--- a/src/egl/drivers/dri2/egl_dri2.h
++++ b/src/egl/drivers/dri2/egl_dri2.h
+@@ -435,6 +435,9 @@ _EGLImage *
+ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
+                           EGLClientBuffer buffer, const EGLint *attr_list);
+ 
++_EGLImage *
++dri2_create_image_from_dri(_EGLDisplay *disp, __DRIimage *dri_image);
++
+ #ifdef HAVE_X11_PLATFORM
+ EGLBoolean
+ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index da90c44d601..3814187724a 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -788,18 +788,19 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+    return EGL_TRUE;
+ }
+ 
+-static _EGLImage *
++static __DRIimage *
+ droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, _EGLContext *ctx,
+                                      struct ANativeWindowBuffer *buf,
+                                      int num_fds, int fds[3])
+ {
+    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+    struct android_ycbcr ycbcr;
+-   size_t offsets[3];
+-   size_t pitches[3];
++   int offsets[3];
++   int pitches[3];
+    enum chroma_order chroma_order;
+    int fourcc;
+    int ret;
++   unsigned error;
+ 
+    if (!dri2_dpy->gralloc->lock_ycbcr) {
+       _eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
+@@ -863,52 +864,27 @@ droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, _EGLContext *ctx,
+       assert(num_fds == expected_planes);
+    }
+ 
+-   if (ycbcr.chroma_step == 2) {
+-      /* Semi-planar Y + CbCr or Y + CrCb format. */
+-      const EGLint attr_list_2plane[] = {
+-         EGL_WIDTH, buf->width,
+-         EGL_HEIGHT, buf->height,
+-         EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+-         EGL_DMA_BUF_PLANE0_FD_EXT, fds[0],
+-         EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
+-         EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
+-         EGL_DMA_BUF_PLANE1_FD_EXT, fds[1],
+-         EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
+-         EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
+-         EGL_NONE, 0
+-      };
+-
+-      return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_2plane);
+-   } else {
+-      /* Fully planar Y + Cb + Cr or Y + Cr + Cb format. */
+-      const EGLint attr_list_3plane[] = {
+-         EGL_WIDTH, buf->width,
+-         EGL_HEIGHT, buf->height,
+-         EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+-         EGL_DMA_BUF_PLANE0_FD_EXT, fds[0],
+-         EGL_DMA_BUF_PLANE0_PITCH_EXT, pitches[0],
+-         EGL_DMA_BUF_PLANE0_OFFSET_EXT, offsets[0],
+-         EGL_DMA_BUF_PLANE1_FD_EXT, fds[1],
+-         EGL_DMA_BUF_PLANE1_PITCH_EXT, pitches[1],
+-         EGL_DMA_BUF_PLANE1_OFFSET_EXT, offsets[1],
+-         EGL_DMA_BUF_PLANE2_FD_EXT, fds[2],
+-         EGL_DMA_BUF_PLANE2_PITCH_EXT, pitches[2],
+-         EGL_DMA_BUF_PLANE2_OFFSET_EXT, offsets[2],
+-         EGL_NONE, 0
+-      };
+-
+-      return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list_3plane);
+-   }
++   return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
++      buf->width, buf->height, fourcc,
++      fds, num_fds, pitches, offsets,
++      EGL_ITU_REC601_EXT,
++      EGL_YUV_NARROW_RANGE_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      &error,
++      NULL);
+ }
+ 
+-static _EGLImage *
++static __DRIimage *
+ droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
+                                   struct ANativeWindowBuffer *buf, int num_fds, int fds[3])
+ {
+-   unsigned int pitch;
++   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++   int pitches[4] = { 0 }, offsets[4] = { 0 };
++   unsigned error;
+ 
+    if (is_yuv(buf->format)) {
+-      _EGLImage *image;
++      __DRIimage *image;
+ 
+       image = droid_create_image_from_prime_fds_yuv(disp, ctx, buf, num_fds, fds);
+       /*
+@@ -935,23 +911,21 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
+       return NULL;
+    }
+ 
+-   pitch = buf->stride * get_format_bpp(buf->format);
+-   if (pitch == 0) {
++   pitches[0] = buf->stride * get_format_bpp(buf->format);
++   if (pitches[0] == 0) {
+       _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+       return NULL;
+    }
+ 
+-   const EGLint attr_list[] = {
+-      EGL_WIDTH, buf->width,
+-      EGL_HEIGHT, buf->height,
+-      EGL_LINUX_DRM_FOURCC_EXT, fourcc,
+-      EGL_DMA_BUF_PLANE0_FD_EXT, fds[0],
+-      EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch,
+-      EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
+-      EGL_NONE, 0
+-   };
+-
+-   return dri2_create_image_dma_buf(disp, ctx, NULL, attr_list);
++   return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
++      buf->width, buf->height, fourcc,
++      fds, num_fds, pitches, offsets,
++      EGL_ITU_REC601_EXT,
++      EGL_YUV_NARROW_RANGE_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      &error,
++      NULL);
+ }
+ 
+ #ifdef HAVE_DRM_GRALLOC
+@@ -1053,8 +1027,14 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+    }
+ 
+    num_fds = get_native_buffer_fds(buf, fds);
+-   if (num_fds > 0)
+-      return droid_create_image_from_prime_fds(disp, ctx, buf, num_fds, fds);
++   if (num_fds > 0) {
++      __DRIimage *dri_image =
++         droid_create_image_from_prime_fds(disp, ctx, buf, num_fds, fds);
++      if (!dri_image)
++         return EGL_NO_IMAGE_KHR;
++
++      return dri2_create_image_from_dri(disp, dri_image);
++   }
+ 
+ #ifdef HAVE_DRM_GRALLOC
+    return droid_create_image_from_name(disp, ctx, buf);
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Drop-unused-ctx-argument.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Drop-unused-ctx-argument.patch
new file mode 100644
index 0000000..465476b
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Drop-unused-ctx-argument.patch
@@ -0,0 +1,71 @@
+From a4cbe69e4766ceeb1b94d980b01461651e9f5837 Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Thu, 6 Aug 2020 17:29:35 -0700
+Subject: [PATCH 03/11] egl/android: Drop unused ctx argument
+
+EGL_ANDROID_image_native_buffer requires the ctx argument to always be
+NULL, so not point in passing it around.
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ src/egl/drivers/dri2/platform_android.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 646a7333755..6bcc3143606 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -789,7 +789,7 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+ }
+ 
+ static __DRIimage *
+-droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, _EGLContext *ctx,
++droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp,
+                                      struct ANativeWindowBuffer *buf,
+                                      int num_fds, int fds[3])
+ {
+@@ -876,7 +876,7 @@ droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, _EGLContext *ctx,
+ }
+ 
+ static __DRIimage *
+-droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
++droid_create_image_from_prime_fds(_EGLDisplay *disp,
+                                   struct ANativeWindowBuffer *buf)
+ {
+    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+@@ -892,7 +892,7 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
+    if (is_yuv(buf->format)) {
+       __DRIimage *image;
+ 
+-      image = droid_create_image_from_prime_fds_yuv(disp, ctx, buf, num_fds, fds);
++      image = droid_create_image_from_prime_fds_yuv(disp, buf, num_fds, fds);
+       /*
+        * HACK: https://issuetracker.google.com/32077885
+        * There is no API available to properly query the IMPLEMENTATION_DEFINED
+@@ -936,7 +936,7 @@ droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
+ 
+ #ifdef HAVE_DRM_GRALLOC
+ static _EGLImage *
+-droid_create_image_from_name(_EGLDisplay *disp, _EGLContext *ctx,
++droid_create_image_from_name(_EGLDisplay *disp,
+                              struct ANativeWindowBuffer *buf)
+ {
+    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+@@ -1030,12 +1030,12 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+    }
+ 
+    __DRIimage *dri_image =
+-      droid_create_image_from_prime_fds(disp, ctx, buf);
++      droid_create_image_from_prime_fds(disp, buf);
+    if (dri_image)
+       return dri2_create_image_from_dri(disp, dri_image);
+ 
+ #ifdef HAVE_DRM_GRALLOC
+-   return droid_create_image_from_name(disp, ctx, buf);
++   return droid_create_image_from_name(disp, buf);
+ #else
+    return NULL;
+ #endif
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Look-up-prime-fds-in-droid_create_image_.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Look-up-prime-fds-in-droid_create_image_.patch
new file mode 100644
index 0000000..4de79f2
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Look-up-prime-fds-in-droid_create_image_.patch
@@ -0,0 +1,69 @@
+From c55d7757f0f16d52675e9178b5fca43a5ad03f30 Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Thu, 6 Aug 2020 16:45:28 -0700
+Subject: [PATCH 02/11] egl/android: Look up prime fds in
+ droid_create_image_from_prime_fds()
+
+We always need to look them up before calling this function, so move
+the lookup into the function to consolidate the code.
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ src/egl/drivers/dri2/platform_android.c | 22 ++++++++++------------
+ 1 file changed, 10 insertions(+), 12 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 3814187724a..646a7333755 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -877,11 +877,17 @@ droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp, _EGLContext *ctx,
+ 
+ static __DRIimage *
+ droid_create_image_from_prime_fds(_EGLDisplay *disp, _EGLContext *ctx,
+-                                  struct ANativeWindowBuffer *buf, int num_fds, int fds[3])
++                                  struct ANativeWindowBuffer *buf)
+ {
+    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+    int pitches[4] = { 0 }, offsets[4] = { 0 };
+    unsigned error;
++   int num_fds;
++   int fds[3];
++
++   num_fds = get_native_buffer_fds(buf, fds);
++   if (num_fds == 0)
++      return NULL;
+ 
+    if (is_yuv(buf->format)) {
+       __DRIimage *image;
+@@ -1005,9 +1011,6 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+                                         _EGLContext *ctx,
+                                         struct ANativeWindowBuffer *buf)
+ {
+-   int fds[3];
+-   unsigned num_fds;
+-
+    if (ctx != NULL) {
+       /* From the EGL_ANDROID_image_native_buffer spec:
+        *
+@@ -1026,15 +1029,10 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+       return NULL;
+    }
+ 
+-   num_fds = get_native_buffer_fds(buf, fds);
+-   if (num_fds > 0) {
+-      __DRIimage *dri_image =
+-         droid_create_image_from_prime_fds(disp, ctx, buf, num_fds, fds);
+-      if (!dri_image)
+-         return EGL_NO_IMAGE_KHR;
+-
++   __DRIimage *dri_image =
++      droid_create_image_from_prime_fds(disp, ctx, buf);
++   if (dri_image)
+       return dri2_create_image_from_dri(disp, dri_image);
+-   }
+ 
+ #ifdef HAVE_DRM_GRALLOC
+    return droid_create_image_from_name(disp, ctx, buf);
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Move-droid_create_image_from_prime_fds-f.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Move-droid_create_image_from_prime_fds-f.patch
new file mode 100644
index 0000000..f3e7150
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Move-droid_create_image_from_prime_fds-f.patch
@@ -0,0 +1,326 @@
+From 95194827ba10969185a324ea8ee559324752bacd Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Mon, 10 Aug 2020 18:42:33 -0700
+Subject: [PATCH 05/11] egl/android: Move droid_create_image_from_prime_fds()
+ function up
+
+We'll use it for get_back_bo() next.
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ src/egl/drivers/dri2/platform_android.c | 292 ++++++++++++------------
+ 1 file changed, 146 insertions(+), 146 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 01a62cf0d7b..b77acb4c273 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -204,6 +204,152 @@ get_native_buffer_name(struct ANativeWindowBuffer *buf)
+ }
+ #endif /* HAVE_DRM_GRALLOC */
+ 
++static __DRIimage *
++droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp,
++                                     struct ANativeWindowBuffer *buf,
++                                     int num_fds, int fds[3])
++{
++   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++   struct android_ycbcr ycbcr;
++   int offsets[3];
++   int pitches[3];
++   enum chroma_order chroma_order;
++   int fourcc;
++   int ret;
++   unsigned error;
++
++   if (!dri2_dpy->gralloc->lock_ycbcr) {
++      _eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
++      return NULL;
++   }
++
++   memset(&ycbcr, 0, sizeof(ycbcr));
++   ret = dri2_dpy->gralloc->lock_ycbcr(dri2_dpy->gralloc, buf->handle,
++                                       0, 0, 0, 0, 0, &ycbcr);
++   if (ret) {
++      /* HACK: See droid_create_image_from_prime_fds() and
++       * https://issuetracker.google.com/32077885.*/
++      if (buf->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
++         return NULL;
++
++      _eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret);
++      return NULL;
++   }
++   dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, buf->handle);
++
++   /* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
++    * it will return the .y/.cb/.cr pointers based on a NULL pointer,
++    * so they can be interpreted as offsets. */
++   offsets[0] = (size_t)ycbcr.y;
++   /* We assume here that all the planes are located in one DMA-buf. */
++   if ((size_t)ycbcr.cr < (size_t)ycbcr.cb) {
++      chroma_order = YCrCb;
++      offsets[1] = (size_t)ycbcr.cr;
++      offsets[2] = (size_t)ycbcr.cb;
++   } else {
++      chroma_order = YCbCr;
++      offsets[1] = (size_t)ycbcr.cb;
++      offsets[2] = (size_t)ycbcr.cr;
++   }
++
++   /* .ystride is the line length (in bytes) of the Y plane,
++    * .cstride is the line length (in bytes) of any of the remaining
++    * Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully
++    * planar formats. */
++   pitches[0] = ycbcr.ystride;
++   pitches[1] = pitches[2] = ycbcr.cstride;
++
++   /* .chroma_step is the byte distance between the same chroma channel
++    * values of subsequent pixels, assumed to be the same for Cb and Cr. */
++   fourcc = get_fourcc_yuv(buf->format, chroma_order, ycbcr.chroma_step);
++   if (fourcc == -1) {
++      _eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = %d",
++              buf->format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", ycbcr.chroma_step);
++      return NULL;
++   }
++
++   /*
++    * Since this is EGL_NATIVE_BUFFER_ANDROID don't assume that
++    * the single-fd case cannot happen.  So handle eithe single
++    * fd or fd-per-plane case:
++    */
++   if (num_fds == 1) {
++      fds[2] = fds[1] = fds[0];
++   } else {
++      int expected_planes = (ycbcr.chroma_step == 2) ? 2 : 3;
++      assert(num_fds == expected_planes);
++   }
++
++   return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
++      buf->width, buf->height, fourcc,
++      fds, num_fds, pitches, offsets,
++      EGL_ITU_REC601_EXT,
++      EGL_YUV_NARROW_RANGE_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      &error,
++      NULL);
++}
++
++static __DRIimage *
++droid_create_image_from_prime_fds(_EGLDisplay *disp,
++                                  struct ANativeWindowBuffer *buf)
++{
++   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
++   int pitches[4] = { 0 }, offsets[4] = { 0 };
++   unsigned error;
++   int num_fds;
++   int fds[3];
++
++   num_fds = get_native_buffer_fds(buf, fds);
++   if (num_fds == 0)
++      return NULL;
++
++   if (is_yuv(buf->format)) {
++      __DRIimage *image;
++
++      image = droid_create_image_from_prime_fds_yuv(disp, buf, num_fds, fds);
++      /*
++       * HACK: https://issuetracker.google.com/32077885
++       * There is no API available to properly query the IMPLEMENTATION_DEFINED
++       * format. As a workaround we rely here on gralloc allocating either
++       * an arbitrary YCbCr 4:2:0 or RGBX_8888, with the latter being recognized
++       * by lock_ycbcr failing.
++       */
++      if (image || buf->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
++         return image;
++   }
++
++   /*
++    * Non-YUV formats could *also* have multiple planes, such as ancillary
++    * color compression state buffer, but the rest of the code isn't ready
++    * yet to deal with modifiers:
++    */
++   assert(num_fds == 1);
++
++   const int fourcc = get_fourcc(buf->format);
++   if (fourcc == -1) {
++      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
++      return NULL;
++   }
++
++   pitches[0] = buf->stride * get_format_bpp(buf->format);
++   if (pitches[0] == 0) {
++      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
++      return NULL;
++   }
++
++   return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
++      buf->width, buf->height, fourcc,
++      fds, num_fds, pitches, offsets,
++      EGL_ITU_REC601_EXT,
++      EGL_YUV_NARROW_RANGE_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      EGL_YUV_CHROMA_SITING_0_EXT,
++      &error,
++      NULL);
++}
++
+ static EGLBoolean
+ droid_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf)
+ {
+@@ -788,152 +934,6 @@ droid_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
+    return EGL_TRUE;
+ }
+ 
+-static __DRIimage *
+-droid_create_image_from_prime_fds_yuv(_EGLDisplay *disp,
+-                                     struct ANativeWindowBuffer *buf,
+-                                     int num_fds, int fds[3])
+-{
+-   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+-   struct android_ycbcr ycbcr;
+-   int offsets[3];
+-   int pitches[3];
+-   enum chroma_order chroma_order;
+-   int fourcc;
+-   int ret;
+-   unsigned error;
+-
+-   if (!dri2_dpy->gralloc->lock_ycbcr) {
+-      _eglLog(_EGL_WARNING, "Gralloc does not support lock_ycbcr");
+-      return NULL;
+-   }
+-
+-   memset(&ycbcr, 0, sizeof(ycbcr));
+-   ret = dri2_dpy->gralloc->lock_ycbcr(dri2_dpy->gralloc, buf->handle,
+-                                       0, 0, 0, 0, 0, &ycbcr);
+-   if (ret) {
+-      /* HACK: See droid_create_image_from_prime_fds() and
+-       * https://issuetracker.google.com/32077885.*/
+-      if (buf->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
+-         return NULL;
+-
+-      _eglLog(_EGL_WARNING, "gralloc->lock_ycbcr failed: %d", ret);
+-      return NULL;
+-   }
+-   dri2_dpy->gralloc->unlock(dri2_dpy->gralloc, buf->handle);
+-
+-   /* When lock_ycbcr's usage argument contains no SW_READ/WRITE flags
+-    * it will return the .y/.cb/.cr pointers based on a NULL pointer,
+-    * so they can be interpreted as offsets. */
+-   offsets[0] = (size_t)ycbcr.y;
+-   /* We assume here that all the planes are located in one DMA-buf. */
+-   if ((size_t)ycbcr.cr < (size_t)ycbcr.cb) {
+-      chroma_order = YCrCb;
+-      offsets[1] = (size_t)ycbcr.cr;
+-      offsets[2] = (size_t)ycbcr.cb;
+-   } else {
+-      chroma_order = YCbCr;
+-      offsets[1] = (size_t)ycbcr.cb;
+-      offsets[2] = (size_t)ycbcr.cr;
+-   }
+-
+-   /* .ystride is the line length (in bytes) of the Y plane,
+-    * .cstride is the line length (in bytes) of any of the remaining
+-    * Cb/Cr/CbCr planes, assumed to be the same for Cb and Cr for fully
+-    * planar formats. */
+-   pitches[0] = ycbcr.ystride;
+-   pitches[1] = pitches[2] = ycbcr.cstride;
+-
+-   /* .chroma_step is the byte distance between the same chroma channel
+-    * values of subsequent pixels, assumed to be the same for Cb and Cr. */
+-   fourcc = get_fourcc_yuv(buf->format, chroma_order, ycbcr.chroma_step);
+-   if (fourcc == -1) {
+-      _eglLog(_EGL_WARNING, "unsupported YUV format, native = %x, chroma_order = %s, chroma_step = %d",
+-              buf->format, chroma_order == YCbCr ? "YCbCr" : "YCrCb", ycbcr.chroma_step);
+-      return NULL;
+-   }
+-
+-   /*
+-    * Since this is EGL_NATIVE_BUFFER_ANDROID don't assume that
+-    * the single-fd case cannot happen.  So handle eithe single
+-    * fd or fd-per-plane case:
+-    */
+-   if (num_fds == 1) {
+-      fds[2] = fds[1] = fds[0];
+-   } else {
+-      int expected_planes = (ycbcr.chroma_step == 2) ? 2 : 3;
+-      assert(num_fds == expected_planes);
+-   }
+-
+-   return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+-      buf->width, buf->height, fourcc,
+-      fds, num_fds, pitches, offsets,
+-      EGL_ITU_REC601_EXT,
+-      EGL_YUV_NARROW_RANGE_EXT,
+-      EGL_YUV_CHROMA_SITING_0_EXT,
+-      EGL_YUV_CHROMA_SITING_0_EXT,
+-      &error,
+-      NULL);
+-}
+-
+-static __DRIimage *
+-droid_create_image_from_prime_fds(_EGLDisplay *disp,
+-                                  struct ANativeWindowBuffer *buf)
+-{
+-   struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+-   int pitches[4] = { 0 }, offsets[4] = { 0 };
+-   unsigned error;
+-   int num_fds;
+-   int fds[3];
+-
+-   num_fds = get_native_buffer_fds(buf, fds);
+-   if (num_fds == 0)
+-      return NULL;
+-
+-   if (is_yuv(buf->format)) {
+-      __DRIimage *image;
+-
+-      image = droid_create_image_from_prime_fds_yuv(disp, buf, num_fds, fds);
+-      /*
+-       * HACK: https://issuetracker.google.com/32077885
+-       * There is no API available to properly query the IMPLEMENTATION_DEFINED
+-       * format. As a workaround we rely here on gralloc allocating either
+-       * an arbitrary YCbCr 4:2:0 or RGBX_8888, with the latter being recognized
+-       * by lock_ycbcr failing.
+-       */
+-      if (image || buf->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
+-         return image;
+-   }
+-
+-   /*
+-    * Non-YUV formats could *also* have multiple planes, such as ancillary
+-    * color compression state buffer, but the rest of the code isn't ready
+-    * yet to deal with modifiers:
+-    */
+-   assert(num_fds == 1);
+-
+-   const int fourcc = get_fourcc(buf->format);
+-   if (fourcc == -1) {
+-      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+-      return NULL;
+-   }
+-
+-   pitches[0] = buf->stride * get_format_bpp(buf->format);
+-   if (pitches[0] == 0) {
+-      _eglError(EGL_BAD_PARAMETER, "eglCreateEGLImageKHR");
+-      return NULL;
+-   }
+-
+-   return dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+-      buf->width, buf->height, fourcc,
+-      fds, num_fds, pitches, offsets,
+-      EGL_ITU_REC601_EXT,
+-      EGL_YUV_NARROW_RANGE_EXT,
+-      EGL_YUV_CHROMA_SITING_0_EXT,
+-      EGL_YUV_CHROMA_SITING_0_EXT,
+-      &error,
+-      NULL);
+-}
+-
+ #ifdef HAVE_DRM_GRALLOC
+ static _EGLImage *
+ droid_create_image_from_name(_EGLDisplay *disp,
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Simplify-droid_create_image_from_name-pa.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Simplify-droid_create_image_from_name-pa.patch
new file mode 100644
index 0000000..8320a7e3
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Simplify-droid_create_image_from_name-pa.patch
@@ -0,0 +1,82 @@
+From 4b9dbe0bed5dac7f7a669b7cd1e8b28a5dee05de Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Thu, 6 Aug 2020 17:39:47 -0700
+Subject: [PATCH 04/11] egl/android: Simplify droid_create_image_from_name()
+ path
+
+This can now return an __DRIimage which we'll wrap in the shared code
+in dri2_create_image_android_native_buffer().
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ src/egl/drivers/dri2/platform_android.c | 29 +++++++------------------
+ 1 file changed, 8 insertions(+), 21 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 6bcc3143606..01a62cf0d7b 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -940,7 +940,7 @@ droid_create_image_from_name(_EGLDisplay *disp,
+                              struct ANativeWindowBuffer *buf)
+ {
+    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+-   struct dri2_egl_image *dri2_img;
++   __DRIimage *dri_image;
+    int name;
+    int format;
+ 
+@@ -954,15 +954,7 @@ droid_create_image_from_name(_EGLDisplay *disp,
+    if (format == -1)
+        return NULL;
+ 
+-   dri2_img = calloc(1, sizeof(*dri2_img));
+-   if (!dri2_img) {
+-      _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+-      return NULL;
+-   }
+-
+-   _eglInitImage(&dri2_img->base, disp);
+-
+-   dri2_img->dri_image =
++   return
+       dri2_dpy->image->createImageFromName(dri2_dpy->dri_screen,
+ 					   buf->width,
+ 					   buf->height,
+@@ -970,13 +962,6 @@ droid_create_image_from_name(_EGLDisplay *disp,
+ 					   name,
+ 					   buf->stride,
+ 					   dri2_img);
+-   if (!dri2_img->dri_image) {
+-      free(dri2_img);
+-      _eglError(EGL_BAD_ALLOC, "droid_create_image_mesa_drm");
+-      return NULL;
+-   }
+-
+-   return &dri2_img->base;
+ }
+ #endif /* HAVE_DRM_GRALLOC */
+ 
+@@ -1031,14 +1016,16 @@ dri2_create_image_android_native_buffer(_EGLDisplay *disp,
+ 
+    __DRIimage *dri_image =
+       droid_create_image_from_prime_fds(disp, buf);
++
++#ifdef HAVE_DRM_GRALLOC
++   if (dri_image == NULL)
++      dri_image = droid_create_image_from_name(disp, buf);
++#endif
++
+    if (dri_image)
+       return dri2_create_image_from_dri(disp, dri_image);
+ 
+-#ifdef HAVE_DRM_GRALLOC
+-   return droid_create_image_from_name(disp, buf);
+-#else
+    return NULL;
+-#endif
+ }
+ 
+ static _EGLImage *
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Use-droid_create_image_from_prime_fds-in.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Use-droid_create_image_from_prime_fds-in.patch
new file mode 100644
index 0000000..cd9e9770
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-Use-droid_create_image_from_prime_fds-in.patch
@@ -0,0 +1,70 @@
+From 9e39ddf9e3940c705eb584a6b50ab4f2726049ea Mon Sep 17 00:00:00 2001
+From: "Kristian H. Kristensen" <hoegsberg@google.com>
+Date: Mon, 10 Aug 2020 18:44:34 -0700
+Subject: [PATCH 06/11] egl/android: Use droid_create_image_from_prime_fds() in
+ get_back_bo()
+
+This function wants to create a __DRIimage for an ANativeWindowBuffer,
+which is mostly the same logic as when we create an EGLImage for an
+ANativeWindowBuffer.  Reuse droid_create_image_from_prime_fds().
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6055>
+---
+ src/egl/drivers/dri2/platform_android.c | 33 ++-----------------------
+ 1 file changed, 2 insertions(+), 31 deletions(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index b77acb4c273..73955b6299e 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -735,11 +735,7 @@ get_front_bo(struct dri2_egl_surface *dri2_surf, unsigned int format)
+ static int
+ get_back_bo(struct dri2_egl_surface *dri2_surf)
+ {
+-   struct dri2_egl_display *dri2_dpy =
+-      dri2_egl_display(dri2_surf->base.Resource.Display);
+-   int fourcc, pitch;
+-   int offset = 0, fds[3];
+-   unsigned num_fds;
++   _EGLDisplay *disp = dri2_surf->base.Resource.Display;
+ 
+    if (dri2_surf->dri_image_back)
+       return 0;
+@@ -750,33 +746,8 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
+          return -1;
+       }
+ 
+-      num_fds = get_native_buffer_fds(dri2_surf->buffer, fds);
+-      if (num_fds == 0) {
+-         _eglLog(_EGL_WARNING, "Could not get native buffer FD");
+-         return -1;
+-      }
+-
+-      fourcc = get_fourcc(dri2_surf->buffer->format);
+-
+-      pitch = dri2_surf->buffer->stride *
+-         get_format_bpp(dri2_surf->buffer->format);
+-
+-      if (fourcc == -1 || pitch == 0) {
+-         _eglLog(_EGL_WARNING, "Invalid buffer fourcc(%x) or pitch(%d)",
+-                 fourcc, pitch);
+-         return -1;
+-      }
+-
+       dri2_surf->dri_image_back =
+-         dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
+-                                             dri2_surf->base.Width,
+-                                             dri2_surf->base.Height,
+-                                             fourcc,
+-                                             fds,
+-                                             num_fds,
+-                                             &pitch,
+-                                             &offset,
+-                                             dri2_surf);
++         droid_create_image_from_prime_fds(disp, dri2_surf->buffer);
+       if (!dri2_surf->dri_image_back) {
+          _eglLog(_EGL_WARNING, "failed to create DRI image from FD");
+          return -1;
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+
diff --git a/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-don-t-pass-loaderPriv-in-get_front_bo.patch b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-don-t-pass-loaderPriv-in-get_front_bo.patch
new file mode 100644
index 0000000..1172859
--- /dev/null
+++ b/media-libs/arc-mesa-virgl/files/UPSTREAM-egl-android-don-t-pass-loaderPriv-in-get_front_bo.patch
@@ -0,0 +1,34 @@
+From 937af204a97a9fdb175417905b8f408e5ef3b11b Mon Sep 17 00:00:00 2001
+From: David Stevens <stevensd@chromium.org>
+Date: Thu, 26 Nov 2020 18:29:31 +0900
+Subject: [PATCH 08/11] egl/android: don't pass loaderPriv in get_front_bo
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is a noop, as no loader extensions pass a __DRIimage's
+loader_private data back to the loader.
+
+Signed-off-by: David Stevens <stevensd@chromium.org>
+Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7805>
+---
+ src/egl/drivers/dri2/platform_android.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
+index 3b2dffad212..0395b5246e4 100644
+--- a/src/egl/drivers/dri2/platform_android.c
++++ b/src/egl/drivers/dri2/platform_android.c
+@@ -787,7 +787,7 @@ get_front_bo(struct dri2_egl_surface *dri2_surf, unsigned int format)
+                                               dri2_surf->base.Height,
+                                               format,
+                                               0,
+-                                              dri2_surf);
++                                              NULL);
+       if (!dri2_surf->dri_image_front) {
+          _eglLog(_EGL_WARNING, "dri2_image_front allocation failed");
+          return -1;
+-- 
+2.29.2.684.gfbc64c5ab5-goog
+