EGL/android: Enhance pbuffer implementation
authorLiu Zhiquan <zhiquan.liu@intel.com>
Fri, 9 Dec 2016 11:29:56 +0000 (19:29 +0800)
committerTapani Pälli <tapani.palli@intel.com>
Mon, 19 Dec 2016 06:26:32 +0000 (08:26 +0200)
Some dri drivers will pass multiple bits in buffer_mask parameter
to droid_image_get_buffer(), more than the actual supported buffer
type combination. For such case, will go through all the bits, and
will not return error when unsupported buffer is requested, only
return error when the allocation for supported buffer failed.

v2: coding style and log changes
v3: coding style changes and update patch format

Signed-off-by: Liu Zhiquan <zhiquan.liu@intel.com>
Signed-off-by: Long, Zhifang <zhifang.long@intel.com>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
src/egl/drivers/dri2/platform_android.c

index 373e2c04322bcb030630057b259b3ff22cfaeb2e..1c880f934af910365b390b2fbe6c9aa3a3a91786 100644 (file)
@@ -434,7 +434,40 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
 }
 
 static int
-get_back_bo(struct dri2_egl_surface *dri2_surf)
+get_front_bo(struct dri2_egl_surface *dri2_surf, unsigned int format)
+{
+   struct dri2_egl_display *dri2_dpy =
+      dri2_egl_display(dri2_surf->base.Resource.Display);
+
+   if (dri2_surf->dri_image_front)
+      return 0;
+
+   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+      /* According current EGL spec, front buffer rendering
+       * for window surface is not supported now.
+       * and mesa doesn't have the implementation of this case.
+       * Add warning message, but not treat it as error.
+       */
+      _eglLog(_EGL_DEBUG, "DRI driver requested unsupported front buffer for window surface");
+   } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) {
+      dri2_surf->dri_image_front =
+          dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+                                              dri2_surf->base.Width,
+                                              dri2_surf->base.Height,
+                                              format,
+                                              0,
+                                              dri2_surf);
+      if (!dri2_surf->dri_image_front) {
+         _eglLog(_EGL_WARNING, "dri2_image_front allocation failed");
+         return -1;
+      }
+   }
+
+   return 0;
+}
+
+static int
+get_back_bo(struct dri2_egl_surface *dri2_surf, unsigned int format)
 {
    struct dri2_egl_display *dri2_dpy =
       dri2_egl_display(dri2_surf->base.Resource.Display);
@@ -444,42 +477,68 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
    if (dri2_surf->dri_image_back)
       return 0;
 
-   if (!dri2_surf->buffer)
-      return -1;
+   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+      if (!dri2_surf->buffer) {
+         _eglLog(_EGL_WARNING, "Could not get native buffer");
+         return -1;
+      }
 
-   fd = get_native_buffer_fd(dri2_surf->buffer);
-   if (fd < 0) {
-      _eglLog(_EGL_WARNING, "Could not get native buffer FD");
-      return -1;
-   }
+      fd = get_native_buffer_fd(dri2_surf->buffer);
+      if (fd < 0) {
+         _eglLog(_EGL_WARNING, "Could not get native buffer FD");
+         return -1;
+      }
 
-   fourcc = get_fourcc(dri2_surf->buffer->format);
+      fourcc = get_fourcc(dri2_surf->buffer->format);
 
-   pitch = dri2_surf->buffer->stride *
-      get_format_bpp(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;
-   }
+      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,
-                                          &fd,
-                                          1,
-                                          &pitch,
-                                          &offset,
-                                          dri2_surf);
-   if (!dri2_surf->dri_image_back)
-      return -1;
+      dri2_surf->dri_image_back =
+         dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
+                                             dri2_surf->base.Width,
+                                             dri2_surf->base.Height,
+                                             fourcc,
+                                             &fd,
+                                             1,
+                                             &pitch,
+                                             &offset,
+                                             dri2_surf);
+      if (!dri2_surf->dri_image_back) {
+         _eglLog(_EGL_WARNING, "failed to create DRI image from FD");
+         return -1;
+      }
+   } else if (dri2_surf->base.Type == EGL_PBUFFER_BIT) {
+      /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically,
+       * the spec states that they have a back buffer but no front buffer, in
+       * contrast to pixmaps, which have a front buffer but no back buffer.
+       *
+       * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate
+       * from the spec, following the precedent of Mesa's EGL X11 platform. The
+       * X11 platform correctly assigns pbuffers to single-buffered configs, but
+       * assigns the pbuffer a front buffer instead of a back buffer.
+       *
+       * Pbuffers in the X11 platform mostly work today, so let's just copy its
+       * behavior instead of trying to fix (and hence potentially breaking) the
+       * world.
+       */
+      _eglLog(_EGL_DEBUG, "DRI driver requested unsupported back buffer for pbuffer surface");
+   }
 
    return 0;
 }
 
