[Mesa-dev] [PATCH 06/10] egl/android: Fix support for pbuffers

Rob Herring robh at kernel.org
Wed Jul 20 21:19:35 UTC 2016


On Fri, Jul 15, 2016 at 2:53 AM, Tomasz Figa <tfiga at chromium.org> wrote:
> 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.
>
> 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 | 61 +++++++++++++++++++++++++++------
>  2 files changed, 51 insertions(+), 11 deletions(-)
>
> diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
> index 317de06..3ffc177 100644
> --- a/src/egl/drivers/dri2/egl_dri2.h
> +++ b/src/egl/drivers/dri2/egl_dri2.h
> @@ -287,6 +287,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 7495445..0f707dd 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,29 @@ 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) {
> +      _eglLog(_EGL_WARNING, "Front buffer is not supported for window surfaces");
> +      return -1;
> +   }
> +
> +   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 +411,11 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
>     int fourcc, pitch;
>     int offset = 0, fd;
>
> +   if (dri2_surf->base.Type != EGL_WINDOW_BIT) {
> +      _eglLog(_EGL_WARNING, "Back buffer is not supported for pbuffer surfaces");
> +      return -1;
> +   }
> +
>     if (dri2_surf->dri_image)
>            return 0;
>
> @@ -440,8 +471,11 @@ droid_image_get_buffers(__DRIdrawable *driDrawable,
>        return 0;
>
>     if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
> -      _eglLog(_EGL_WARNING, "Front buffer is not supported for window surfaces");
> -      return 0;
> +      if (get_front_bo(dri2_surf, format) < 0)
> +         return 0;
> +
> +      images->front = dri2_surf->dri_front_image;
> +      images->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
>     }
>
>     if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
> @@ -698,14 +732,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);
> @@ -728,6 +754,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. */
> +         else if (!dri2_conf->dri_double_config[j])
> +            dri2_conf->base.SurfaceType &= ~EGL_WINDOW_BIT;
> +      }

I still don't know why this patch causes problems, but I don't think
this hunk is needed. The core DRI2 EGL code takes care of this. It's
not so obvious though. EGL_PBUFFER_BIT is cleared in dri2_add_config,
and dri2_get_dri_config returns single or double config based on the
surface type.

Rob


More information about the mesa-dev mailing list