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

Tomasz Figa tfiga at chromium.org
Thu Jul 21 05:35:31 UTC 2016


On Thu, Jul 21, 2016 at 6:19 AM, Rob Herring <robh at kernel.org> wrote:
> 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.

Well, it just doesn't work correctly without this.

If DRI driver exposes certain double buffered configs that don't have
their equivalent single buffered configs then it will leave double
buffered configs with EGL_PBUFFER_BIT set and dri2_get_dri_config()
will return NULL at the time of eglCreateSurface(), which doesn't
conform to the spec and will cause failures, because it is expected
that if eglChooseConfig() is given EGL_PBUFFER_BIT then resulting
config must support pbuffers. Similarly for EGL_WINDOW_BIT and
single-buffered configs without double-buffered equivalents.

Also I don't see where dri2_add_config() clears EGL_PBUFFER_BIT. I can
see only EGL_PIXMAP_BIT.

Best regards,
Tomasz


More information about the mesa-dev mailing list