+/* Some drivers will pass multiple bits in buffer_mask.
+ * For such case, will go through all the bits, and
+ * will not return error when unsupported buffer is requested, only
+ * return error when the allocation for supported buffer failed.
+ */
 static int
 droid_image_get_buffers(__DRIdrawable *driDrawable,
                   unsigned int format,
@@ -489,8 +548,6 @@ droid_image_get_buffers(__DRIdrawable *driDrawable,
                   struct __DRIimageList *images)
 {
    struct dri2_egl_surface *dri2_surf = loaderPrivate;
-   struct dri2_egl_display *dri2_dpy =
-      dri2_egl_display(dri2_surf->base.Resource.Display);
 
    images->image_mask = 0;
    images->front = NULL;
@@ -500,65 +557,23 @@ droid_image_get_buffers(__DRIdrawable *driDrawable,
       return 0;
 
    if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
-      if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
-         /* According current EGL spec,
-          * front buffer rendering for window surface is not supported now */
-         _eglLog(_EGL_WARNING,
-                 "%s:%d front buffer rendering for window surface is not supported!",
-                 __func__, __LINE__);
+      if (get_front_bo(dri2_surf, format) < 0)
          return 0;
-      }
-
-      /* The EGL 1.5 spec states that pbuffers are single-buffered. Specifically,
-       * the spec states that they have a back buffer but no front buffer, in
-       * contrast to pixmaps, which have a front buffer but no back buffer.
-       *
-       * Single-buffered surfaces with no front buffer confuse Mesa; so we deviate
-       * from the spec, following the precedent of Mesa's EGL X11 platform. The
-       * X11 platform correctly assigns pbuffers to single-buffered configs, but
-       * assigns the pbuffer a front buffer instead of a back buffer.
-       *
-       * Pbuffers in the X11 platform mostly work today, so let's just copy its
-       * behavior instead of trying to fix (and hence potentially breaking) the
-       * world.
-       */
-      if (!dri2_surf->dri_image_front &&
-          dri2_surf->base.Type == EGL_PBUFFER_BIT) {
-         dri2_surf->dri_image_front =
-            dri2_dpy->image->createImage(dri2_dpy->dri_screen,
-                                         dri2_surf->base.Width,
-                                         dri2_surf->base.Height,
-                                         format,
-                                         0,
-                                         dri2_surf);
-      }
 
-      if (!dri2_surf->dri_image_front) {
-         _eglLog(_EGL_WARNING,
-                 "%s:%d dri2_image front buffer allocation failed!",
-                 __func__, __LINE__);
-         return 0;
+      if (dri2_surf->dri_image_front) {
+         images->front = dri2_surf->dri_image_front;
+         images->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
       }
-
-      images->front = dri2_surf->dri_image_front;
-      images->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
    }
 
    if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
-      if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
-         if (get_back_bo(dri2_surf) < 0)
-            return 0;
-      }
-
-      if (!dri2_surf->dri_image_back) {
-         _eglLog(_EGL_WARNING,
-                 "%s:%d dri2_image back buffer allocation failed!",
-                 __func__, __LINE__);
+      if (get_back_bo(dri2_surf, format) < 0)
          return 0;
-      }
 
-      images->back = dri2_surf->dri_image_back;
-      images->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+      if (dri2_surf->dri_image_back) {
+         images->back = dri2_surf->dri_image_back;
+         images->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+      }
    }
 
    return 1;