egl: drop an indentation level in _eglFindDisplay() by replacing break/if with a...
[mesa.git] / src / egl / drivers / dri2 / platform_android.c
index b59853f553330142deb9adfcdc82f13cebfb645e..9d3598726d4276b02762a1d76cd300b02ed4e7bf 100644 (file)
@@ -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)
 {
@@ -717,11 +782,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;
@@ -732,33 +793,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_native_buffer(disp, dri2_surf->buffer);
       if (!dri2_surf->dri_image_back) {
          _eglLog(_EGL_WARNING, "failed to create DRI image from FD");
          return -1;
@@ -1016,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)