[Mesa-dev] [PATCH v2 3/7] egl/android: Fix support for pbuffers (v2)

Tomasz Figa tfiga at chromium.org
Tue Aug 2 11:07:51 UTC 2016


From: Nicolas Boichat <drinkcat at chromium.org>

Existing image loader code supports creating images only for window
surfaces. Moreover droid_create_surface() passes wrong surface type to
dri2_get_dri_config(), resulting in incorrect configs being returned for
pbuffers. This patch fixes these issues.

In addition, the config generation code is fixed to include single
buffered contexts required for pbuffers and make sure that generated
configs support only surfaces which can handle their supported buffering
modes.

v2: Return error only in case of real error condition and ignore requests
    of unavailable buffers.
    Improve coding style.

Signed-off-by: Nicolas Boichat <drinkcat at chromium.org>
Signed-off-by: Tomasz Figa <tfiga at chromium.org>
---
 src/egl/drivers/dri2/egl_dri2.h         |  1 +
 src/egl/drivers/dri2/platform_android.c | 64 +++++++++++++++++++++++++--------
 2 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 4577875..3da6bef 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -291,6 +291,7 @@ struct dri2_egl_surface
    struct ANativeWindow *window;
    struct ANativeWindowBuffer *buffer;
    __DRIimage *dri_image;
+   __DRIimage *dri_front_image;
 
    /* EGL-owned buffers */
    __DRIbuffer           *local_buffers[__DRI_BUFFER_COUNT];
diff --git a/src/egl/drivers/dri2/platform_android.c b/src/egl/drivers/dri2/platform_android.c
index d78c06d..420436c 100644
--- a/src/egl/drivers/dri2/platform_android.c
+++ b/src/egl/drivers/dri2/platform_android.c
@@ -286,7 +286,7 @@ droid_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
       window->query(window, NATIVE_WINDOW_HEIGHT, &dri2_surf->base.Height);
    }
 
-   config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+   config = dri2_get_dri_config(dri2_conf, type,
                                 dri2_surf->base.GLColorspace);
    if (!config)
       goto cleanup_surface;
@@ -347,6 +347,9 @@ droid_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
       dri2_surf->window->common.decRef(&dri2_surf->window->common);
    }
 
+   if (dri2_surf->dri_front_image)
+      dri2_dpy->image->destroyImage(dri2_surf->dri_front_image);
+
    (*dri2_dpy->core->destroyDrawable)(dri2_surf->dri_drawable);
 
    free(dri2_surf);
@@ -378,6 +381,27 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
 }
 
 static int
+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->base.Type == EGL_WINDOW_BIT)
+      return 0;
+
+   if (dri2_surf->dri_front_image)
+      return 0;
+
+   dri2_surf->dri_front_image =
+      dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+                                   dri2_surf->base.Width,
+                                   dri2_surf->base.Height,
+                                   format, 0, dri2_surf);
+
+   return dri2_surf->dri_front_image ? 0 : -1;
+}
+
+static int
 get_back_bo(struct dri2_egl_surface *dri2_surf)
 {
    struct dri2_egl_display *dri2_dpy =
@@ -385,6 +409,9 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
    int fourcc, pitch;
    int offset = 0, fd;
 
+   if (dri2_surf->base.Type != EGL_WINDOW_BIT)
+      return 0;
+
    if (dri2_surf->dri_image)
 	   return 0;
 
@@ -440,11 +467,12 @@ droid_image_get_buffers(__DRIdrawable *driDrawable,
       return 0;
 
    if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
-      /*
-       * We don't support front buffers and GLES doesn't require them for
-       * window surfaces, but some DRI drivers will request them anyway.
-       * We just ignore such request as other platforms backends do.
-       */
+      if (get_front_bo(dri2_surf, format) < 0)
+         return 0;
+
+      images->front = dri2_surf->dri_front_image;
+      if (images->front)
+         images->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
    }
 
    if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
@@ -452,7 +480,8 @@ droid_image_get_buffers(__DRIdrawable *driDrawable,
          return 0;
 
       images->back = dri2_surf->dri_image;
-      images->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+      if (images->back)
+         images->image_mask |= __DRI_IMAGE_BUFFER_BACK;
    }
 
    return 1;
@@ -696,14 +725,6 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
       for (j = 0; dri2_dpy->driver_configs[j]; j++) {
          const EGLint surface_type = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
          struct dri2_egl_config *dri2_conf;
-         unsigned int double_buffered = 0;
-
-         dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[j],
-            __DRI_ATTRIB_DOUBLE_BUFFER, &double_buffered);
-
-         /* support only double buffered configs */
-         if (!double_buffered)
-            continue;
 
          dri2_conf = dri2_add_config(dpy, dri2_dpy->driver_configs[j],
                count + 1, surface_type, config_attrs, visuals[i].rgba_masks);
@@ -726,6 +747,19 @@ droid_add_configs_for_visuals(_EGLDriver *drv, _EGLDisplay *dpy)
       /* there is no front buffer so no OpenGL */
       dri2_conf->base.RenderableType &= ~EGL_OPENGL_BIT;
       dri2_conf->base.Conformant &= ~EGL_OPENGL_BIT;
+
+      for (j = 0; j < 2; j++) {
+         /* Unsupported color space variants should not affect surface type. */
+         if (!dri2_conf->dri_single_config[j] && !dri2_conf->dri_double_config[j])
+            continue;
+
+         /* Pbuffers support only single buffering. */
+         if (!dri2_conf->dri_single_config[j])
+            dri2_conf->base.SurfaceType &= ~EGL_PBUFFER_BIT;
+         /* Windows support only double buffering. */
+         if (!dri2_conf->dri_double_config[j])
+            dri2_conf->base.SurfaceType &= ~EGL_WINDOW_BIT;
+      }
    }
 
    return (count != 0);
-- 
2.8.0.rc3.226.g39d4020



More information about the mesa-dev mailing list